|
|
@@ -1,7 +1,6 @@
|
|
|
<template>
|
|
|
<!-- AI发展历程 -->
|
|
|
<div class="home-container">
|
|
|
-
|
|
|
<!-- 展开收起侧边栏 -->
|
|
|
<div
|
|
|
class="icon-expand"
|
|
|
@@ -20,16 +19,16 @@
|
|
|
>
|
|
|
</div>
|
|
|
|
|
|
- <el-drawer
|
|
|
- v-model="drawerVisible"
|
|
|
- direction="ltr"
|
|
|
- size="18%"
|
|
|
- :with-header="false"
|
|
|
- >
|
|
|
- <!-- 添加抽屉 -->
|
|
|
- <div class="drawer-box">
|
|
|
- <el-row class="tac">
|
|
|
- <el-col :span="12">
|
|
|
+ <el-drawer
|
|
|
+ v-model="drawerVisible"
|
|
|
+ direction="ltr"
|
|
|
+ size="18%"
|
|
|
+ :with-header="false"
|
|
|
+ >
|
|
|
+ <!-- 添加抽屉 -->
|
|
|
+ <div class="drawer-box">
|
|
|
+ <el-row class="tac">
|
|
|
+ <el-col :span="12">
|
|
|
<span class="mb-2">
|
|
|
<img :src="classImages" alt="课程小节图标" />
|
|
|
课程小节
|
|
|
@@ -119,7 +118,7 @@
|
|
|
<!-- 下一个视频 -->
|
|
|
<div class="caret-right" @click="playNextVideo">
|
|
|
<el-button type="warning" round
|
|
|
- >下一节
|
|
|
+ >下一节
|
|
|
<img :src="rightImg" alt="Right" />
|
|
|
</el-button>
|
|
|
</div>
|
|
|
@@ -174,10 +173,9 @@
|
|
|
</div>
|
|
|
<!-- 右侧小图标 -->
|
|
|
<div
|
|
|
- v-if="courseConfig.ccAiAnswer !== null"
|
|
|
- class="ai-icon-container"
|
|
|
- @click="handleAIClick"
|
|
|
-
|
|
|
+ v-if="courseConfig.ccAiAnswer !== null"
|
|
|
+ class="ai-icon-container"
|
|
|
+ @click="handleAIClick"
|
|
|
>
|
|
|
<img
|
|
|
src="@/assets/images/xiaozhi.png"
|
|
|
@@ -242,13 +240,9 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { ref, onMounted,onUnmounted, onBeforeUnmount } from 'vue'
|
|
|
+import { ref, onMounted, onUnmounted, onBeforeUnmount } from 'vue'
|
|
|
import { useRouter } from 'vue-router'
|
|
|
-import {
|
|
|
- Expand,
|
|
|
- Fold,
|
|
|
- Memo
|
|
|
-} from '@element-plus/icons-vue'
|
|
|
+import { Expand, Fold, Memo } from '@element-plus/icons-vue'
|
|
|
import { Search, ArrowLeftBold } from '@element-plus/icons-vue'
|
|
|
import {
|
|
|
ElMessage,
|
|
|
@@ -281,7 +275,6 @@ const toggleDrawer = () => {
|
|
|
drawerVisible.value = !drawerVisible.value
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// 返回上一页
|
|
|
const goBack = () => {
|
|
|
router.go(-1)
|
|
|
@@ -297,15 +290,15 @@ const course = ref({})
|
|
|
// 菜单数据
|
|
|
const menuItems = ref([])
|
|
|
// 课程集合数据
|
|
|
-const videoPathMap = ref({})
|
|
|
+const videoPathMap = ref({})
|
|
|
|
|
|
//课程小节字典(需要新加接口调取字典)
|
|
|
const menuDict = ref({
|
|
|
- "1": "课前回顾",
|
|
|
- "2": "课程引入",
|
|
|
- "3": "知识讲解",
|
|
|
- "4": "趣味实操",
|
|
|
- "5": "课程总结",
|
|
|
+ 1: '课前回顾',
|
|
|
+ 2: '课程引入',
|
|
|
+ 3: '知识讲解',
|
|
|
+ 4: '趣味实操',
|
|
|
+ 5: '课程总结'
|
|
|
})
|
|
|
|
|
|
// 渲染 课程数据结构 以及 视频
|
|
|
@@ -318,18 +311,22 @@ onMounted(async () => {
|
|
|
courseList.value = res.data
|
|
|
|
|
|
//课程数据
|
|
|
- courseList.value.forEach((courseTemp,index) => {
|
|
|
- let menuIndex = courseTemp.courseLabel + '-' + (index+1);
|
|
|
+ courseList.value.forEach((courseTemp, index) => {
|
|
|
+ let menuIndex = courseTemp.courseLabel + '-' + (index + 1)
|
|
|
// 填充大纲小节
|
|
|
- let menu = menuItems.value.find(menu => courseTemp.courseLabel === menu.index);
|
|
|
- if (menu){//小节
|
|
|
- menu.children = menu.children || [];
|
|
|
+ let menu = menuItems.value.find(
|
|
|
+ menu => courseTemp.courseLabel === menu.index
|
|
|
+ )
|
|
|
+ if (menu) {
|
|
|
+ //小节
|
|
|
+ menu.children = menu.children || []
|
|
|
menu.children.push({
|
|
|
key: menuIndex,
|
|
|
index: menuIndex,
|
|
|
title: courseTemp.courseName
|
|
|
})
|
|
|
- }else {//大节
|
|
|
+ } else {
|
|
|
+ //大节
|
|
|
menuItems.value.push({
|
|
|
key: menuIndex,
|
|
|
index: courseTemp.courseLabel,
|
|
|
@@ -337,15 +334,14 @@ onMounted(async () => {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- courseTemp["key"] = menuIndex;
|
|
|
+ courseTemp['key'] = menuIndex
|
|
|
videoPathMap.value[menuIndex] = courseTemp
|
|
|
|
|
|
//确定默认课程
|
|
|
if (index === 0) {
|
|
|
- course.value = courseTemp;
|
|
|
+ course.value = courseTemp
|
|
|
}
|
|
|
})
|
|
|
-
|
|
|
} catch (error) {
|
|
|
console.error('获取课程数据失败:', error)
|
|
|
}
|
|
|
@@ -368,7 +364,7 @@ const handleClose = () => {}
|
|
|
// 菜单选择的处理函数
|
|
|
const handleSelect = index => {
|
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo(index))return;
|
|
|
+ if (disableVideo(index)) return
|
|
|
|
|
|
const findTitle = items => {
|
|
|
for (const item of items) {
|
|
|
@@ -389,11 +385,11 @@ const handleSelect = index => {
|
|
|
course.value = videoPathMap.value[index]
|
|
|
// 切换标题后,关闭抽屉
|
|
|
drawerVisible.value = false
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
//视频不存在
|
|
|
- Message().notifyWarning('视频不存在!', true);
|
|
|
+ Message().notifyWarning('视频不存在!', true)
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//测试账号禁用视频
|
|
|
if (disableVideo()) return
|
|
|
}
|
|
|
@@ -417,7 +413,7 @@ const flattenMenuItems = () => {
|
|
|
// 播放下一个视频
|
|
|
const playNextVideo = () => {
|
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo())return;
|
|
|
+ if (disableVideo()) return
|
|
|
|
|
|
const allIndices = flattenMenuItems()
|
|
|
const currentIndexInList = allIndices.indexOf(course.value.key)
|
|
|
@@ -433,7 +429,7 @@ const playNextVideo = () => {
|
|
|
}
|
|
|
|
|
|
// 重置
|
|
|
- pausedIndices = ref({time: [], newTime: []})
|
|
|
+ pausedIndices = ref({ time: [], newTime: [] })
|
|
|
userMessage = ref('')
|
|
|
messageHistory = ref([])
|
|
|
}
|
|
|
@@ -442,7 +438,7 @@ const playNextVideo = () => {
|
|
|
// 播放上一个视频
|
|
|
const playPreviousVideo = () => {
|
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo())return;
|
|
|
+ if (disableVideo()) return
|
|
|
|
|
|
const allIndices = flattenMenuItems()
|
|
|
const currentIndexInList = allIndices.indexOf(course.value.key)
|
|
|
@@ -461,7 +457,7 @@ const playPreviousVideo = () => {
|
|
|
// 尝试播放视频,处理浏览器自动播放限制
|
|
|
const tryPlayVideo = () => {
|
|
|
//测试账号禁用视频
|
|
|
- if (disableVideo())return;
|
|
|
+ if (disableVideo()) return
|
|
|
|
|
|
const playPromise = videoRef.value.play()
|
|
|
if (playPromise !== undefined) {
|
|
|
@@ -479,32 +475,44 @@ const checkVideoPermission = () => {
|
|
|
}
|
|
|
}
|
|
|
//记录已暂停的内容
|
|
|
- setVideoStop();
|
|
|
-};
|
|
|
+ setVideoStop()
|
|
|
+}
|
|
|
|
|
|
//禁用视频
|
|
|
const disableVideo = (index = course.value.key) => {
|
|
|
- let dis = ["3-7","3-8","3-9","3-10","3-11","3-12","3-13","4-14","5-15"]
|
|
|
-
|
|
|
- if (localStorage.getItem('userName') === "aiTest" &&
|
|
|
- dis.indexOf(index) !== -1) {
|
|
|
+ let dis = [
|
|
|
+ '3-7',
|
|
|
+ '3-8',
|
|
|
+ '3-9',
|
|
|
+ '3-10',
|
|
|
+ '3-11',
|
|
|
+ '3-12',
|
|
|
+ '3-13',
|
|
|
+ '4-14',
|
|
|
+ '5-15'
|
|
|
+ ]
|
|
|
+
|
|
|
+ if (
|
|
|
+ localStorage.getItem('userName') === 'aiTest' &&
|
|
|
+ dis.indexOf(index) !== -1
|
|
|
+ ) {
|
|
|
if (videoRef.value) {
|
|
|
// 记录当前播放时间
|
|
|
videoRef.value.pause()
|
|
|
// 阻止用户跳转到新的时间点,将播放时间重置为之前的时间
|
|
|
- videoRef.value.currentTime = 0;
|
|
|
+ videoRef.value.currentTime = 0
|
|
|
}
|
|
|
//提示禁用// 显示消息框
|
|
|
- Message().notifyWarning('您的账号并未开放此课程!', true);
|
|
|
- return true;
|
|
|
+ Message().notifyWarning('您的账号并未开放此课程!', true)
|
|
|
+ return true
|
|
|
}
|
|
|
- return false;
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
// 视频 ref
|
|
|
const videoRef = ref(null)
|
|
|
// 记录已经暂停过的时间点索引
|
|
|
-let pausedIndices = ref({time: [], newTime: []})
|
|
|
+let pausedIndices = ref({ time: [], newTime: [] })
|
|
|
// 试题弹框显示状态
|
|
|
const questionDialogVisible = ref(false)
|
|
|
// 当前显示的试题
|
|
|
@@ -528,14 +536,16 @@ const handleTimeUpdate = () => {
|
|
|
|
|
|
if (!course.value.courseConfigList) return
|
|
|
course.value.courseConfigList.forEach(courseCofig => {
|
|
|
-
|
|
|
//暂停时间
|
|
|
let time = courseCofig.ccTime
|
|
|
// 检查是否到达时间点且还未暂停过
|
|
|
- let timeIndex = pausedIndices.value.time.indexOf(time);
|
|
|
-
|
|
|
- if (currentTime === time && (timeIndex === -1 || Date.now() - pausedIndices.value.newTime[timeIndex] > 1000) ) {
|
|
|
+ let timeIndex = pausedIndices.value.time.indexOf(time)
|
|
|
|
|
|
+ if (
|
|
|
+ currentTime === time &&
|
|
|
+ (timeIndex === -1 ||
|
|
|
+ Date.now() - pausedIndices.value.newTime[timeIndex] > 1000)
|
|
|
+ ) {
|
|
|
videoRef.value.pause()
|
|
|
|
|
|
// 显示对应的问题
|
|
|
@@ -559,17 +569,17 @@ const handleCloseQuestionDialog = () => {
|
|
|
videoRef.value.play()
|
|
|
|
|
|
//记录已暂停的内容
|
|
|
- setVideoStop();
|
|
|
+ setVideoStop()
|
|
|
}
|
|
|
|
|
|
//记录已暂停的内容
|
|
|
const setVideoStop = () => {
|
|
|
const currentTime = parseInt(videoRef.value.currentTime)
|
|
|
- let timeIndex = pausedIndices.value.time.indexOf(currentTime);
|
|
|
+ let timeIndex = pausedIndices.value.time.indexOf(currentTime)
|
|
|
if (timeIndex === -1) {
|
|
|
pausedIndices.value.time.push(currentTime)
|
|
|
pausedIndices.value.newTime.push(Date.now())
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
pausedIndices.value.time[timeIndex] = currentTime
|
|
|
pausedIndices.value.newTime[timeIndex] = Date.now()
|
|
|
}
|
|
|
@@ -584,7 +594,7 @@ const handleSubmitAnswer = () => {
|
|
|
selectedOption.value = null
|
|
|
|
|
|
//记录已暂停的内容
|
|
|
- setVideoStop();
|
|
|
+ setVideoStop()
|
|
|
}
|
|
|
|
|
|
// 发送消息
|
|
|
@@ -639,7 +649,6 @@ const simulateAIResponse = question => {
|
|
|
const handleCloseAIDialog = () => {
|
|
|
showAIDialog.value = false
|
|
|
}
|
|
|
-
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
@@ -732,6 +741,10 @@ $text-color: #483d8b; // 文本颜色:靛蓝色
|
|
|
height: rpx(20);
|
|
|
margin-bottom: rpx(5);
|
|
|
border-radius: rpx(6);
|
|
|
+ // 添加flex布局使标题和图标两端对齐
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
}
|
|
|
.el-menu ::v-deep(.el-sub-menu__title:hover),
|
|
|
.el-menu ::v-deep(.el-sub-menu__title:focus),
|
|
|
@@ -739,8 +752,18 @@ $text-color: #483d8b; // 文本颜色:靛蓝色
|
|
|
background: linear-gradient(to bottom, #fee78a, #ffce1b);
|
|
|
background-color: transparent;
|
|
|
}
|
|
|
-.el-menu ::v-deep(.el-icon svg) {
|
|
|
- font-size: rpx(9);
|
|
|
+// 添加二级标题折叠图标样式
|
|
|
+::v-deep(.el-sub-menu__icon-arrow) {
|
|
|
+ color: white;
|
|
|
+ font-size: rpx(10); // 增大图标尺寸
|
|
|
+ margin-left: auto; // 将图标推到右侧
|
|
|
+ margin-top: rpx(-5);
|
|
|
+ display: block;
|
|
|
+ width: rpx(16); // 确保有明确宽度
|
|
|
+}
|
|
|
+// 鼠标悬停时的图标样式
|
|
|
+.el-menu ::v-deep(.el-sub-menu__title:hover .el-sub-menu__icon-arrow) {
|
|
|
+ color: black; // 与悬停状态的文字颜色保持一致
|
|
|
}
|
|
|
|
|
|
.mb-2 {
|
|
|
@@ -995,9 +1018,9 @@ video::-webkit-media-controls-panel {
|
|
|
border: none;
|
|
|
border-radius: rpx(20);
|
|
|
background: linear-gradient(
|
|
|
- 135deg,
|
|
|
- $light-color,
|
|
|
- #d8bfd8
|
|
|
+ 135deg,
|
|
|
+ $light-color,
|
|
|
+ #d8bfd8
|
|
|
); // 柔和的蓝紫色渐变
|
|
|
overflow: hidden;
|
|
|
display: flex; // 添加 flex 布局
|