|
@@ -0,0 +1,227 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="row" style="margin: 0;">
|
|
|
|
+ <div class="col-md-12 text-center" style="padding:8px;">
|
|
|
|
+ <div style="font-size: 30px;">
|
|
|
|
+ <span>人脸检测</span>
|
|
|
|
+ <span v-if="showIframe">({{timeCount}})</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div v-if="showIframe" class="text-center" style="color: red; font-size: 16px;">
|
|
|
|
+ (注意:请点击下方“开始比对”按钮并在60秒内完成人脸检测,超时将退出考试)
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div id="faceIdDiv" style="position: relative;
|
|
|
|
+ height:620px;
|
|
|
|
+ background-color: #6e6f72!important;
|
|
|
|
+ background-image: radial-gradient(circle at 50% 0,#a9a9a9,#34363c);">
|
|
|
|
+ <div v-if="!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;">
|
|
|
|
+ {{redoBtnMsg}}
|
|
|
|
+ </div>
|
|
|
|
+ <button ng-show="redoBtnShow" type="button" class="btn" ng-disabled="redoBtnDisabled" ng-click="startFaceVerify()">重试</button>
|
|
|
|
+ </div>
|
|
|
|
+ <iframe ng-show="showIframe" allow="camera *" allowusermedia id="myFrame" scrolling="no" width="100%" height="620px" frameborder="0"></iframe>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import {
|
|
|
|
+ FACEID_LINENESS_URL,
|
|
|
|
+ VUE_APP_WK_SERVER_SOCKET
|
|
|
|
+} from "@/constants/constants.js";
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ name: "FaceId",
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ showIframe: false,
|
|
|
|
+ redoBtnShow: false,
|
|
|
|
+ timeCount: 60,
|
|
|
|
+ redoBtnMsg: ""
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ mounted() {
|
|
|
|
+ this.startFaceVerify();
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ showRedo(redoMsg) {
|
|
|
|
+ this.showIframe = false;
|
|
|
|
+ this.redoBtnDisabled = false;
|
|
|
|
+ this.redoBtnShow = true;
|
|
|
|
+ if (redoMsg) {
|
|
|
|
+ this.redoBtnMsg = redoMsg;
|
|
|
|
+ } else {
|
|
|
|
+ this.redoBtnMsg = "系统繁忙,请手动点击重试";
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ updateFaceVerify(errorMsg, redoMsg) {
|
|
|
|
+ this.showRedo(redoMsg);
|
|
|
|
+ this.$http.get(
|
|
|
|
+ "/api/face_verify/updateFaceVerify/" +
|
|
|
|
+ this.$route.params.examRecordDataId,
|
|
|
|
+ { params: { errorMsg: errorMsg } }
|
|
|
|
+ );
|
|
|
|
+ },
|
|
|
|
+ checkIframeOnload() {
|
|
|
|
+ var iframe = document.getElementById("myFrame");
|
|
|
|
+ if (!iframe) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ var app = iframe.contentWindow.document.getElementById("app");
|
|
|
|
+ if (app) {
|
|
|
|
+ return "success";
|
|
|
|
+ } else {
|
|
|
|
+ var preLabel = iframe.contentWindow.document.getElementsByTagName(
|
|
|
|
+ "pre"
|
|
|
|
+ )[0];
|
|
|
|
+ if (
|
|
|
|
+ preLabel &&
|
|
|
|
+ preLabel.innerText &&
|
|
|
|
+ preLabel.innerText.indexOf("error_message") > -1
|
|
|
|
+ ) {
|
|
|
|
+ return preLabel.innerText;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ },
|
|
|
|
+ iframeLoadSuccess() {
|
|
|
|
+ try {
|
|
|
|
+ var iframe = document.getElementById("myFrame");
|
|
|
|
+ var app = iframe.contentWindow.document.getElementById("app");
|
|
|
|
+ app.querySelector(".footer").remove();
|
|
|
|
+ } catch (err) {
|
|
|
|
+ console.error(err);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const examRecordId = this.$route.params.examRecordDataId;
|
|
|
|
+
|
|
|
|
+ this.timeCount = 60; //人脸检测倒计时60秒
|
|
|
|
+ setInterval(() => {
|
|
|
|
+ --this.timeCount;
|
|
|
|
+ }, 1000);
|
|
|
|
+
|
|
|
|
+ //定时事件,如果1分钟内未完成人脸检测,执行内部程序
|
|
|
|
+ var faceIdTime = setTimeout(() => {
|
|
|
|
+ this.$Modal.remove();
|
|
|
|
+ ws.close();
|
|
|
|
+ var that = this;
|
|
|
|
+ this.$http
|
|
|
|
+ .get(
|
|
|
|
+ "/api/ecs_oe_student/examFaceLivenessVerify/faceLivenessVerifyTimeOut/" +
|
|
|
|
+ examRecordId
|
|
|
|
+ )
|
|
|
|
+ .then(function success(response) {
|
|
|
|
+ if (response.status == 200) {
|
|
|
|
+ var receivedMsg = response.data;
|
|
|
|
+ that.faceTestEnd(receivedMsg);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }, 60000); //60000
|
|
|
|
+ /**
|
|
|
|
+ * 人脸检测结果返回后台处理
|
|
|
|
+ */
|
|
|
|
+ this.faceTestEndHandle = result => {
|
|
|
|
+ this.$http
|
|
|
|
+ .get(
|
|
|
|
+ "/api/ecs_oe_student/examFaceLivenessVerify/faceLivenessVerifyEnd/" +
|
|
|
|
+ examRecordId +
|
|
|
|
+ "?result=" +
|
|
|
|
+ result
|
|
|
|
+ )
|
|
|
|
+ .then(() => {
|
|
|
|
+ if (result != "SUCCESS") {
|
|
|
|
+ this.$router.push("/login");
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * 人脸检测结束
|
|
|
|
+ */
|
|
|
|
+ this.faceTestEnd = receivedMsg => {
|
|
|
|
+ if (receivedMsg.verifyCount == 1) {
|
|
|
|
+ if (
|
|
|
|
+ receivedMsg.verifyResult == "VERIFY_FAILED" ||
|
|
|
|
+ receivedMsg.verifyResult == "TIME_OUT"
|
|
|
|
+ ) {
|
|
|
|
+ this.$Message.info("第一次人脸检测失败,系统退出,请重新登录", {
|
|
|
|
+ time: 5000
|
|
|
|
+ });
|
|
|
|
+ this.$router.push("/login");
|
|
|
|
+ } else if (receivedMsg.verifyResult == "NOT_ONESELF") {
|
|
|
|
+ this.$Message.info("人脸检测不合格,结束考试", { time: 5000 });
|
|
|
|
+ this.faceTestEndHandle("FAILED");
|
|
|
|
+ } else if (receivedMsg.verifyResult == "VERIFY_SUCCESS") {
|
|
|
|
+ this.$Message.info("人脸检测成功,请继续完成考试", { time: 5000 });
|
|
|
|
+ this.faceTestEndHandle("SUCCESS");
|
|
|
|
+ }
|
|
|
|
+ } else if (receivedMsg.verifyCount >= 2) {
|
|
|
|
+ if (receivedMsg.verifyResult == "VERIFY_SUCCESS") {
|
|
|
|
+ this.$Message.info("人脸检测成功,请继续完成考试", { time: 5000 });
|
|
|
|
+ this.faceTestEndHandle("SUCCESS");
|
|
|
|
+ } else {
|
|
|
|
+ this.$Message.info("人脸检测不合格,结束考试", { time: 5000 });
|
|
|
|
+ this.faceTestEndHandle("FAILED");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // open websocket
|
|
|
|
+ var ws = new WebSocket(VUE_APP_WK_SERVER_SOCKET + examRecordId);
|
|
|
|
+ ws.onopen = function() {
|
|
|
|
+ console.log("websocket已连接");
|
|
|
|
+ };
|
|
|
|
+ ws.onmessage = response => {
|
|
|
|
+ if (response.data.indexOf("verifyResult") > -1) {
|
|
|
|
+ var receivedMsg = JSON.parse(response.data);
|
|
|
|
+ clearTimeout(faceIdTime);
|
|
|
|
+ this.$router.push("/login");
|
|
|
|
+ ws.close();
|
|
|
|
+ this.faceTestEnd(receivedMsg);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ ws.onclose = function() {
|
|
|
|
+ console.log("websocket连接已关闭...");
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ async startFaceVerify() {
|
|
|
|
+ this.redoBtnDisabled = true;
|
|
|
|
+ this.redoBtnMsg = "正在进入人脸检测...";
|
|
|
|
+ const examRecordId = this.$route.params.examRecordDataId;
|
|
|
|
+ const response = await this.$http.get(
|
|
|
|
+ "/api/ecs_oe_student/examFaceLivenessVerify/getFaceLivenessVerifyToken/" +
|
|
|
|
+ examRecordId
|
|
|
|
+ );
|
|
|
|
+ if (!response.data || !response.data.token) {
|
|
|
|
+ this.updateFaceVerify("TOKEN_EXPIRED", null);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.showIframe = true;
|
|
|
|
+ var iframe = document.getElementById("myFrame");
|
|
|
|
+ try {
|
|
|
|
+ iframe.src = FACEID_LINENESS_URL + response.data.token;
|
|
|
|
+ } catch (err) {
|
|
|
|
+ console.error(err);
|
|
|
|
+ }
|
|
|
|
+ var index = 0;
|
|
|
|
+ var iframeLoadTime = setInterval(() => {
|
|
|
|
+ var iframeLoadMsg = this.checkIframeOnload();
|
|
|
|
+ if (!iframeLoadMsg) {
|
|
|
|
+ index++;
|
|
|
|
+ if (index == 20) {
|
|
|
|
+ //检测达到20次
|
|
|
|
+ clearInterval(iframeLoadTime);
|
|
|
|
+ this.showRedo("网络异常,请手动点击重试");
|
|
|
|
+ }
|
|
|
|
+ } else if (iframeLoadMsg.indexOf("error_message") > -1) {
|
|
|
|
+ clearInterval(iframeLoadTime);
|
|
|
|
+ this.updateFaceVerify(iframeLoadMsg, null);
|
|
|
|
+ } else if (iframeLoadMsg == "success") {
|
|
|
|
+ clearInterval(iframeLoadTime);
|
|
|
|
+ this.iframeLoadSuccess();
|
|
|
|
+ }
|
|
|
|
+ }, 500);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+</script>
|