Ver código fonte

离开活体检测页面时,关闭ws。非考试页面不发心跳。添加断点续考信息。

Michael Wang 6 anos atrás
pai
commit
065b757499

+ 35 - 17
src/features/OnlineExam/Examing/FaceId.vue

@@ -10,7 +10,7 @@
       </div>
     </div>
     <div id="faceIdDiv" style="position: relative;
-								  height:620px; background-color: #6e6f72!important;
+								  height:620px; background-color: #6e6f72 !important;
   								background-image: radial-gradient(circle at 50% 0,#a9a9a9,#34363c);">
       <div v-show="!showIframe" width="100%" height="200px" style="text-align: center;line-height:100px;margin-top:5px;">
         <div style="color:white;font-weight: bold;font-size:20px;">
@@ -43,6 +43,15 @@ export default {
     console.debug("startFaceVerify");
     this.startFaceVerify();
   },
+  beforeDestroy() {
+    try {
+      if (this.ws && this.ws.readyState === 1) this.ws.close();
+    } catch (e) {
+      console.log("关闭ws异常。");
+    }
+    clearTimeout(this.faceIdTime);
+    clearInterval(this.timeCountInterval);
+  },
   methods: {
     showRedo(redoMsg) {
       this.showIframe = false;
@@ -96,31 +105,34 @@ export default {
       const examRecordId = this.$route.params.examRecordDataId;
 
       this.timeCount = 60; //人脸检测倒计时60秒
-      var timeCountInterval = setInterval(() => {
+      this.timeCountInterval = setInterval(() => {
         --this.timeCount;
         if (this.timeCount === 0) {
-          clearInterval(timeCountInterval);
+          clearInterval(this.timeCountInterval);
         }
       }, 1000);
 
       //定时事件,如果1分钟内未完成人脸检测,执行内部程序
-      var faceIdTime = setTimeout(() => {
-        ws.close();
-        var that = this;
+      this.faceIdTime = setTimeout(() => {
+        this.ws.close();
         this.$http
           .get(
             "/api/ecs_oe_student/examFaceLivenessVerify/faceLivenessVerifyTimeOut/" +
               examRecordId
           )
-          .then(function success(response) {
+          .then(response => {
             if (response.status == 200) {
               var receivedMsg = response.data;
-              that.faceTestEnd(receivedMsg);
+              this.faceTestEnd(receivedMsg);
             }
           })
           .finally(() => {
             // Chrome 63开始支持。但是vue-cli引入了p-finally,所以已经加在Promise对象中了
-            clearInterval(timeCountInterval);
+            clearInterval(this.timeCountInterval);
+            this.$Message.error({
+              content: "第一次人脸检测超时,系统退出,请重新登录",
+              duration: 30
+            });
             this.logout();
           });
       }, 60000); //60000
@@ -139,6 +151,10 @@ export default {
             if (result != "SUCCESS") {
               this.logout();
             }
+          })
+          .catch(() => {
+            this.$Message.error("上传人脸检测结果出错!");
+            this.logout();
           });
       };
       /**
@@ -173,7 +189,6 @@ export default {
           }
         } else if (receivedMsg.verifyCount >= 2) {
           if (receivedMsg.verifyResult == "VERIFY_SUCCESS") {
-            // FIXME: 什么逻辑?
             this.$Message.info({
               content: "人脸检测成功,请继续完成考试",
               duration: 15
@@ -190,21 +205,23 @@ export default {
       };
 
       // open websocket
-      var ws = new WebSocket(VUE_APP_WK_SERVER_SOCKET + examRecordId);
-      ws.onopen = function() {
+      this.ws = new WebSocket(VUE_APP_WK_SERVER_SOCKET + examRecordId);
+      this.ws.onopen = function() {
         console.log("websocket已连接");
       };
-      ws.onmessage = response => {
+      this.ws.onmessage = response => {
         if (response.data.indexOf("verifyResult") > -1) {
           var receivedMsg = JSON.parse(response.data);
           this.faceTestEnd(receivedMsg);
-          clearTimeout(faceIdTime);
-          clearInterval(timeCountInterval);
+          clearTimeout(this.faceIdTime);
+          clearInterval(this.timeCountInterval);
           this.$emit("closeFaceId");
-          ws.close();
+          this.ws.close();
         }
       };
-      ws.onclose = function() {
+
+      // 重复关闭不会报错
+      this.ws.onclose = function() {
         console.log("websocket连接已关闭...");
       };
     },
@@ -231,6 +248,7 @@ export default {
           content: "您上传的底照不适合做活体检测,请联系老师!",
           duration: 30
         });
+        this.logout();
         return;
       }
 

+ 4 - 0
src/features/OnlineExam/Examing/RemainTime.vue

@@ -32,6 +32,10 @@ export default {
   methods: {
     ...mapMutations(["setShouldSubmitPaper"]),
     async getRemainTimeFromServer() {
+      if (this.$route.name !== "OnlineExamingHome") {
+        // 非考试页,不继续发心跳。可能退出后再进,导致心跳多发一次。可能会话已过期。
+        return;
+      }
       try {
         const res = await this.$http.get(
           "/api/ecs_oe_student/examControl/examHeartbeat"

+ 7 - 0
src/features/OnlineExam/OnlineExamHome.vue

@@ -25,6 +25,11 @@ export default {
     };
   },
   async mounted() {
+    this.$Spin.show({
+      render: () => {
+        return <div style="font-size: 24px">正在获取断点续考信息...</div>;
+      }
+    });
     try {
       // 断点续考
       const examingRes = (await this.$http.get(
@@ -46,6 +51,8 @@ export default {
       this.$Message.error("获取断点续考信息异常,退出登录");
       this.logout();
       return;
+    } finally {
+      this.$Spin.hide();
     }
 
     const res = await this.$http.get(