Kaynağa Gözat

Merge remote-tracking branch 'origin/host-nju' into JiangPengYu_20260111_fix_part1
Try to fix the conflicts between the two branches.

Jiang Pengyu 7 ay önce
ebeveyn
işleme
ff275ef464

+ 1 - 1
src/router/index.ts

@@ -305,4 +305,4 @@ const router = createRouter({
     return true;
   });
 
-export default router
+export default router

+ 7 - 4
src/views/AiSpeakingPage/SpeakingPage.vue

@@ -152,21 +152,21 @@
           <el-button
             @click="startRecording"
             class="start-button"
-            :disabled="!isHomeworkStarted || isHomeworkSubmitted || hasStartPlay"
+            :disabled="!isHomeworkStarted || isHomeworkSubmitted || hasStartPlay || isLoading"
           >
             {{ hasStopRecording ? "继续" : "开始" }}
           </el-button>
           <el-button
             @click="stopRecording"
             class="stop-button"
-            :disabled="!isHomeworkStarted || isHomeworkSubmitted || hasStartPlay"
+            :disabled="!isHomeworkStarted || isHomeworkSubmitted || hasStartPlay || isLoading"
           >
             暂停
           </el-button>
           <el-button
             @click="resetRecording"
             class="reset-button"
-            :disabled="!isHomeworkStarted || isHomeworkSubmitted"
+            :disabled="!isHomeworkStarted || isHomeworkSubmitted || isLoading"
           >
             重试
           </el-button>
