丸子 9 сар өмнө
parent
commit
f287856d97

+ 1 - 1
src/components/HomePage.vue

@@ -394,7 +394,7 @@ onMounted(() => {
 }
 .dropdown-menu {
   width: rpx(100);
-  height: rpx(60);
+  // height: rpx(60);
   border-radius: rpx(5);
   border: 1px white solid;
   background-color: rgb(255, 255, 255,0.5);

+ 94 - 71
src/views/AIDevelop.vue

@@ -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 布局

+ 99 - 60
src/views/AIGeneralCourse.vue

@@ -2,51 +2,55 @@
   <!-- AI智能课 -->
   <div class="home-container">
     <!-- 展开收起侧边栏 -->
-    <div
-      class="icon-expand"
-      :style="{
-        backgroundColor: drawerVisible ? '#44449c' : '#7F70C840',
-        left: drawerVisible ? '18%' : '0'
-      }"
-      @click="toggleDrawer"
-    >
-      <span
-        class="vertical-lines"
-        :style="{
-          color: drawerVisible ? '#8a78d0' : 'white'
-        }"
-        >||</span
-      >
-    </div>
+    <div class="sidebar-container">
+      <div class="sidebar-layout">
+        <div
+          class="icon-expand"
+          :style="{
+            backgroundColor: drawerVisible ? '#44449c' : '#7F70C840',
+            left: drawerVisible ? '18%' : '0'
+          }"
+          @click="toggleDrawer"
+        >
+          <span
+            class="vertical-lines"
+            :style="{
+              color: drawerVisible ? '#8a78d0' : 'white'
+            }"
+            >||</span
+          >
+        </div>
+      </div>
 
-    <transition name="drawer-slide">
-      <div class="main-content" v-if="drawerVisible">
-        <!-- 菜单栏 -->
-        <div class="drawer-box">
-          <el-row class="tac">
-            <el-col :span="12">
-              <span class="mb-2">
-                <img :src="teachingImg" alt="教学" />
-                教学大纲
-              </span>
-              <el-menu
-                default-active="1"
-                :class="{ 'el-menu-vertical-demo': true }"
-              >
-                <el-menu-item
-                  v-for="(title, index) in courseTitles"
-                  :key="index + 1"
-                  :index="(index + 1).toString()"
-                  @click="goToAIExperience(index + 1)"
+      <transition name="drawer-slide">
+        <div class="main-content" v-if="drawerVisible">
+          <!-- 菜单栏 -->
+          <div class="drawer-box">
+            <el-row class="tac">
+              <el-col :span="12">
+                <span class="mb-2">
+                  <img :src="teachingImg" alt="教学" />
+                  教学大纲
+                </span>
+                <el-menu
+                  default-active="1"
+                  :class="{ 'el-menu-vertical-demo': true }"
                 >
-                  0{{ index + 1 }} {{ title }}
-                </el-menu-item>
-              </el-menu>
-            </el-col>
-          </el-row>
+                  <el-menu-item
+                    v-for="(title, index) in courseTitles"
+                    :key="index + 1"
+                    :index="(index + 1).toString()"
+                    @click="goToAIExperience(index + 1)"
+                  >
+                    0{{ index + 1 }} {{ title }}
+                  </el-menu-item>
+                </el-menu>
+              </el-col>
+            </el-row>
+          </div>
         </div>
-      </div>
-    </transition>
+      </transition>
+    </div>
 
     <div class="content-box">
       <div class="box-1">
@@ -106,7 +110,7 @@
           ></div>
           <div class="additional-text">
             0{{ outlineData.ctTypeSort }} {{ outlineData.ctType }}
-          </div> 
+          </div>
         </div>
       </div>
     </div>
@@ -140,8 +144,19 @@ const selectedGrade = ref('')
 // 添加抽屉显示状态
 const drawerVisible = ref(true)
 // 处理下拉菜单选择
-const handleGradeSelect = (command) => {
+const handleGradeSelect = command => {
   selectedGrade.value = command
+  // 保存选中值到localStorage
+  localStorage.setItem('selectedGrade', command)
+  // 年级切换时重新加载数据的逻辑
+  const selectedItem = classData.value.find(item => item.ctType === command)
+  if (selectedItem) {
+    ClassOutline(selectedItem.id).then(res => {
+      if (res.code === 0) {
+        classOutlineData.value = res.data
+      }
+    })
+  }
 }
 // 添加切换抽屉显示状态的函数
 const toggleDrawer = () => {
@@ -154,15 +169,20 @@ const classOutlineData = ref([])
 
 const fetchCtTypes = async () => {
   try {
-    const response = await ClassList() 
-    console.log(response);
+    const response = await ClassList()
+    console.log(response)
     if (response.code === 0) {
       classData.value = response.data
-      // 获取到数据,将第一个选项的值作为默认选中值
-      if (classData.value.length > 0) {
-        selectedGrade.value = classData.value[0].ctType
-        // 初始化时获取课程大纲数据
-        const selectedItem = classData.value[0]
+      // 获取到数据,优先从localStorage读取选中值
+      const savedGrade = localStorage.getItem('selectedGrade')
+      selectedGrade.value =
+        savedGrade ||
+        (classData.value.length > 0 ? classData.value[0].ctType : '')
+      // 初始化时获取课程大纲数据
+      const selectedItem =
+        classData.value.find(item => item.ctType === selectedGrade.value) ||
+        classData.value[0]
+      if (selectedItem) {
         ClassOutline(selectedItem.id).then(res => {
           if (res.code === 0) {
             classOutlineData.value = res.data
@@ -240,7 +260,6 @@ const goToAIExperience = outlineData => {
     }
   }
 }
-
 </script>
 
 <style scoped lang="scss">
@@ -276,13 +295,35 @@ const goToAIExperience = outlineData => {
   ); /* 设置悬停、聚焦、点击状态下的背景色 */
   gap: rpx(0);
 }
+// // 添加新的容器样式
+// .sidebar-wrapper {
+//   display: flex;
+//   align-items: stretch;
+//   transition: all 0.3s ease;
+// }
+// // 折叠状态样式
+// .sidebar-wrapper.collapsed .icon-expand {
+//   border-radius: 0 4px 4px 0;
+// }
+.sidebar-layout {
+  display: flex;
+  flex-direction: row;
+  align-items: flex-start;
+}
+.icon-wrapper {
+  width: 40px; /* 根据实际需要调整宽度 */
+  flex-shrink: 0;
+  background-color: saddlebrown;
+}
 .main-content {
   width: rpx(135);
   height: 100%;
+  flex-grow: 1;
   position: relative;
   background: linear-gradient(to bottom, #001169, #8a78d0);
   overflow-y: auto; /* 添加垂直滚动条 */
   max-height: 100%; /* 设置最大高度 */
+  transition: all 0.3s ease;
 }
 .icon-expand {
   width: rpx(8);
@@ -295,7 +336,7 @@ const goToAIExperience = outlineData => {
   transform: translateY(-50%);
   cursor: pointer; // 添加鼠标指针样式
   // 修改裁剪路径使右侧边缘垂直无缝贴合
-  clip-path: polygon(0 0, 100%  15%, 100% 90%, 0 100%);
+  clip-path: polygon(0 0, 100% 15%, 100% 90%, 0 100%);
   display: flex;
   justify-content: center;
   align-items: center;
@@ -479,10 +520,10 @@ const goToAIExperience = outlineData => {
 }
 .dropdown-menu {
   width: rpx(100);
-  height: rpx(60);
+  // height: rpx(60);
   border-radius: rpx(5);
   border: 1px white solid;
-  background-color: rgb(255, 255, 255,0.5);
+  background-color: rgb(255, 255, 255, 0.5);
   backdrop-filter: blur(rpx(5));
   box-shadow: 0 4px 8px rgba(202, 52, 52, 0.1);
   margin-left: rpx(40);
@@ -586,20 +627,18 @@ const goToAIExperience = outlineData => {
 }
 </style>
 
-
-
 <style lang="scss">
 /* 消除小三角 */
-.el-popper__arrow{
+.el-popper__arrow {
   display: none;
 }
 .el-popper.is-light,
-.el-dropdown__popper.el-popper{
+.el-dropdown__popper.el-popper {
   background: transparent;
   border: none;
   box-shadow: none;
 }
-.el-dropdown__popper{
+.el-dropdown__popper {
   --el-dropdown-menuItem-hover-color: none;
 }
 </style>