Просмотр исходного кода

feat: 修复交卷结束之后还会提示上传答案失败的问题

chenhao 2 лет назад
Родитель
Сommit
1ec7be9f9d

+ 9 - 4
src/features/OnlineExam/Examing/ExamingHome.vue

@@ -23,7 +23,7 @@ import { useFaceLive } from "./setups/useFaceLive";
 import { useFaceCompare } from "./setups/useFaceCompare";
 import { initExamData } from "./setups/useInitExamData";
 import { useWXSocket } from "./setups/useWXSocket";
-import { answerAllQuestions } from "./setups/useAnswerQuestions";
+import { useAnswerQuestions } from "./setups/useAnswerQuestions";
 import { useRealSubmitPaper } from "./setups/useSubmitPaper";
 import { Store } from "@/types/student-client";
 import { closeMediaStream } from "@/utils/camera";
@@ -34,8 +34,13 @@ store.exam.compareResultMap = new Map();
 
 const { addTimeout, addInterval } = useTimers();
 
+const answerAllQuestions = useAnswerQuestions();
+
 let loading = $ref(true);
-let usedExamTimes = reactive({ usedExamSeconds: 0, startTimestamp: Date.now() });
+let usedExamTimes = reactive({
+  usedExamSeconds: 0,
+  startTimestamp: Date.now(),
+});
 const route = useRoute();
 const examId = +route.params.examId;
 const examRecordDataId = +route.params.examRecordDataId;
@@ -127,8 +132,8 @@ function onStartAnswer({
 }: {
   usedExamSeconds: number;
 }) {
-  usedExamTimes.usedExamSeconds = n
-  usedExamTimes.startTimestamp = Date.now()
+  usedExamTimes.usedExamSeconds = n;
+  usedExamTimes.startTimestamp = Date.now();
 }
 
 type CompareResult = { hasError: boolean; fileName: string };

+ 71 - 48
src/features/OnlineExam/Examing/setups/useAnswerQuestions.ts

@@ -4,6 +4,8 @@ import { AudioPlayTime } from "@/types/student-client";
 import { doEnc } from "@/utils/encDec";
 import { MD5 } from "@/utils/md5";
 import { getKey } from "@/utils/utils";
+import { onUnmounted, getCurrentInstance } from "vue";
+import axios from "axios";
 
 function resetExamQuestionDirty() {
   store.exam.examQuestionList = store.exam.examQuestionList.map((eq) => {
@@ -18,56 +20,77 @@ type Answer = {
   isStarred: boolean;
 };
 
-export async function answerAllQuestions(
-  ignoreDirty?: boolean
-): Promise<boolean> {
-  // 根据线上错误排查:可能已经退出页面了,没有数据了
-  if (!store.exam.examQuestionList) return false;
-  const answers: Answer[] = store.exam.examQuestionList
-    .filter((eq) => (ignoreDirty ? true : eq.dirty))
-    .filter((eq) => eq.gotQuestionContent)
-    .map((eq) => {
-      return Object.assign(
-        {
-          order: eq.order,
-          studentAnswer: eq.studentAnswer,
-        },
-        eq.audioPlayTimes && {
-          audioPlayTimes: JSON.stringify(eq.audioPlayTimes) as any,
-        },
-        eq.isStarred && { isStarred: eq.isStarred }
-      ) as Answer;
-    });
-  if (answers.length > 0) {
-    const timestamp = Date.now();
-    const rawStr = MD5(JSON.stringify(answers));
+export const useAnswerQuestions = () => {
+  let abortcontroller: AbortController | null;
 
-    const key = getKey(timestamp);
+  function cancel() {
+    if (abortcontroller && !abortcontroller.signal.aborted) {
+      abortcontroller.abort();
+      abortcontroller = null;
+    }
+  }
+  if(getCurrentInstance()){
+    onUnmounted(cancel);
+  }
+  return async function answerAllQuestions(
+    ignoreDirty?: boolean
+  ): Promise<boolean> {
+    // 根据线上错误排查:可能已经退出页面了,没有数据了
+    if (!store.exam.examQuestionList) return false;
+
+    const answers: Answer[] = store.exam.examQuestionList
+      .filter((eq) => (ignoreDirty ? true : eq.dirty))
+      .filter((eq) => eq.gotQuestionContent)
+      .map((eq) => {
+        return Object.assign(
+          {
+            order: eq.order,
+            studentAnswer: eq.studentAnswer,
+          },
+          eq.audioPlayTimes && {
+            audioPlayTimes: JSON.stringify(eq.audioPlayTimes) as any,
+          },
+          eq.isStarred && { isStarred: eq.isStarred }
+        ) as Answer;
+      });
+    if (answers.length > 0) {
+      const timestamp = Date.now();
+      const rawStr = MD5(JSON.stringify(answers));
+
+      const key = getKey(timestamp);
 
-    const sign = doEnc(rawStr, key);
+      const sign = doEnc(rawStr, key);
 
-    try {
-      await httpApp.post(
-        "/api/ecs_oe_student/examControl/submitQuestionAnswer",
-        { answers: JSON.stringify(answers), sign },
-        {
-          "axios-retry": { retries: 4 },
-          noErrorMessage: true,
-          headers: { timestamp },
+      cancel();
+
+      abortcontroller = new AbortController();
+
+      try {
+        await httpApp.post(
+          "/api/ecs_oe_student/examControl/submitQuestionAnswer",
+          { answers: JSON.stringify(answers), sign },
+          {
+            "axios-retry": { retries: 4 },
+            noErrorMessage: true,
+            headers: { timestamp },
+            signal: abortcontroller.signal,
+          }
+        );
+        resetExamQuestionDirty();
+      } catch (error) {
+        if (!axios.isCancel(error)) {
+          logger({
+            cnl: ["server", "local"],
+            pgu: "AUTO",
+            act: "提交答案失败",
+            possibleError: error,
+          });
+          $message.error("提交答案失败");
         }
-      );
-      resetExamQuestionDirty();
-    } catch (error) {
-      logger({
-        cnl: ["server", "local"],
-        pgu: "AUTO",
-        act: "提交答案失败",
-        possibleError: error,
-      });
-      $message.error("提交答案失败");
-      return false;
+        return false;
+      }
     }
-  }
-  // 提交成功,返回true,供最后提交时判断。自动提交失败,不暂停。
-  return true;
-}
+    // 提交成功,返回true,供最后提交时判断。自动提交失败,不暂停。
+    return true;
+  };
+};

+ 2 - 2
src/features/OnlineExam/Examing/setups/useSubmitPaper.tsx

@@ -1,7 +1,7 @@
 import router from "@/router";
 import { useTimers } from "@/setups/useTimers";
 import { store } from "@/store/store";
-import { answerAllQuestions } from "./useAnswerQuestions";
+import { useAnswerQuestions } from "./useAnswerQuestions";
 
 export function useRealSubmitPaper(
   examId: number,
@@ -9,7 +9,7 @@ export function useRealSubmitPaper(
   doSnap: () => void
 ) {
   const { addTimeout } = useTimers();
-
+  const answerAllQuestions = useAnswerQuestions()
   async function userSubmitPaper(usedExamTimes: {
     usedExamSeconds: number;
     startTimestamp: number;