فهرست منبع

feat: 添加批改页面学生切换和进度显示功能

stupig-zcx 1 سال پیش
والد
کامیت
0d617403fb

+ 17 - 0
src/apis/engagement.ts

@@ -64,6 +64,23 @@ const engagementApis = {
                 assignmentId
             }
         })
+    },
+    // 获取下一个学生作业ID
+    getNextStudentAssignment: (assignmentId: number, studentId: number) => {
+        return axiosInstance.get(`${ENGAGE_PREFIX}/next`, {
+            params: {
+                assignmentId,
+                studentId
+            }
+        })
+    },
+    // 获取当前作业参与及批改情况
+    getAssignmentCorrectionStats: (assignmentId: number) => {
+        return axiosInstance.get(`${ENGAGE_PREFIX}/number`, {
+            params: {
+                assignmentId
+            }
+        })
     }
 }
 

+ 9 - 5
src/router/index.ts

@@ -16,13 +16,17 @@ const router = createRouter({
     },
 
     // 登录与注册
+    // {
+    //   path: "/",
+    //   redirect: () => {
+    //     window.location.href = "https://p-nju.seec.seecoder.cn/login?from=https://air.seec.seecoder.cn/";
+    //     // {本地门户首页地址}?from={本地eai首页地址}
+    //     return "/"; // 占位返回值,实际不会执行
+    // },
+    // },
     {
       path: "/",
-      redirect: () => {
-        window.location.href = "https://p-nju.seec.seecoder.cn/login?from=https://air.seec.seecoder.cn/";
-        // {本地门户首页地址}?from={本地eai首页地址}
-        return "/"; // 占位返回值,实际不会执行
-    },
+      redirect: "/login"
     },
     {
       path: '/login',

+ 104 - 4
src/views/AiSpeakingPage/SpeakingRecord.vue

@@ -251,9 +251,23 @@
               score-template="{value} 分"
             />
           </div>
-          <el-button style="background-color:#597D3B;color:white" @click="submitComment" class="submit-button"
-            >提交评语</el-button
-          >
+          <div class="correction-actions">
+            <div class="button-container">
+              <el-button 
+                style="background-color:#597D3B;color:white;width:300px" 
+                @click="submitComment" 
+                class="submit-button"
+                :loading="submitting"
+              >
+                提交评语
+              </el-button>
+              
+              <!-- 批改进度数字显示 -->
+              <div class="progress-numbers">
+                {{ correctionStats.correctNumber }}/{{ correctionStats.engageNumber }}
+              </div>
+            </div>
+          </div>
         </template>
       </div>
     </el-card>
@@ -261,7 +275,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted, onBeforeUnmount, nextTick, defineProps } from "vue";
+import { ref, onMounted, onBeforeUnmount, nextTick, defineProps, computed } from "vue";
 import doubaoApis from "@/apis/doubao";
 import engagementApis from "@/apis/engagement";
 import mediaApis from "@/apis/media";
@@ -321,6 +335,44 @@ const engagement = ref({
 
 const isSuggestionLoading = ref(true);
 const isVideoEmotionLoading = ref(true);
+const submitting = ref(false);
+
+// 批改进度统计
+const correctionStats = ref({
+  engageNumber: 0,
+  correctNumber: 0
+});
+
+// 计算批改进度百分比
+const progressPercentage = computed(() => {
+  if (correctionStats.value.engageNumber === 0) return 0;
+  return Math.round((correctionStats.value.correctNumber / correctionStats.value.engageNumber) * 100);
+});
+
+// 获取批改进度统计
+const fetchCorrectionStats = async () => {
+  try {
+    const res = await engagementApis.getAssignmentCorrectionStats(props.assignmentId);
+    if (res.data.code === 200) {
+      correctionStats.value = res.data.data;
+    }
+  } catch (error) {
+    console.error('获取批改进度失败:', error);
+  }
+};
+
+// 获取下一个学生作业ID
+const getNextStudentAssignment = async () => {
+  try {
+    const res = await engagementApis.getNextStudentAssignment(props.assignmentId, props.userId);
+    if (res.data.code === 200) {
+      return res.data.data;
+    }
+  } catch (error) {
+    console.error('获取下一个学生失败:', error);
+  }
+  return null;
+};
 
 const emotionChartRef = ref(null);
 let emotionChartInstance = null;
@@ -376,6 +428,8 @@ const submitComment = async () => {
     ElMessage.warning("请填写评语和评分");
     return;
   }
+  
+  submitting.value = true;
   try {
     // 调用 API 提交评语和评分
     const response = await engagementApis.engagementCorrect(
@@ -388,12 +442,34 @@ const submitComment = async () => {
     );
     if (response.data.code === 200) {
       ElMessage.success("评语提交成功");
+      
+      // 获取下一个学生作业ID
+      const nextStudentId = await getNextStudentAssignment();
+      
+      if (nextStudentId) {
+        // 跳转到下一个学生的作业
+        router.push({
+          path: `/home/assignment/${props.assignmentId}/airecord`,
+          query: {
+            userId: nextStudentId,
+            assignmentId: props.assignmentId,
+            assignmentName: props.assignmentName
+          }
+        });
+        ElMessage.success("已自动跳转到下一个学生");
+      } else {
+        // 没有下一个学生,跳转到作业列表
+        router.push(`/home/myCorrect/assignment/${props.assignmentId}`);
+        ElMessage.info("已是最后一个学生,批改完成");
+      }
     } else {
       ElMessage.error("评语提交失败");
     }
   } catch (error) {
     console.error("提交评语失败:", error);
     ElMessage.error("网络错误,请重试");
+  } finally {
+    submitting.value = false;
   }
 };
 
@@ -849,6 +925,10 @@ onMounted(async () => {
       score: engagementRes.data.data.score || 0,
       remark: engagementRes.data.data.remark || "",
     };
+    
+    // 获取批改进度统计
+    await fetchCorrectionStats();
+    
     // 渲染每个对话的图表
     nextTick(() => {
       renderAvgScoreChart();
@@ -1106,4 +1186,24 @@ onMounted(async () => {
 .el-card {
   margin-bottom: 30px !important;
 }
+
+.correction-actions {
+  display: flex;
+  justify-content: center;
+  margin-top: 10px;
+}
+
+.button-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 8px;
+}
+
+.progress-numbers {
+  font-size: 13px;
+  color: #999;
+  font-weight: 400;
+  margin-left: 0;
+}
 </style>

+ 94 - 6
src/views/Home/component/Remark/Remark.vue

@@ -10,7 +10,33 @@
       <textarea v-model="correction.remark" placeholder="暂无评语" :readonly="isStudent"></textarea>
     </div>
 
-    <el-button color="#597D3B" @click="handleCorrect" v-if="!isStudent">提交批改</el-button>
+    <div class="correction-actions">
+      <div class="button-with-progress">
+        <el-button 
+          color="#597D3B" 
+          @click="handleCorrect" 
+          v-if="!isStudent"
+          :loading="submitting"
+        >
+          提交批改
+        </el-button>
+        
+        <!-- 批改进度数字显示 -->
+        <span class="progress-numbers" v-if="!isStudent">
+          {{ correctionStats.correctNumber }}/{{ correctionStats.engageNumber }}
+        </span>
+      </div>
+      
+      <!-- 批改进度条显示 -->
+      <div class="correction-progress" v-if="!isStudent">
+        <el-progress 
+          :percentage="progressPercentage" 
+          :stroke-width="6"
+          color="#597D3B"
+          class="progress-bar"
+        />
+      </div>
+    </div>
   </div>
 </template>
 
@@ -24,7 +50,6 @@ import { useStore } from "@/store";
 
 const store = useStore()
 
-
 export default defineComponent({
   props: {
     studentId: {
@@ -38,6 +63,7 @@ export default defineComponent({
   },
   setup(props) {
     const isStudent = computed(() => store.user.role === 'STUDENT');
+    const submitting = ref(false);
 
     //定义一个correction接收后端传过来的批改信息(如果有) 
     const correction = ref({
@@ -45,6 +71,31 @@ export default defineComponent({
       remark: ''
     });
 
+    // 批改进度统计
+    const correctionStats = ref({
+      engageNumber: 0,
+      correctNumber: 0
+    });
+
+    // 计算批改进度百分比
+    const progressPercentage = computed(() => {
+      if (correctionStats.value.engageNumber === 0) return 0;
+      return Math.round((correctionStats.value.correctNumber / correctionStats.value.engageNumber) * 100);
+    });
+
+    // 获取批改进度统计
+    const fetchCorrectionStats = async () => {
+      const apis = useApis();
+      try {
+        const res = await apis.getAssignmentCorrectionStats(props.assignmentId);
+        if (res.data.code === 200) {
+          correctionStats.value = res.data.data;
+        }
+      } catch (error) {
+        console.error('获取批改进度失败:', error);
+      }
+    };
+
     //新增:获取后台批改数据
     const fetchCorrection = async () => {
       const apis = useApis();
@@ -63,9 +114,23 @@ export default defineComponent({
       }
     };
 
+    // 获取下一个学生作业ID
+    const getNextStudentAssignment = async () => {
+      const apis = useApis();
+      try {
+        const res = await apis.getNextStudentAssignment(props.assignmentId, props.studentId);
+        if (res.data.code === 200) {
+          return res.data.data;
+        }
+      } catch (error) {
+        console.error('获取下一个学生失败:', error);
+      }
+      return null;
+    };
 
     onMounted(() => {
       fetchCorrection();
+      fetchCorrectionStats();
     });
 
     const handleCorrect = async () => {
@@ -73,19 +138,39 @@ export default defineComponent({
         ElMessage.error("学生不能提交批改");
         return;
       } else {
+        submitting.value = true;
         const apis = useApis();
         try {
           await apis.engagementCorrect(props.studentId, props.assignmentId, correction.value)
-            .then(res => {
+            .then(async (res) => {
               if (res.data.code === 200) {
                 ElMessage.success("批改成功");
-                router.push(`/home/myCorrect/assignment/${props.assignmentId}`);
+                
+                // 获取下一个学生作业ID
+                const nextStudentId = await getNextStudentAssignment();
+                
+                if (nextStudentId) {
+                  // 跳转到下一个学生的作业
+                  router.push({
+                    name: 'correct',
+                    params: { assignmentId: props.assignmentId },
+                    query: { studentId: nextStudentId }
+                  });
+                  ElMessage.success("已自动跳转到下一个学生");
+                } else {
+                  // 没有下一个学生,跳转到作业列表
+                  router.push(`/home/myCorrect/assignment/${props.assignmentId}`);
+                  ElMessage.info("已是最后一个学生,批改完成");
+                }
               } else {
                 ElMessage.error("批改异常" + res.data.msg);
               }
             });
         } catch (err) {
-          console.log(err)
+          console.log(err);
+          ElMessage.error("批改失败,请重试");
+        } finally {
+          submitting.value = false;
         }
       }
     };
@@ -93,7 +178,10 @@ export default defineComponent({
     return {
       correction,
       handleCorrect,
-      isStudent
+      isStudent,
+      submitting,
+      correctionStats,
+      progressPercentage
     };
   }
 });  

+ 41 - 1
src/views/Home/component/Remark/index.scss

@@ -1,4 +1,3 @@
-
 .remark {  
   display: flex;  
   flex-direction: column; // 垂直布局  
@@ -43,4 +42,45 @@ textarea {
   border-radius: 4px; // 边框圆角  
   font-size: 18px;  
   resize: none; // 禁止用户调整大小
+}   
+
+.correction-actions {
+  display: flex;
+  flex-direction: column;
+  gap: 15px;
+  margin-top: 10px;
+  
+  // 让按钮保持原来的宽度
+  .el-button {
+    width: fit-content;
+    align-self: flex-start;
+  }
+}
+
+.button-with-progress {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  
+  .progress-numbers {
+    font-size: 13px;
+    color: #999;
+    font-weight: 400;
+  }
+}
+
+.correction-progress {
+  display: flex;
+  flex-direction: column;
+  gap: 8px;
+  
+  .progress-text {
+    font-size: 14px;
+    color: #666;
+    font-weight: 500;
+  }
+  
+  .progress-bar {
+    width: 100%;
+  }
 }