@@ -425,7 +425,7 @@ const stopRecording = async() => {
   
   console.log("识别结果:", resultText.value);
   // 只有当有识别结果时才追加
-  if (resultText.value && resultText.value.trim() !== '') {
+  if (resultText.value) {
     userInput.value += resultText.value;
     ElMessage.success("语音识别完成");
   } else {
@@ -606,6 +606,9 @@ const autoPlay = (message) => {
 };
 
 const playAudio = (message) => {
+  if(isLoading.value) {
+    ElMessage.warning('正在发送中,无法处理语音');
+  }
   if (message.audioUrl) {
     if (message.isPlaying) {
       // 如果正在播放,则暂停

+ 24 - 8
src/views/BehaviorPage/component/EditCanvas.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import {onMounted, type Ref, watch} from "vue";
+import {onMounted, ref, type Ref, watch} from "vue";
 import * as echarts from 'echarts';
 import {inject} from "vue-demi";
 import useApis from "@/apis";
@@ -15,10 +15,19 @@ const currentEngagement = inject('currentEngagement') as Ref<any>;
 let productData = [];
 let cursorData = [];
 let processData = [];
+let noData = ref(false)
+
 watch(currentEngagement,()=>{
-  let chartDom = document.getElementById('edit-canvas');
-  let myChart = echarts.getInstanceByDom(chartDom);
-  getCanvasData(myChart);
+  noData.value = false
+  setTimeout(()=>{
+    let chartDom = document.getElementById('edit-canvas');
+    if (!chartDom)return;
+    let myChart = echarts.getInstanceByDom(chartDom);
+    if (!myChart){
+      myChart = echarts.init(chartDom);
+    }
+    getCanvasData(myChart);
+  },0)
 });
 const loadingStatus = inject('loadingStatus') as Ref<{
   edit:boolean,
@@ -54,10 +63,14 @@ function getCanvasData(chart:EChartsType){
       let processCount = 0;
       let zeroCount =0;
       if (!rowData){
-        ElMessage.error('获取修改过程数据失败')
-        loadingStatus.value.edit = false;
         chart.hideLoading();
-        return;
+        loadingStatus.value.edit = false;
+        noData.value = true
+        return
+      }
+      else{
+        noData.value = false
+        loadingStatus.value.edit = false;
       }
       rowData.forEach((item:any) => {
         // console.log("item",item)
@@ -374,9 +387,12 @@ onMounted(()=>{
 </script>
 
 <template>
-  <div id="edit-canvas" class="canvas-container">
+  <div id="edit-canvas" class="canvas-container" v-if="!noData">
 
   </div>
+  <div class="canvas-container" v-else>
+    <el-empty description="暂无数据"/>
+  </div>
 </template>
 
 <style scoped>

+ 25 - 5
src/views/BehaviorPage/component/PauseCanvas.vue

@@ -13,6 +13,10 @@ const props = defineProps<{
 const apis = useApis();
 const pauseData:any[] = [];
 let chartData:any[] = [];
+
+let noData = ref(false)
+
+
 const limit = {
   max:0,
   min:0
@@ -28,9 +32,17 @@ function formatTimeWithMilliseconds(stamp:number ){
 
 const currentEngagement = inject('currentEngagement') as Ref<any>;
 watch(currentEngagement,()=>{
-  let chartDom = document.getElementById('pause-canvas');
-  let myChart = echarts.getInstanceByDom(chartDom);
-  getCanvasData(myChart);
+  noData.value = false
+  setTimeout(()=>{
+    let chartDom = document.getElementById('pause-canvas');
+    if (!chartDom)return;
+    let myChart = echarts.getInstanceByDom(chartDom);
+    if (!myChart){
+      myChart = echarts.init(chartDom);
+    }
+    getCanvasData(myChart);
+  },0)
+
 });
 
 const maxPauseTime = inject('maxPauseTime') as Ref<number>;
@@ -57,11 +69,16 @@ function getCanvasData(chart:EChartsType){
           pauseData.length = 0;
           chartData.length = 0;
           if (!rowData){
-            ElMessage.error('获取停顿数据失败')
+            // ElMessage.error('获取停顿数据失败')
             loadingStatus.value.pause = false;
             chart.hideLoading();
+            noData.value = true
             return;
           }
+          else{
+            loadingStatus.value.pause = false;
+            noData.value = false
+          }
           if (rowData.length>0){
             limit.max = rowData[0].pauseTime;
           }
@@ -169,9 +186,12 @@ onMounted(()=>{
 </script>
 
 <template>
-  <div id="pause-canvas" class="canvas-container">
+  <div id="pause-canvas" class="canvas-container" v-if="!noData">
 
   </div>
+  <div class="canvas-container" v-else>
+    <el-empty description="暂无数据"/>
+  </div>
 </template>
 
 <style scoped>

+ 22 - 6
src/views/BehaviorPage/component/ProcessCanvas.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import {onMounted, type Ref, watch} from "vue";
+import {onMounted, ref, type Ref, watch} from "vue";
 import * as echarts from 'echarts';
 import {inject} from "vue-demi";
 import type {EChartsType} from "echarts";
@@ -14,9 +14,17 @@ let productData = [];
 let cursorData = [];
 let processData = [];
 watch(currentEngagement,()=>{
-  let chartDom = document.getElementById('process-canvas');
-  let myChart = echarts.getInstanceByDom(chartDom);
-  getCanvasData(myChart);
+  noData.value = false
+  setTimeout(()=>{
+    let chartDom = document.getElementById('process-canvas');
+    if (!chartDom)return;
+    let myChart = echarts.getInstanceByDom(chartDom);
+    if (!myChart){
+      myChart = echarts.init(chartDom);
+    }
+    getCanvasData(myChart);
+  },0)
+
 });
 const loadingStatus = inject('loadingStatus') as Ref<{
   edit:boolean,
@@ -66,8 +74,13 @@ function getCanvasData(chart:EChartsType){
           if (!rowData){
             chart.hideLoading();
             loadingStatus.value.process = false;
+            noData.value = true
             return
           }
+          else{
+            loadingStatus.value.process = false;
+            noData.value = false
+          }
           rowData.forEach((item:any) => {
             // console.log("item",item)
             let startStamp = 0;
@@ -225,7 +238,7 @@ function getCanvasData(chart:EChartsType){
   //测试用数据
 
 }
-
+let noData = ref(false)
 
 
 
@@ -240,9 +253,12 @@ onMounted(()=>{
 </script>
 
 <template>
-  <div id="process-canvas" class="canvas-container">
+  <div id="process-canvas" class="canvas-container" v-if="!noData">
 
   </div>
+  <div class="canvas-container" v-else>
+    <el-empty description="暂无数据"/>
+  </div>
 </template>
 
 <style scoped>

+ 28 - 7
src/views/BehaviorPage/component/TotalCanvas.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import {onMounted, type Ref, watch} from "vue";
+import {onMounted, type Ref, watch,ref} from "vue";
 import * as echarts from 'echarts';
 import {inject} from "vue-demi";
 
@@ -18,14 +18,20 @@ const loadingStatus = inject('loadingStatus') as Ref<{
   process:boolean,
   total:boolean
 }>;
-
+let noData = ref(false)
 watch(currentEngagement,()=>{
   if (currentEngagement.value === null){
     return;
   }
-  let chartDom = document.getElementById('total-canvas');
-  let myChart = echarts.getInstanceByDom(chartDom);
-  drawChart(myChart);
+  noData.value = false
+  setTimeout(()=>{
+    let chartDom = document.getElementById('total-canvas');
+    let myChart = echarts.getInstanceByDom(chartDom);
+    if (!myChart){
+      myChart = echarts.init(chartDom);
+    }
+    drawChart(myChart);
+  },0)
 },{deep:true})
 
 let data = []
@@ -42,6 +48,13 @@ function drawChart(chart: EChartsType){
   .then((res:any) => {
     // console.log(res);
     if (res&&res.data&&res.data.code === 200){
+      noData.value = false
+      if (res.data.data.insertCount == 0 && res.data.data.longPauseCount == 0 && res.data.data.deleteCount == 0){
+        noData.value = true;
+        chart.hideLoading();
+        loadingStatus.value.total = false;
+        return
+      }
       data = [
         { value: res.data.data.insertCount, name: '产出行为' },
         { value: res.data.data.longPauseCount, name: '停顿行为' },
@@ -89,6 +102,11 @@ function drawChart(chart: EChartsType){
       chart.hideLoading();
       loadingStatus.value.total = false;
     }
+    else{
+      noData.value = true;
+      chart.hideLoading();
+      loadingStatus.value.total = false;
+    }
   })
 }
 onMounted(()=>{
@@ -102,9 +120,12 @@ onMounted(()=>{
 </script>
 
 <template>
-<div id="total-canvas" class="canvas-container">
+  <div id="total-canvas" class="canvas-container" v-if="!noData">
 
-</div>
+  </div>
+  <div class="canvas-container" v-else>
+    <el-empty description="暂无数据"/>
+  </div>
 </template>
 
 <style scoped>

+ 5 - 3
src/views/ClassPage/ClassHomework.vue

@@ -291,12 +291,14 @@ const getHomeworks = async () => {
             // console.log('----------------------');
             // console.log(res.data.data.records);
             res.data.data.records.forEach(item => Homeworksdata.value.push(item))
+            if(res.data.data.records.length!=0){
             ShowTheHomework.value = res.data.data.records[0].assignmentName
             ShowTheHomeworkId.value = res.data.data.records[0].assignmentId
+            }
         })
     // t.forEach(item => Homeworksdata.value.push(item))
     HomeworkDataLoading.value = true
-    console.log(ShowTheHomeworkId.value);
+    console.log('ShowTheHomeworkId',ShowTheHomeworkId.value);
 }
 const getStudents = () => {
     StudentsDataLoading.value=false
@@ -306,12 +308,12 @@ const getStudents = () => {
         .then((res:any)=>{
             console.log(res.data.data);
             Studentsdata.value = res.data.data
-            StudentsDataLoading.value = true
         })
         .catch((err:any)=>{
             console.log('-------------------------');
             console.log(err);
         })
+        StudentsDataLoading.value = true
 }
 const changeHomework = () => {
     console.log(ShowTheHomework.value)
@@ -348,7 +350,7 @@ const showData = computed(() => {
 })
 
 const DataLoading = computed(() => {
-  return StudentsDataLoading.value && HomeworkDataLoading.value
+   return StudentsDataLoading.value && HomeworkDataLoading.value
 })
 
 watch(TheHomework, () => {

+ 18 - 15
src/views/ClassPage/StudentDetail.vue

@@ -109,6 +109,7 @@ import { useStore } from "@/store"
 import classHeader from './components/classHeader.vue';
 import type {CourseDetailVO, ClassVO, ClassStudentVO} from "@/types/vo";
 import useApis from "@/apis";
+import { log } from 'console';
 
 const route = useRoute()
 const store = useStore()
@@ -211,20 +212,21 @@ const Studentdata = ref({
     "studentId": 0,
     "assignments":[]
 })
-const getStudent = () => {
+const getStudent = async () => {
     StudentdataLoading.value = false
     console.log(courseId)
     console.log(studentId)
-    apis.getHomeworkOfStudent(courseId,studentId)
+    await apis.getHomeworkOfStudent(courseId,studentId)
         .then((res:any)=>{
             Studentdata.value = res.data.data
-            console.log(res.data.data);
-            StudentdataLoading.value = true
+            console.log('zcx',Studentdata.value);
         })
+    StudentdataLoading.value = true
+    console.log('zzzz','修改',StudentdataLoading.value);
 }
-const getClass = () => {
+const getClass = async () => {
     console.log("classId:",classId)
-    apis.getClassByClassId(classId)
+    await apis.getClassByClassId(classId)
         .then((res:any)=>{
             console.log(res.data.data);
             Classdata.value = res.data.data
@@ -235,22 +237,23 @@ const getClass = () => {
     ClassDataLoading.value = true
 }
 
-const getCourse = () => {
+const getCourse = async () => {
   // 获取课程信息
-  apis.getCourseByCourseId(courseId)
+    await apis.getCourseByCourseId(courseId)
       .then((res: any) => {
         let data = res.data.data.records[0]
         Object.assign(Coursedata, {...data})
-        CourseDataLoading.value = true
       })
       .catch((err: any) => {
         console.error(err);
       })
+    CourseDataLoading.value = true
 }
 
 const DataLoading = computed(() => {
 //   return CourseDataLoading.value && ClassDataLoading.value
     if(store.user.role === "STUDENT"){
+        console.log('finally',StudentdataLoading.value,CourseDataLoading.value,ClassDataLoading.value)
         return StudentdataLoading.value && CourseDataLoading.value && ClassDataLoading.value
     }
     else{
@@ -259,14 +262,14 @@ const DataLoading = computed(() => {
 })
 const searchData = computed(()=>{
     if(searchInput.value===""){
-        return Studentdata.value.assignments
+        return Studentdata.value.assignments??[]
     }
     else{
         return Studentdata.value.assignments.filter(student => {
           return (
             student.assignmentName.includes(searchInput.value)
           )
-        })
+        })??[]
     }
 })
 const showData = computed(() => {
@@ -318,13 +321,13 @@ watch(ShowTheSort,(newData) =>{
     }
 })
 
-onMounted(() => {
+onMounted(async () => {
     // identify()
     if(store.user.role === "STUDENT"){
-        getCourse()
-        getClass()
+        await getCourse()
+        await getClass()
     }
-    getStudent()
+    await getStudent()
     
 })
 </script>

+ 21 - 6
src/views/CourseSquare/component/CourseDetails/component/CourseHomeworkTable.vue

@@ -235,23 +235,38 @@ const openEditor = (url: string, title: string) => {
   /*
   鼠标聚焦于功能按钮(写作or编辑)时,显示提示信息
    */
+  let lastTriggerTime = 0;
+
+  // 防抖函数
+  const throttleMessage = () => {
+    const currentTime = Date.now();
+    
+    // 如果距离上次触发时间小于5秒,则不执行
+    if (currentTime - lastTriggerTime < 5000) {
+      return false;
+    }
+    
+    // 更新触发时间并执行
+    lastTriggerTime = currentTime;
+    return true;
+  };
   let hover = false
   const handleMouse = (type: string, teacherId:string, endDate:string) => {
     if(!hover && type == 'over'){
        hover = true;
        //如果被禁用则提示
-      if(props.disabled || isDisabled(teacherId, endDate)){
+      if((props.disabled || isDisabled(teacherId, endDate))&&throttleMessage()){
         if(props.role == 'student'){
           if(props.disabled){
-            ElMessage.error('请先加入课程')
+            ElMessage.warning('请先加入课程')
           } else {
-            ElMessage.error('作业已经超过截止时间')
+            ElMessage.warning('作业已经超过截止时间')
           }
         }else if(props.role == 'teachers'){
-          ElMessage.error('无权限')
+          ElMessage.warning('无权限')
         }
       }
-    } else if(hover && type == 'leave'){
+    } else if(hover && type == 'leave'){                    
       hover = false
     }
   }
@@ -272,7 +287,7 @@ const openEditor = (url: string, title: string) => {
   }
 
   const handleWriting = (assignmentId:number) => {
-    router.push(`/home/homeworkDetail/${assignmentId}`);
+    router.push(`/home/homeworkDetail/${assignmentId}?fromCourse=1`);
     // Location.reload()
   }
 

+ 14 - 7
src/views/HomeworkPage/component/HomeworkDetail.vue

@@ -228,13 +228,20 @@ const fetchData = () => {
 
 const handleBack = () => {
    // 跳转到我的作业页面,携带课程ID参数以便自动选中对应课程
-   router.push({
-     path: '/home/myHomework',
-     query: {
-       courseId: data.courseId,
-       fromAssignment: 'true'
-     }
-   }).then(() => {window.location.reload()})
+  const { fromCourse} = route.query
+  if (!fromCourse){
+    router.push({
+      name: 'myHomework',
+      query: {
+        courseId: data.courseId,
+        fromAssignment: 'true'
+      }
+    }).then(() => {window.location.reload()})
+  }
+  else{
+    router.back()
+  }
+
 }
 
 onMounted(() => {