Explorar el Código

保存视频进度和互动完成率进度

丸子 hace 9 meses
padre
commit
d3e8a51cd9

+ 1 - 1
src/api/personalized/index.js

@@ -10,7 +10,7 @@ export function saveRecord (data) {
 }
 }
 
 
 
 
-// 获取评估报告
+// 获取评估报告数据
 export function getReport (data) {
 export function getReport (data) {
   return axios({
   return axios({
     url: 'bjdxReport/progress/getReportProgress',
     url: 'bjdxReport/progress/getReportProgress',

+ 22 - 1
src/components/HomePage.vue

@@ -160,6 +160,8 @@ const goToPersonalized = () =>{
 
 
 // 添加下拉菜单选中项
 // 添加下拉菜单选中项
 const selectedGrade = ref(localStorage.getItem('selectedGrade') || '')
 const selectedGrade = ref(localStorage.getItem('selectedGrade') || '')
+// 添加年级ID存储变量
+const selectedGradeId = ref(localStorage.getItem('selectedGradeId') || '')
 // 获取年级
 // 获取年级
 const classData = ref([])
 const classData = ref([])
 const fetchCtTypes = async () => {
 const fetchCtTypes = async () => {
@@ -170,9 +172,11 @@ const fetchCtTypes = async () => {
     if (response.code === 0) {
     if (response.code === 0) {
       classData.value = response.data
       classData.value = response.data
       // 获取到数据,将第一个选项的值作为默认选中值
       // 获取到数据,将第一个选项的值作为默认选中值
-      if (classData.value.length > 0 && !selectedGrade.value) {
+     if (classData.value.length > 0 && !selectedGrade.value) {
         selectedGrade.value = classData.value[0].ctType
         selectedGrade.value = classData.value[0].ctType
+        selectedGradeId.value = classData.value[0].id
         localStorage.setItem('selectedGrade', selectedGrade.value)
         localStorage.setItem('selectedGrade', selectedGrade.value)
+        localStorage.setItem('selectedGradeId', selectedGradeId.value)
       }
       }
     }
     }
   } catch (error) {
   } catch (error) {
@@ -184,12 +188,29 @@ const fetchCtTypes = async () => {
 watch(selectedGrade, (newValue) => {
 watch(selectedGrade, (newValue) => {
   if (newValue) {
   if (newValue) {
     localStorage.setItem('selectedGrade', newValue)
     localStorage.setItem('selectedGrade', newValue)
+    // 当年级名称变化时,查找对应的ID
+    const selectedItem = classData.value.find(item => item.ctType === newValue)
+    if (selectedItem) {
+      selectedGradeId.value = selectedItem.id
+      localStorage.setItem('selectedGradeId', selectedGradeId.value)
+    }
+  }
+})
+// 监听 selectedGradeId 变化,保存到 localStorage
+watch(selectedGradeId, (newValue) => {
+  if (newValue) {
+    localStorage.setItem('selectedGradeId', newValue)
   }
   }
 })
 })
 
 
 // 处理下拉菜单选择
 // 处理下拉菜单选择
 const handleGradeSelect = (command) => {
 const handleGradeSelect = (command) => {
   selectedGrade.value = command
   selectedGrade.value = command
+  // 查找对应的ID
+  const selectedItem = classData.value.find(item => item.ctType === command)
+  if (selectedItem) {
+    selectedGradeId.value = selectedItem.id
+  }
 }
 }
 
 
 //AI实验室
 //AI实验室

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 559 - 397
src/views/AIDevelop.vue


+ 2 - 0
src/views/AILaboratory.vue

@@ -93,6 +93,7 @@ import human from '@/assets/icon/human.png'
 // 数字人接口
 // 数字人接口
 const grade = ref('')
 const grade = ref('')
 const peopleList = ref([])
 const peopleList = ref([])
+
 onMounted(async () => {
 onMounted(async () => {
   try {
   try {
     grade.value = route.query.grade || localStorage.getItem('selectedGrade')
     grade.value = route.query.grade || localStorage.getItem('selectedGrade')
@@ -136,6 +137,7 @@ const groupList = ref([
     title: '数字人老师'
     title: '数字人老师'
   }
   }
 ])
 ])
+
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 23 - 2
src/views/AIPainting.vue

@@ -178,6 +178,9 @@ import {
   User
   User
 } from '@element-plus/icons-vue'
 } from '@element-plus/icons-vue'
 
 
+import { saveRecord } from '@/api/personalized/index.js'
+
+
 
 
 // 返回上一页
 // 返回上一页
 const goBack = () => {
 const goBack = () => {
@@ -242,6 +245,24 @@ const handleClose = () => {}
 
 
 const demoImageList = [demo1, demo2, demo3, demo4]
 const demoImageList = [demo1, demo2, demo3, demo4]
 
 
+  // 年级ID相关
+const gradeId = ref('')
+// 保存记录
+onMounted(async () => {
+  gradeId.value = localStorage.getItem('selectedGradeId') || ''
+  console.log(gradeId.value);
+  try{
+    const res = await saveRecord({
+        brpNjId: gradeId.value,
+        brpType: "aiCount",
+        brpProgress: 1
+      });
+      console.log(res);
+  }catch(error){
+    console.error('保存记录失败:', error);
+  }
+});
+
 // 消息列表和输入内容的响应式变量
 // 消息列表和输入内容的响应式变量
 const messages = ref([])
 const messages = ref([])
 
 
@@ -250,6 +271,7 @@ const inputMessage = ref('')
 const sendMessage = () => {
 const sendMessage = () => {
   console.log(inputMessage.value)
   console.log(inputMessage.value)
   if (inputMessage.value.trim()) {
   if (inputMessage.value.trim()) {
+    
     // messages.value.push(inputMessage.value.trim())
     // messages.value.push(inputMessage.value.trim())
     // 先保存内容 再置空输入框
     // 先保存内容 再置空输入框
     let content = inputMessage.value;
     let content = inputMessage.value;
@@ -396,8 +418,7 @@ const inProgressTimerFun = () => {
 .left-group1 {
 .left-group1 {
   width: rpx(135);
   width: rpx(135);
   height: 100%;
   height: 100%;
-    background: linear-gradient(to bottom, #001169, #8a78d0);
-
+  background: linear-gradient(to bottom, #001169, #8a78d0);
 }
 }
 .home-container {
 .home-container {
   position: fixed;
   position: fixed;

+ 193 - 167
src/views/AIQuestions.vue

@@ -6,14 +6,14 @@
       class="icon-expand"
       class="icon-expand"
       :style="{
       :style="{
         backgroundColor: drawerVisible ? '#44449c' : '#7F70C840',
         backgroundColor: drawerVisible ? '#44449c' : '#7F70C840',
-        left: drawerVisible ? '18%' : '0'
+        left: drawerVisible ? '18%' : '0',
       }"
       }"
       @click="toggleDrawer"
       @click="toggleDrawer"
     >
     >
       <span
       <span
         class="vertical-lines"
         class="vertical-lines"
         :style="{
         :style="{
-          color: drawerVisible ? '#8a78d0' : 'white'
+          color: drawerVisible ? '#8a78d0' : 'white',
         }"
         }"
         >||</span
         >||</span
       >
       >
@@ -80,10 +80,13 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { ref, onMounted, computed } from 'vue'
-import { CreateDialogue, sendChatMessageStream } from '@/api/questions.js'
-import { useRouter, useRoute } from 'vue-router'
-import MarkdownView from '@/components/MarkdownView/index.vue'
+import { ref, onMounted, computed,watch } from "vue";
+import { CreateDialogue, sendChatMessageStream } from "@/api/questions.js";
+import { useRouter, useRoute } from "vue-router";
+import { saveRecord } from '@/api/personalized/index.js'
+
+
+import MarkdownView from "@/components/MarkdownView/index.vue";
 import {
 import {
   Document,
   Document,
   Menu as IconMenu,
   Menu as IconMenu,
@@ -96,264 +99,283 @@ import {
   Expand,
   Expand,
   Picture,
   Picture,
   Tickets,
   Tickets,
-  User
-} from '@element-plus/icons-vue'
+  User,
+} from "@element-plus/icons-vue";
 
 
-import DefaultMessage from '@/components/DefaultMessage/index.vue'
+import DefaultMessage from "@/components/DefaultMessage/index.vue";
 
 
 // 导入图片
 // 导入图片
 // import question from '@/assets/icon/question.png'
 // import question from '@/assets/icon/question.png'
 // import painting from '@/assets/icon/painting.png'
 // import painting from '@/assets/icon/painting.png'
 // import human from '@/assets/icon/human.png'
 // import human from '@/assets/icon/human.png'
 
 
-import LeftPanel from '@/components/LeftPanel.vue'
-const leftPanelRef = ref(null)
+import LeftPanel from "@/components/LeftPanel.vue";
+const leftPanelRef = ref(null);
+
 
 
 // 默认消息控制
 // 默认消息控制
-const showDefaultMessages = ref(true)
-const handleDefaultMessageSelect = message => {
-  prompt.value = message
-  handleSendByButton()
-  showDefaultMessages.value = false
-}
+const showDefaultMessages = ref(true);
+const handleDefaultMessageSelect = (message) => {
+  prompt.value = message;
+  handleSendByButton();
+  showDefaultMessages.value = false;
+};
 
 
 // 添加抽屉显示状态
 // 添加抽屉显示状态
-const drawerVisible = ref(true)
+const drawerVisible = ref(true);
 // 添加切换抽屉显示状态的函数
 // 添加切换抽屉显示状态的函数
 const toggleDrawer = () => {
 const toggleDrawer = () => {
-  drawerVisible.value = !drawerVisible.value
-}
+  drawerVisible.value = !drawerVisible.value;
+};
 
 
 // 处理菜单展开和关闭
 // 处理菜单展开和关闭
-const handleOpen = () => {}
-const handleClose = () => {}
+const handleOpen = () => {};
+const handleClose = () => {};
 
 
 // 返回上一页
 // 返回上一页
 const goBack = () => {
 const goBack = () => {
-  router.push('/ai-laboratory')
-}
-const router = useRouter()
-const route = useRoute()
+  router.push("/ai-laboratory");
+};
+const router = useRouter();
+const route = useRoute();
 
 
-const personId = ref(route.query.id)
-const personName = ref(route.query.name)
-const personIntroduce = ref(route.query.message)
-const personImage = ref(route.query.image)
+const personId = ref(route.query.id);
+const personName = ref(route.query.name);
+const personIntroduce = ref(route.query.message);
+const personImage = ref(route.query.image);
 
 
 // 渲染实验室携带的人物形象图片
 // 渲染实验室携带的人物形象图片
-const selectedImage = ref('')
+const selectedImage = ref("");
 onMounted(() => {
 onMounted(() => {
-  const image = route.query.image
+  const image = route.query.image;
   if (image) {
   if (image) {
-    selectedImage.value = image
+    selectedImage.value = image;
   }
   }
-})
+});
 
 
 // 聊天对话
 // 聊天对话
-const activeConversationModelPath = ref(null) // 选中的对话编号
-const activeConversationId = ref(null) // 选中的对话编号
-const activeConversation = ref(null) // 选中的 Conversation
-const conversationInProgress = ref(false) // 对话是否正在进行中。目前只有【发送】消息时,会更新为 true,避免切换对话、删除对话等操作,导致 stream 中断
+const activeConversationModelPath = ref(null); // 选中的对话编号
+const activeConversationId = ref(null); // 选中的对话编号
+const activeConversation = ref(null); // 选中的 Conversation
+const conversationInProgress = ref(false); // 对话是否正在进行中。目前只有【发送】消息时,会更新为 true,避免切换对话、删除对话等操作,导致 stream 中断
 
 
 // 消息列表
 // 消息列表
-const messageRef = ref()
-const activeMessageList = ref([]) // 选中对话的消息列表
-const activeMessageListLoading = ref(false) // activeMessageList 是否正在加载中
-const activeMessageListLoadingTimer = ref() // activeMessageListLoading Timer 定时器。如果加载速度很快,就不进入加载中
+const messageRef = ref();
+const activeMessageList = ref([]); // 选中对话的消息列表
+const activeMessageListLoading = ref(false); // activeMessageList 是否正在加载中
+const activeMessageListLoadingTimer = ref(); // activeMessageListLoading Timer 定时器。如果加载速度很快,就不进入加载中
 // 消息滚动
 // 消息滚动
-const textSpeed = ref(50) // Typing speed in milliseconds
-const textRoleRunning = ref(false) // Typing speed in milliseconds
+const textSpeed = ref(50); // Typing speed in milliseconds
+const textRoleRunning = ref(false); // Typing speed in milliseconds
 
 
 // 发送消息输入框
 // 发送消息输入框
-const isComposing = ref(false) // 判断用户是否在输入
-const conversationInAbortController = ref() // 对话进行中 abort 控制器(控制 stream 对话)
-const inputTimeout = ref() // 处理输入中回车的定时器
-const prompt = ref() // prompt
-const enableContext = ref(true) // 是否开启上下文
+const isComposing = ref(false); // 判断用户是否在输入
+const conversationInAbortController = ref(); // 对话进行中 abort 控制器(控制 stream 对话)
+const inputTimeout = ref(); // 处理输入中回车的定时器
+const prompt = ref(); // prompt
+const enableContext = ref(true); // 是否开启上下文
 // 接收 Stream 消息
 // 接收 Stream 消息
-const receiveMessageFullText = ref('')
-const receiveMessageDisplayedText = ref('')
+const receiveMessageFullText = ref("");
+const receiveMessageDisplayedText = ref("");
 
 
 // =========== 【聊天对话】相关 ===========
 // =========== 【聊天对话】相关 ===========
 
 
 /** 获取对话信息 */
 /** 获取对话信息 */
-const getConversation = async id => {
+const getConversation = async (id) => {
   if (!id) {
   if (!id) {
-    return
+    return;
   }
   }
-  const conversation = ref({})
+  const conversation = ref({});
   if (!conversation) {
   if (!conversation) {
-    return
+    return;
   }
   }
-  conversation.systemMessage = personIntroduce.value
-  activeConversation.value = conversation
+  conversation.systemMessage = personIntroduce.value;
+  activeConversation.value = conversation;
   // activeConversationId.value = personId.value
   // activeConversationId.value = personId.value
-  activeConversationModelPath.value = personImage.value
-}
+  activeConversationModelPath.value = personImage.value;
+};
 
 
 // =========== 【发送消息】相关 ===========
 // =========== 【发送消息】相关 ===========
 
 
 /** 处理来自 keydown 的发送消息 */
 /** 处理来自 keydown 的发送消息 */
-const handleSendByKeydown = async event => {
+const handleSendByKeydown = async (event) => {
   // 判断用户是否在输入
   // 判断用户是否在输入
   if (isComposing.value) {
   if (isComposing.value) {
-    return
+    return;
   }
   }
   // 进行中不允许发送
   // 进行中不允许发送
   if (conversationInProgress.value) {
   if (conversationInProgress.value) {
-    return
+    return;
   }
   }
-  const content = prompt.value?.trim()
-  if (event.key === 'Enter') {
+  const content = prompt.value?.trim();
+  if (event.key === "Enter") {
     if (event.shiftKey) {
     if (event.shiftKey) {
       // 插入换行
       // 插入换行
-      prompt.value += '\r\n'
-      event.preventDefault() // 防止默认的换行行为
+      prompt.value += "\r\n";
+      event.preventDefault(); // 防止默认的换行行为
     } else {
     } else {
       // 发送消息
       // 发送消息
-      await doSendMessage(content)
-      event.preventDefault() // 防止默认的提交行为
+      await doSendMessage(content);
+      event.preventDefault(); // 防止默认的提交行为
     }
     }
   }
   }
-}
+};
 
 
 /** 处理来自【发送】按钮的发送消息 */
 /** 处理来自【发送】按钮的发送消息 */
 const handleSendByButton = () => {
 const handleSendByButton = () => {
-  doSendMessage(prompt.value?.trim())
-}
+  doSendMessage(prompt.value?.trim());
+};
 
 
 /** 处理 prompt 输入变化 */
 /** 处理 prompt 输入变化 */
-const handlePromptInput = event => {
+const handlePromptInput = (event) => {
   // 非输入法 输入设置为 true
   // 非输入法 输入设置为 true
   if (!isComposing.value) {
   if (!isComposing.value) {
     // 回车 event data 是 null
     // 回车 event data 是 null
     if (event.data == null) {
     if (event.data == null) {
-      return
+      return;
     }
     }
-    isComposing.value = true
+    isComposing.value = true;
   }
   }
   // 清理定时器
   // 清理定时器
   if (inputTimeout.value) {
   if (inputTimeout.value) {
-    clearTimeout(inputTimeout.value)
+    clearTimeout(inputTimeout.value);
   }
   }
   // 重置定时器
   // 重置定时器
   inputTimeout.value = setTimeout(() => {
   inputTimeout.value = setTimeout(() => {
-    isComposing.value = false
-  }, 400)
-}
+    isComposing.value = false;
+  }, 400);
+};
 // TODO注:是不是可以通过 @keydown.enter、@keydown.shift.enter 来实现,回车发送、shift+回车换行;主要看看,是不是可以简化 isComposing 相关的逻辑
 // TODO注:是不是可以通过 @keydown.enter、@keydown.shift.enter 来实现,回车发送、shift+回车换行;主要看看,是不是可以简化 isComposing 相关的逻辑
 const onCompositionstart = () => {
 const onCompositionstart = () => {
-  isComposing.value = true
-}
+  isComposing.value = true;
+};
 const onCompositionend = () => {
 const onCompositionend = () => {
   setTimeout(() => {
   setTimeout(() => {
-    isComposing.value = false
-  }, 200)
-}
+    isComposing.value = false;
+  }, 200);
+};
+
+// 保存记录
+// 年级ID相关
+const gradeId = ref('')
+
+onMounted(async () => {
+  gradeId.value = localStorage.getItem('selectedGradeId') || ''
+  console.log(gradeId.value);
+  try{
+    const res = await saveRecord({
+        brpNjId: gradeId.value,
+        brpType: "aiCount",
+        brpProgress: 1
+      });
+      console.log(res);
+  }catch(error){
+    console.error('保存记录失败:', error);
+  }
+});
 
 
 /** 真正执行【发送】消息操作 */
 /** 真正执行【发送】消息操作 */
-const doSendMessage = async content => {
+const doSendMessage = async (content) => {
   // 校验
   // 校验
   if (content.length < 1) {
   if (content.length < 1) {
-    console.error('发送失败,原因:内容为空!')
-    return
+    console.error("发送失败,原因:内容为空!");
+    return;
   }
   }
-
   if (activeConversationId.value == null) {
   if (activeConversationId.value == null) {
-    console.error('还没创建对话,不能发送!')
-    return
+    console.error("还没创建对话,不能发送!");
+    return;
   }
   }
   // 清空输入框
   // 清空输入框
-  prompt.value = ''
+  prompt.value = "";
   // 执行发送
   // 执行发送
   await doSendMessageStream({
   await doSendMessageStream({
     conversationId: activeConversationId.value,
     conversationId: activeConversationId.value,
-    content: content
-  })
-}
+    content: content,
+  });
+};
 
 
 /** 真正执行【发送】消息操作 */
 /** 真正执行【发送】消息操作 */
-const doSendMessageStream = async userMessage => {
+const doSendMessageStream = async (userMessage) => {
   // 创建 AbortController 实例,以便中止请求
   // 创建 AbortController 实例,以便中止请求
-  conversationInAbortController.value = new AbortController()
+  conversationInAbortController.value = new AbortController();
   // 标记对话进行中
   // 标记对话进行中
-  conversationInProgress.value = true
+  conversationInProgress.value = true;
   // 设置为空
   // 设置为空
-  receiveMessageFullText.value = ''
+  receiveMessageFullText.value = "";
 
 
   try {
   try {
     // 1.1 先添加两个假数据,等 stream 返回再替换
     // 1.1 先添加两个假数据,等 stream 返回再替换
     activeMessageList.value.push({
     activeMessageList.value.push({
       id: -1,
       id: -1,
       conversationId: activeConversationId.value,
       conversationId: activeConversationId.value,
-      type: 'user',
+      type: "user",
       content: userMessage.content,
       content: userMessage.content,
-      createTime: new Date()
-    })
+      createTime: new Date(),
+    });
     activeMessageList.value.push({
     activeMessageList.value.push({
       id: -2,
       id: -2,
       conversationId: activeConversationId.value,
       conversationId: activeConversationId.value,
-      type: 'assistant',
-      content: '思考中...',
-      createTime: new Date()
-    })
+      type: "assistant",
+      content: "思考中...",
+      createTime: new Date(),
+    });
 
 
     // 1.3 开始滚动
     // 1.3 开始滚动
-    textRoll()
+    textRoll();
 
 
     // 2. 发送 event stream
     // 2. 发送 event stream
-    let isFirstChunk = true // 是否是第一个 chunk 消息段
+    let isFirstChunk = true; // 是否是第一个 chunk 消息段
 
 
     await sendChatMessageStream(
     await sendChatMessageStream(
       userMessage.conversationId,
       userMessage.conversationId,
       userMessage.content,
       userMessage.content,
       conversationInAbortController.value,
       conversationInAbortController.value,
       enableContext.value,
       enableContext.value,
-      async res => {
-        const { code, data, msg } = JSON.parse(res.data)
+      async (res) => {
+        const { code, data, msg } = JSON.parse(res.data);
         if (code !== 0) {
         if (code !== 0) {
-          console.log(`对话异常! ${msg}`)
-          return
+          console.log(`对话异常! ${msg}`);
+          return;
         }
         }
         // 如果内容为空,就不处理。
         // 如果内容为空,就不处理。
         // if (data.receive.content === '') {
         // if (data.receive.content === '') {
         //   return
         //   return
         // }
         // }
         receiveMessageFullText.value =
         receiveMessageFullText.value =
-          receiveMessageFullText.value + data.receive.content
+          receiveMessageFullText.value + data.receive.content;
         // 首次返回需要添加一个 message 到页面,后面的都是更新
         // 首次返回需要添加一个 message 到页面,后面的都是更新
         if (isFirstChunk) {
         if (isFirstChunk) {
-          isFirstChunk = false
+          isFirstChunk = false;
           // 弹出两个假数据
           // 弹出两个假数据
-          activeMessageList.value.pop()
-          activeMessageList.value.pop()
+          activeMessageList.value.pop();
+          activeMessageList.value.pop();
           // 更新返回的数据
           // 更新返回的数据
-          activeMessageList.value.push(data.send)
-          activeMessageList.value.push(data.receive)
+          activeMessageList.value.push(data.send);
+          activeMessageList.value.push(data.receive);
         }
         }
       },
       },
-      error => {
-        console.log(`对话异常! ${error}`)
-        stopStream()
+      (error) => {
+        console.log(`对话异常! ${error}`);
+        stopStream();
         // 需要抛出异常,禁止重试
         // 需要抛出异常,禁止重试
-        throw error
+        throw error;
       },
       },
       () => {
       () => {
-        stopStream()
+        stopStream();
       }
       }
-    )
+    );
   } catch {}
   } catch {}
-}
+};
 
 
 /** 停止 stream 流式调用 */
 /** 停止 stream 流式调用 */
 const stopStream = async () => {
 const stopStream = async () => {
   // tip:如果 stream 进行中的 message,就需要调用 controller 结束
   // tip:如果 stream 进行中的 message,就需要调用 controller 结束
   if (conversationInAbortController.value) {
   if (conversationInAbortController.value) {
-    conversationInAbortController.value.abort()
+    conversationInAbortController.value.abort();
   }
   }
   // 设置为 false
   // 设置为 false
-  conversationInProgress.value = false
-}
+  conversationInProgress.value = false;
+};
 
 
 /**
 /**
  * 消息列表
  * 消息列表
@@ -362,112 +384,116 @@ const stopStream = async () => {
  */
  */
 const messageList = computed(() => {
 const messageList = computed(() => {
   if (activeMessageList.value.length > 0) {
   if (activeMessageList.value.length > 0) {
-    return activeMessageList.value
+    return activeMessageList.value;
   }
   }
 
 
   // 没有消息时,如果有 systemMessage 则展示它
   // 没有消息时,如果有 systemMessage 则展示它
   if (activeConversation.value?.systemMessage) {
   if (activeConversation.value?.systemMessage) {
     let systemMessage = {
     let systemMessage = {
       id: 0,
       id: 0,
-      type: 'system',
-      content: activeConversation.value.systemMessage
-    }
-    activeMessageList.value.push(systemMessage)
-    return [systemMessage]
+      type: "system",
+      content: activeConversation.value.systemMessage,
+    };
+    activeMessageList.value.push(systemMessage);
+    return [systemMessage];
   }
   }
-  return []
-})
+  return [];
+});
 
 
 // ============== 【消息滚动】相关 =============
 // ============== 【消息滚动】相关 =============
 
 
 /** 滚动到 message 底部 */
 /** 滚动到 message 底部 */
-const scrollToBottom = async isIgnore => {
+const scrollToBottom = async (isIgnore) => {
   // if (messageRef.value) {
   // if (messageRef.value) {
   // messageRef.value.scrollToBottom(isIgnore)
   // messageRef.value.scrollToBottom(isIgnore)
   // }
   // }
-}
+};
 
 
 /** 自提滚动效果 */
 /** 自提滚动效果 */
 const textRoll = async () => {
 const textRoll = async () => {
-  let index = 0
+  let index = 0;
   try {
   try {
     // 只能执行一次
     // 只能执行一次
     if (textRoleRunning.value) {
     if (textRoleRunning.value) {
-      return
+      return;
     }
     }
     // 设置状态
     // 设置状态
-    textRoleRunning.value = true
-    receiveMessageDisplayedText.value = ''
+    textRoleRunning.value = true;
+    receiveMessageDisplayedText.value = "";
     const task = async () => {
     const task = async () => {
       // 调整速度
       // 调整速度
       const diff =
       const diff =
         (receiveMessageFullText.value.length -
         (receiveMessageFullText.value.length -
           receiveMessageDisplayedText.value.length) /
           receiveMessageDisplayedText.value.length) /
-        10
+        10;
       if (diff > 5) {
       if (diff > 5) {
-        textSpeed.value = 10
+        textSpeed.value = 10;
       } else if (diff > 2) {
       } else if (diff > 2) {
-        textSpeed.value = 30
+        textSpeed.value = 30;
       } else if (diff > 1.5) {
       } else if (diff > 1.5) {
-        textSpeed.value = 50
+        textSpeed.value = 50;
       } else {
       } else {
-        textSpeed.value = 100
+        textSpeed.value = 100;
       }
       }
       // 对话结束,就按 30 的速度
       // 对话结束,就按 30 的速度
       if (!conversationInProgress.value) {
       if (!conversationInProgress.value) {
-        textSpeed.value = 10
+        textSpeed.value = 10;
       }
       }
 
 
       if (index < receiveMessageFullText.value.length) {
       if (index < receiveMessageFullText.value.length) {
-        receiveMessageDisplayedText.value += receiveMessageFullText.value[index]
-        index++
+        receiveMessageDisplayedText.value +=
+          receiveMessageFullText.value[index];
+        index++;
 
 
         // 更新 message
         // 更新 message
         const lastMessage =
         const lastMessage =
-          activeMessageList.value[activeMessageList.value.length - 1]
-        lastMessage.content = receiveMessageDisplayedText.value
+          activeMessageList.value[activeMessageList.value.length - 1];
+        lastMessage.content = receiveMessageDisplayedText.value;
         // 滚动到住下面
         // 滚动到住下面
-        await scrollToBottom()
+        await scrollToBottom();
         // 重新设置任务
         // 重新设置任务
-        timer = setTimeout(task, textSpeed.value)
+        timer = setTimeout(task, textSpeed.value);
       } else {
       } else {
         // 不是对话中可以结束
         // 不是对话中可以结束
         if (!conversationInProgress.value) {
         if (!conversationInProgress.value) {
-          textRoleRunning.value = false
-          clearTimeout(timer)
+          textRoleRunning.value = false;
+          clearTimeout(timer);
         } else {
         } else {
           // 重新设置任务
           // 重新设置任务
-          timer = setTimeout(task, textSpeed.value)
+          timer = setTimeout(task, textSpeed.value);
         }
         }
       }
       }
-    }
-    let timer = setTimeout(task, textSpeed.value)
+    };
+    let timer = setTimeout(task, textSpeed.value);
   } catch {}
   } catch {}
-}
+};
 
 
 /** 初始化 **/
 /** 初始化 **/
 onMounted(async () => {
 onMounted(async () => {
   if (personId.value) {
   if (personId.value) {
     // 智能问答
     // 智能问答
     CreateDialogue({ roleId: personId.value })
     CreateDialogue({ roleId: personId.value })
-      .then(res => {
-        console.log('创建会话:', res)
-        activeConversationId.value = res.data
-      })
-      .catch(error => {
-        console.error('请求出错:', error)
+      .then((res) => {
+        console.log("创建会话:", res);
+        activeConversationId.value = res.data;
       })
       })
+      .catch((error) => {
+        console.error("请求出错:", error);
+      });
 
 
-    await getConversation(personId.value)
+    await getConversation(personId.value);
   }
   }
 
 
   // 获取列表数据
   // 获取列表数据
   // activeMessageListLoading.value = true
   // activeMessageListLoading.value = true
-})
+});
+
+
+
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
-@use 'sass:math';
+@use "sass:math";
 // 定义rpx转换函数
 // 定义rpx转换函数
 @function rpx($px) {
 @function rpx($px) {
   @return math.div($px, 750) * 100vw;
   @return math.div($px, 750) * 100vw;

+ 23 - 13
src/views/personalized/Personalized.vue

@@ -15,7 +15,7 @@
           <div class="text-content">
           <div class="text-content">
             <p>课程开课率</p>
             <p>课程开课率</p>
             <div>
             <div>
-              <p>{{ njCourseConfigProgress }}</p>
+              <p>{{ njCourseProgress }}</p>
               <span>%</span>
               <span>%</span>
             </div>
             </div>
           </div>
           </div>
@@ -35,13 +35,13 @@
           <div class="middle-content">
           <div class="middle-content">
             <p>互动完成率</p>
             <p>互动完成率</p>
             <div>
             <div>
-              <p>{{  njCourseProgress  }}</p>
+              <p>{{  njCourseConfigProgress  }}</p>
               <span>%</span>
               <span>%</span>
             </div>
             </div>
           </div>
           </div>
         </div>
         </div>
         <div class="middle-bottom-box">
         <div class="middle-bottom-box">
-          <div class="demo-progress" v-for="item in interactionData" :key="item.id">
+          <div class="demo-progress" v-for="item in interactionData" :key="item.id + '-second'">
             <p class="progress-desc">{{ item.desc }}</p>
             <p class="progress-desc">{{ item.desc }}</p>
             <el-progress :percentage="item.percentage" />
             <el-progress :percentage="item.percentage" />
           </div>
           </div>
@@ -62,11 +62,7 @@
             <p>评语</p>
             <p>评语</p>
           </div>
           </div>
           <div class="comment-content">
           <div class="comment-content">
-            <p>
-              教师在AI通识课程的教学中展现出高度的专业素养与教学创新能力,能够有效结合理论知识与实际应用,激发学生对人工智能的兴趣与探索欲望。教学成果呈现出良好的结构性与针对性,课程内容紧贴时代发展,注重培养学生的跨学科思维与技术素养。在引导学生进行项目实践和思辨讨论方面,展现了出色的教学引导与组织能力,达成了“知AI、懂AI、用AI”的教学目标,成果显著,广受学生好评。
-              教师在AI通识课程的教学中展现出高度的专业素养与教学创新能力,能够有效结合理论知识与实际应用,激发学生对人工智能的兴趣与探索欲望。教学成果呈现出良好的结构性与针对性,课程内容紧贴时代发展,注重培养学生的跨学科思维与技术素养。在引导学生进行项目实践和思辨讨论方面,展现了出色的教学引导与组织能力,达成了“知AI、懂AI、用AI”的教学目标,成果显著,广受学生好评。
-              教师在AI通识课程的教学中展现出高度的专业素养与教学创新能力,能够有效结合理论知识与实际应用,激发学生对人工智能的兴趣与探索欲望。教学成果呈现出良好的结构性与针对性,课程内容紧贴时代发展,注重培养学生的跨学科思维与技术素养。在引导学生进行项目实践和思辨讨论方面,展现了出色的教学引导与组织能力,达成了“知AI、懂AI、用AI”的教学目标,成果显著,广受学生好评。
-            </p>
+            <p>{{ comment }}</p>
           </div>
           </div>
         </div>
         </div>
       </div>
       </div>
@@ -94,22 +90,29 @@ const interactionData = ref([]);
 const aiCount = ref(0);
 const aiCount = ref(0);
 const njCourseConfigProgress = ref(0);
 const njCourseConfigProgress = ref(0);
 const njCourseProgress = ref(0);
 const njCourseProgress = ref(0);
+// 评语
+const comment = ref('')
+// 年级ID相关
+const gradeId = ref('')
 // 获取进度
 // 获取进度
 onMounted(async()=>{
 onMounted(async()=>{
+   // 从localStorage获取年级ID,如果没有使用默认值1
+  gradeId.value = localStorage.getItem('selectedGradeId') || ''
   try {
   try {
-    const res = await getReport({ "brpNjId": "1" });
+    const res = await getReport({ brpNjId: gradeId.value });
     console.log(res);
     console.log(res);
-    // 赋值三个数据
+    // 赋值三个数据以及评语
     aiCount.value = res.aiCount;
     aiCount.value = res.aiCount;
     njCourseConfigProgress.value = res.njCourseConfigProgress;
     njCourseConfigProgress.value = res.njCourseConfigProgress;
     njCourseProgress.value = res.njCourseProgress;
     njCourseProgress.value = res.njCourseProgress;
+    comment.value = res.comment
     // 课程开课率数据
     // 课程开课率数据
-    progressData.value = res.reportCourseConfigProgressList.map(item=>({
+    progressData.value = res.reportCourseProgressList.map(item=>({
       desc: item.kcflName,
       desc: item.kcflName,
       percentage: item.progress
       percentage: item.progress
     }))
     }))
     // 互动完成率数据
     // 互动完成率数据
-    interactionData.value = res.reportCourseProgressList.map(item=>({
+    interactionData.value = res.reportCourseConfigProgressList.map(item=>({
       desc: item.kcflName,
       desc: item.kcflName,
       percentage: item.progress
       percentage: item.progress
     }))
     }))
@@ -127,7 +130,6 @@ onMounted(async()=>{
 @function rpx($px) {
 @function rpx($px) {
   @return math.div($px, 750) * 100vw;
   @return math.div($px, 750) * 100vw;
 }
 }
-
 .personalized {
 .personalized {
   position: fixed;
   position: fixed;
   top: 0;
   top: 0;
@@ -353,20 +355,28 @@ onMounted(async()=>{
 }
 }
 
 
 // 修改滚动条样式
 // 修改滚动条样式
+.left-bottom-box::-webkit-scrollbar,
+.middle-bottom-box::-webkit-scrollbar,
 .comment-content::-webkit-scrollbar {
 .comment-content::-webkit-scrollbar {
   width: rpx(2); // 滚动条宽度
   width: rpx(2); // 滚动条宽度
 }
 }
 
 
+.left-bottom-box::-webkit-scrollbar-track,
+.middle-bottom-box::-webkit-scrollbar-track,
 .comment-content::-webkit-scrollbar-track {
 .comment-content::-webkit-scrollbar-track {
   background: #f1f1f1; // 滚动条轨道背景色
   background: #f1f1f1; // 滚动条轨道背景色
   border-radius: rpx(3);
   border-radius: rpx(3);
 }
 }
 
 
+.left-bottom-box::-webkit-scrollbar-thumb,
+.middle-bottom-box::-webkit-scrollbar-thumb,
 .comment-content::-webkit-scrollbar-thumb {
 .comment-content::-webkit-scrollbar-thumb {
   background: #8F74FF; // 滚动条滑块颜色
   background: #8F74FF; // 滚动条滑块颜色
   border-radius: rpx(3); // 滚动条滑块圆角
   border-radius: rpx(3); // 滚动条滑块圆角
 }
 }
 
 
+.left-bottom-box::-webkit-scrollbar-thumb:hover,
+.middle-bottom-box::-webkit-scrollbar-thumb:hover,
 .comment-content::-webkit-scrollbar-thumb:hover {
 .comment-content::-webkit-scrollbar-thumb:hover {
   background: #7a5dff; // 滚动条滑块悬停颜色
   background: #7a5dff; // 滚动条滑块悬停颜色
 }
 }

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio