Răsfoiți Sursa

Merge branch 'master' into dev_v4.1.3

chenhao 2 ani în urmă
părinte
comite
3fc3eae159

+ 17 - 3
src/features/OnlineExam/Examing/ExamingHome.vue

@@ -14,7 +14,7 @@ import { httpApp } from "@/plugins/axiosApp";
 import { useTimers } from "@/setups/useTimers";
 import { checkMainExe } from "@/utils/nativeMethods";
 import { showLogout } from "@/utils/utils";
-import { onBeforeUpdate, onMounted, onUnmounted, watch } from "vue";
+import { onBeforeUpdate, onMounted, onUnmounted, watch, reactive } from "vue";
 import { useRoute } from "vue-router";
 import { store } from "@/store/store";
 import { useRemoteAppChecker } from "@/features/UserLogin/useRemoteAppChecker";
@@ -35,6 +35,7 @@ store.exam.compareResultMap = new Map();
 const { addTimeout, addInterval } = useTimers();
 
 let loading = $ref(true);
+let usedExamTimes = reactive({ usedExamSeconds: 0, startTimestamp: Date.now() });
 const route = useRoute();
 const examId = +route.params.examId;
 const examRecordDataId = +route.params.examRecordDataId;
@@ -50,7 +51,7 @@ const { userSubmitPaper, realSubmitPaper } = useRealSubmitPaper(
 
 async function userClickSubmit() {
   store.increaseGlobalMaskCount("userClickSubmit");
-  void userSubmitPaper();
+  void userSubmitPaper(usedExamTimes);
   // 一定要在这里等待,不然用户快速双击就会点两次
   await new Promise((res) => setTimeout(res, 1000));
   store.decreaseGlobalMaskCount("userClickSubmit");
@@ -115,6 +116,16 @@ onMounted(async () => {
   });
 });
 
+/** 开始作答 */
+function onStartAnswer({
+  usedExamSeconds: n = 0,
+}: {
+  usedExamSeconds: number;
+}) {
+  usedExamTimes.usedExamSeconds = n
+  usedExamTimes.startTimestamp = Date.now()
+}
+
 //#region 人脸抓拍与活体检测
 let { snapId, doSnap, showSnapResult } = useFaceCompare();
 let { showFaceId } = useFaceLive(doSnap);
@@ -216,7 +227,10 @@ const userInfo = $computed(
 <template>
   <div v-if="!loading" class="container">
     <div class="header">
-      <RemainTime @onEndtime="shouldSubmitPaper"></RemainTime>
+      <RemainTime
+        @onEndtime="shouldSubmitPaper"
+        @onStartAnswer="onStartAnswer"
+      ></RemainTime>
       <div class="tw-flex tw-flex-wrap tw-justify-between">
         <div>{{ store.exam.courseName }}</div>
         <OverallProgress></OverallProgress>

+ 9 - 2
src/features/OnlineExam/Examing/RemainTime.vue

@@ -7,7 +7,10 @@ import moment from "moment";
 import { onMounted, onUnmounted, watch } from "vue";
 import { useRoute } from "vue-router";
 
-const emit = defineEmits<{ (e: "on-endtime"): void }>();
+const emit = defineEmits<{
+  (e: "on-endtime"): void;
+  (e: "on-start-answer", data: { usedExamSeconds: number }): void;
+}>();
 
 const route = useRoute();
 let remainTime: number | null = $ref(null);
@@ -44,11 +47,15 @@ addTimeout(() => (enhancedRemainTimeStyle = false), 10 * 1000);
 
 onMounted(async () => {
   try {
-    await httpApp.post(
+    const result = await httpApp.post(
       "/api/ecs_oe_student/examControl/startAnswer?examRecordDataId=" +
         route.params.examRecordDataId,
       { "axios-retry": { retries: 4 }, noErrorMessage: true }
     );
+
+    emit("on-start-answer", {
+      usedExamSeconds: result?.data?.usedExamSeconds || 0,
+    });
   } catch (error) {
     const msg = "/startAnswer 出错";
     logger({ cnl: ["server"], pgu: "AUTO", act: msg, possibleError: error });

+ 22 - 10
src/features/OnlineExam/Examing/setups/useSubmitPaper.tsx

@@ -8,7 +8,28 @@ export function useRealSubmitPaper(examId: number, examRecordDataId: number) {
   const { addTimeout } = useTimers();
   const { doSnap } = useFaceCompare();
 
-  async function userSubmitPaper() {
+  async function userSubmitPaper(usedExamTimes: {
+    usedExamSeconds: number;
+    startTimestamp: number;
+  }) {
+    // if (
+    //   store.exam.freezeTime &&
+    //   store.exam.remainTime >
+    //     (store.exam.duration - store.exam.freezeTime) * 60 * 1000
+    // ) {
+    //   $message.info(`考试开始${store.exam.freezeTime}分钟后才允许交卷。`);
+    //   return;
+    // }
+    if (
+      store.exam.freezeTime &&
+      usedExamTimes.usedExamSeconds * 1000 +
+        Date.now() -
+        usedExamTimes.startTimestamp <
+        store.exam.freezeTime * 60 * 1000
+    ) {
+      $message.info(`考试开始${store.exam.freezeTime}分钟后才允许交卷。`);
+      return;
+    }
     logger({ cnl: ["server", "local", "console"], act: "学生点击交卷" });
     try {
       // 交卷前强制提交所有答案
@@ -21,15 +42,6 @@ export function useRealSubmitPaper(examId: number, examRecordDataId: number) {
       return;
     }
 
-    if (
-      store.exam.freezeTime &&
-      store.exam.remainTime >
-        (store.exam.duration - store.exam.freezeTime) * 60 * 1000
-    ) {
-      $message.info(`考试开始${store.exam.freezeTime}分钟后才允许交卷。`);
-      return;
-    }
-
     const answered = store.exam.examQuestionList.filter(
       (q) => q.studentAnswer !== null
     ).length;

+ 2 - 3
src/features/UserLogin/useNewVersion.ts

@@ -9,10 +9,9 @@ export function useNewVersion() {
     const myHeaders = new Headers();
     myHeaders.append("Content-Type", "application/javascript");
     myHeaders.append("Cache-Control", "no-cache");
+    const scripts = document.scripts;
     const response = await fetch(
-      [...document.scripts].at(-1)?.getAttribute("data-src") +
-        "?x" +
-        Date.now(),
+      scripts[scripts.length - 1]?.getAttribute("data-src") + "?x" + Date.now(),
       {
         method: import.meta.env.DEV ? "GET" : "HEAD",
         headers: myHeaders,