|
@@ -72,6 +72,7 @@ import FaceRecognition from "../../../components/FaceRecognition/FaceRecognition
|
|
|
import { openWS, closeWsWithoutReconnect } from "./ws.js";
|
|
|
import { createNamespacedHelpers } from "vuex";
|
|
|
const { mapState, mapMutations } = createNamespacedHelpers("examingHomeModule");
|
|
|
+import { DOMAINS_CAN_UPLOAD_PHOTOS } from "@/constants/constants";
|
|
|
|
|
|
export default {
|
|
|
name: "ExamingHome",
|
|
@@ -224,15 +225,118 @@ export default {
|
|
|
// // }, this.$route.query.faceVerifyMinute * 60 * 1000); // 定时做活体检测
|
|
|
// }, 5 * 1000); // 定时做活体检测
|
|
|
|
|
|
+ let faceEnable;
|
|
|
+ try {
|
|
|
+ faceEnable = await this.$http.get(
|
|
|
+ "/api/ecs_exam_work/exam/examOrgPropertyFromCache4StudentSession/" +
|
|
|
+ this.$route.params.examId +
|
|
|
+ `/IS_FACE_ENABLE`
|
|
|
+ );
|
|
|
+ } catch (error) {
|
|
|
+ this.$Message.error({
|
|
|
+ content: "获取人脸检测设置失败",
|
|
|
+ duration: 15,
|
|
|
+ closable: true,
|
|
|
+ });
|
|
|
+ this.logout("?LogoutReason=获取人脸检测设置失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (
|
|
|
+ faceEnable.data.IS_FACE_ENABLE &&
|
|
|
+ JSON.parse(faceEnable.data.IS_FACE_ENABLE)
|
|
|
+ ) {
|
|
|
+ this.faceEnable = true;
|
|
|
+
|
|
|
+ // setTimeout(() => {
|
|
|
+ // this.serverLog("debug/S-002001", "进入考试后60秒内抓拍");
|
|
|
+ // this.toggleSnapNow(); // 开启抓拍才在进入考试时抓拍一张
|
|
|
+ // }, 60 * 1000); // 60内秒钟后抓拍
|
|
|
+
|
|
|
+ let initSnapshotTrialTimes = 0;
|
|
|
+ this.initSnapInterval = setInterval(() => {
|
|
|
+ const video = document.getElementById("video");
|
|
|
+ const videoStartFailed =
|
|
|
+ !video || video.readyState !== 4 || !video.srcObject.active;
|
|
|
+ if (videoStartFailed && initSnapshotTrialTimes < 5) {
|
|
|
+ initSnapshotTrialTimes++;
|
|
|
+ } else {
|
|
|
+ // 超过6次后,强行抓拍,如果抓拍不成功,则会因抓拍不成功而退出。
|
|
|
+ clearInterval(this.initSnapInterval);
|
|
|
+
|
|
|
+ if (videoStartFailed) {
|
|
|
+ this.$Message.error({
|
|
|
+ content: "摄像头没有正常启用",
|
|
|
+ duration: 5,
|
|
|
+ closable: true,
|
|
|
+ });
|
|
|
+ window._hmt.push([
|
|
|
+ "_trackEvent",
|
|
|
+ "摄像头框",
|
|
|
+ "摄像头状态",
|
|
|
+ "摄像头没有正常启用-进入考试抓拍",
|
|
|
+ ]);
|
|
|
+
|
|
|
+ this.logout("?LogoutReason=" + "摄像头没有正常启用-退出");
|
|
|
+ } else {
|
|
|
+ this.serverLog(
|
|
|
+ "debug/S-002001",
|
|
|
+ "进入考试后60秒内抓拍-" +
|
|
|
+ `(第${initSnapshotTrialTimes + 1}次尝试)`
|
|
|
+ );
|
|
|
+ this.toggleSnapNow(); // 开启抓拍才在进入考试时抓拍一张
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, 10 * 1000);
|
|
|
+
|
|
|
+ // let initSnapshotTrialTimes = 0;
|
|
|
+ // const initSnapshot = setTimeout(() => {
|
|
|
+ // if (this.exam || initSnapshotTrialTimes < 6) {
|
|
|
+ // this.serverLog("debug/S-002001", "进入考试后60秒内抓拍");
|
|
|
+ // this.toggleSnapNow(); // 开启抓拍才在进入考试时抓拍一张
|
|
|
+ // } else {
|
|
|
+ // setTimeout(() => initSnapshot(), 5 * 1000);
|
|
|
+ // }
|
|
|
+ // }, 5 * 1000); // 60内秒钟后抓拍
|
|
|
+
|
|
|
+ try {
|
|
|
+ const snapshotInterval = await this.$http.get(
|
|
|
+ "/api/ecs_exam_work/exam/examOrgPropertyFromCache4StudentSession/" +
|
|
|
+ this.$route.params.examId +
|
|
|
+ `/SNAPSHOT_INTERVAL`
|
|
|
+ );
|
|
|
+ if (snapshotInterval.data) {
|
|
|
+ // 考务设置抓拍间隔
|
|
|
+ this.snapInterval = setInterval(() => {
|
|
|
+ this.serverLog(
|
|
|
+ "debug/S-002001",
|
|
|
+ "根据抓拍间隔抓拍:抓拍间隔=" +
|
|
|
+ snapshotInterval.data.SNAPSHOT_INTERVAL +
|
|
|
+ "分钟"
|
|
|
+ );
|
|
|
+ this.toggleSnapNow();
|
|
|
+ }, snapshotInterval.data.SNAPSHOT_INTERVAL * 60 * 1000);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ this.$Message.error({
|
|
|
+ content: "获取人脸抓拍间隔设置失败",
|
|
|
+ duration: 15,
|
|
|
+ closable: true,
|
|
|
+ });
|
|
|
+ this.logout("?LogoutReason=获取人脸抓拍间隔设置失败");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
try {
|
|
|
await this.initData();
|
|
|
} catch (error) {
|
|
|
this.$Message.error({
|
|
|
- content: "获取考试和试卷信息失败,退出登录",
|
|
|
+ content: "获取试卷信息失败,退出登录",
|
|
|
duration: 15,
|
|
|
closable: true,
|
|
|
});
|
|
|
- this.logout("?LogoutReason=获取考试和试卷信息失败");
|
|
|
+ this.logout("?LogoutReason=获取试卷信息失败");
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -325,22 +429,10 @@ export default {
|
|
|
]),
|
|
|
async initData() {
|
|
|
const [
|
|
|
- orgPropData,
|
|
|
- examPropData,
|
|
|
examData,
|
|
|
paperStructData,
|
|
|
examQuestionListData,
|
|
|
] = await Promise.all([
|
|
|
- this.$http.get(
|
|
|
- "/api/ecs_core/org/property/" +
|
|
|
- this.$store.state.user.rootOrgId +
|
|
|
- `/WEIXIN_ANSWER_ENABLED`
|
|
|
- ),
|
|
|
- this.$http.get(
|
|
|
- "/api/ecs_exam_work/exam/examOrgPropertyFromCache4StudentSession/" +
|
|
|
- this.$route.params.examId +
|
|
|
- `/IS_FACE_ENABLE,SNAPSHOT_INTERVAL,PRACTICE_TYPE,FREEZE_TIME,WEIXIN_ANSWER_ENABLED`
|
|
|
- ),
|
|
|
this.$http.get("/api/ecs_exam_work/exam/" + this.$route.params.examId),
|
|
|
this.$http.get(
|
|
|
"/api/ecs_oe_student/examRecordPaperStruct/getExamRecordPaperStruct?examRecordDataId=" +
|
|
@@ -348,113 +440,46 @@ export default {
|
|
|
),
|
|
|
this.$http.get("/api/ecs_oe_student/examQuestion/findExamQuestionList"),
|
|
|
]);
|
|
|
- // console.log(orgPropData, examPropData);
|
|
|
-
|
|
|
- const [orgProp, examProp, exam, paperStruct] = [
|
|
|
- orgPropData.data,
|
|
|
- examPropData.data,
|
|
|
- examData.data,
|
|
|
- paperStructData.data,
|
|
|
- ];
|
|
|
+ const [exam, paperStruct] = [examData.data, paperStructData.data];
|
|
|
|
|
|
let examQuestionList = examQuestionListData.data;
|
|
|
|
|
|
if (
|
|
|
- orgProp === undefined ||
|
|
|
- examProp === undefined ||
|
|
|
exam === undefined ||
|
|
|
paperStruct === undefined ||
|
|
|
examQuestionListData === undefined
|
|
|
) {
|
|
|
this.$Message.error({
|
|
|
- content: "获取考试和试卷信息失败",
|
|
|
+ content: "获取试卷信息失败",
|
|
|
duration: 15,
|
|
|
closable: true,
|
|
|
});
|
|
|
- this.logout("?LogoutReason=获取考试和试卷信息失败");
|
|
|
+ this.logout("?LogoutReason=获取试卷信息失败");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (orgProp && examProp.WEIXIN_ANSWER_ENABLED === "true") {
|
|
|
- exam.WEIXIN_ANSWER_ENABLED = true;
|
|
|
- } else {
|
|
|
- exam.WEIXIN_ANSWER_ENABLED = false;
|
|
|
- }
|
|
|
-
|
|
|
- if (examProp.IS_FACE_ENABLE && JSON.parse(examProp.IS_FACE_ENABLE)) {
|
|
|
- this.faceEnable = true;
|
|
|
-
|
|
|
- // setTimeout(() => {
|
|
|
- // this.serverLog("debug/S-002001", "进入考试后60秒内抓拍");
|
|
|
- // this.toggleSnapNow(); // 开启抓拍才在进入考试时抓拍一张
|
|
|
- // }, 60 * 1000); // 60内秒钟后抓拍
|
|
|
-
|
|
|
- let initSnapshotTrialTimes = 0;
|
|
|
- this.initSnapInterval = setInterval(() => {
|
|
|
- const video = document.getElementById("video");
|
|
|
- const videoStartFailed =
|
|
|
- !video || video.readyState !== 4 || !video.srcObject.active;
|
|
|
- if (videoStartFailed && initSnapshotTrialTimes < 5) {
|
|
|
- initSnapshotTrialTimes++;
|
|
|
- } else {
|
|
|
- // 超过6次后,强行抓拍,如果抓拍不成功,则会因抓拍不成功而退出。
|
|
|
- clearInterval(this.initSnapInterval);
|
|
|
-
|
|
|
- if (videoStartFailed) {
|
|
|
- this.$Message.error({
|
|
|
- content: "摄像头没有正常启用",
|
|
|
- duration: 5,
|
|
|
- closable: true,
|
|
|
- });
|
|
|
- window._hmt.push([
|
|
|
- "_trackEvent",
|
|
|
- "摄像头框",
|
|
|
- "摄像头状态",
|
|
|
- "摄像头没有正常启用-进入考试抓拍",
|
|
|
- ]);
|
|
|
-
|
|
|
- this.logout("?LogoutReason=" + "摄像头没有正常启用-退出");
|
|
|
- } else {
|
|
|
- this.serverLog(
|
|
|
- "debug/S-002001",
|
|
|
- "进入考试后60秒内抓拍-" +
|
|
|
- `(第${initSnapshotTrialTimes + 1}次尝试)`
|
|
|
- );
|
|
|
- this.toggleSnapNow(); // 开启抓拍才在进入考试时抓拍一张
|
|
|
- }
|
|
|
- }
|
|
|
- }, 10 * 1000);
|
|
|
-
|
|
|
- // let initSnapshotTrialTimes = 0;
|
|
|
- // const initSnapshot = setTimeout(() => {
|
|
|
- // if (this.exam || initSnapshotTrialTimes < 6) {
|
|
|
- // this.serverLog("debug/S-002001", "进入考试后60秒内抓拍");
|
|
|
- // this.toggleSnapNow(); // 开启抓拍才在进入考试时抓拍一张
|
|
|
- // } else {
|
|
|
- // setTimeout(() => initSnapshot(), 5 * 1000);
|
|
|
- // }
|
|
|
- // }, 5 * 1000); // 60内秒钟后抓拍
|
|
|
-
|
|
|
- if (examProp.SNAPSHOT_INTERVAL) {
|
|
|
- const SNAPSHOT_INTERVAL = JSON.parse(examProp.SNAPSHOT_INTERVAL);
|
|
|
- // 考务设置抓拍间隔
|
|
|
- this.snapInterval = setInterval(() => {
|
|
|
- // this.serverLog(
|
|
|
- // "debug/S-002001",
|
|
|
- // "根据抓拍间隔抓拍:抓拍间隔=" + SNAPSHOT_INTERVAL + "分钟"
|
|
|
- // );
|
|
|
- this.toggleSnapNow();
|
|
|
- }, SNAPSHOT_INTERVAL * 60 * 1000);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
if (exam.examType === "PRACTICE") {
|
|
|
- this.practiceType = examProp.PRACTICE_TYPE; // IN_PRACTICE NO_ANSWER
|
|
|
- exam.practiceType = examProp.PRACTICE_TYPE;
|
|
|
+ const practiceType = (await this.$http.get(
|
|
|
+ "/api/ecs_exam_work/exam/examOrgPropertyFromCache4StudentSession/" +
|
|
|
+ this.$route.params.examId +
|
|
|
+ `/PRACTICE_TYPE`
|
|
|
+ )).data;
|
|
|
+ this.practiceType = practiceType.PRACTICE_TYPE; // IN_PRACTICE NO_ANSWER
|
|
|
+ exam.practiceType = practiceType.PRACTICE_TYPE;
|
|
|
}
|
|
|
|
|
|
- exam.freezeTime =
|
|
|
- examProp.FREEZE_TIME && JSON.parse(examProp.FREEZE_TIME);
|
|
|
+ try {
|
|
|
+ let freezeTimeData = await this.$http.get(
|
|
|
+ "/api/ecs_exam_work/exam/examOrgPropertyFromCache4StudentSession/" +
|
|
|
+ this.$route.params.examId +
|
|
|
+ `/FREEZE_TIME`
|
|
|
+ );
|
|
|
+ exam.freezeTime =
|
|
|
+ freezeTimeData.data.FREEZE_TIME &&
|
|
|
+ JSON.parse(freezeTimeData.data.FREEZE_TIME);
|
|
|
+ } catch (error) {
|
|
|
+ console.log("获取考试冻结时间失败--忽略");
|
|
|
+ }
|
|
|
|
|
|
// parentQuestionBody
|
|
|
// questionUnitWrapperList
|
|
@@ -526,7 +551,9 @@ export default {
|
|
|
// console.log(examQuestionList);
|
|
|
// console.log(examQuestionList.find(v => v.answerType === "SINGLE_AUDIO"));
|
|
|
|
|
|
- const shouldOpenWS = exam.WEIXIN_ANSWER_ENABLED;
|
|
|
+ const shouldOpenWS =
|
|
|
+ examQuestionList.find(v => v.answerType === "SINGLE_AUDIO") ||
|
|
|
+ DOMAINS_CAN_UPLOAD_PHOTOS.includes(this.$store.state.user.schoolDomain);
|
|
|
|
|
|
if (shouldOpenWS) {
|
|
|
// console.log("have single");
|