|
@@ -1,25 +1,32 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
+ <div>{{
|
|
|
+ countdownNumFormat
|
|
|
+ }}</div>
|
|
|
<div><el-avatar :src="faceCheckStu.logo_url || faceCheckStu.face_pic" @click="getChooseStudent" /></div>
|
|
|
<div>{{ faceCheckStu.name }}</div>
|
|
|
<div>成绩:{{ currentResultObj.count }} {{ unit }}</div>
|
|
|
<div>得分:{{ currentResultObj.score }}</div>
|
|
|
- <div @click="getProcess">走一套流程({{ examState == 3 ? "创建测试" : examState == 40 ? "开始人脸识别" : examState == 41 ? "停止人脸识别"
|
|
|
+ <div>中断/犯规:{{ currentResultObj.back_num }}</div>
|
|
|
+ <div v-if="backReason.length">
|
|
|
+ <div>违规项</div>
|
|
|
+ <div v-for="(item, index) in backReason" :key="index">{{ item }}</div>
|
|
|
+ </div>
|
|
|
+ <div>当前状态:({{ examState == 3 ? "创建测试" : examState == 40 ? "开始识别" : examState == 41 ? "停止人脸识别"
|
|
|
:
|
|
|
examState ==
|
|
|
43 ? "开始测试" : examState == 42 ? "正在测试" : "请初始化" }})</div>
|
|
|
- <div @click="getOpenOneTestAndStartFace" v-if="examState == 3 || examState == 40">1、开始人脸识别</div>
|
|
|
-
|
|
|
- <div @click="getChooseStudent">2、选择学生</div>
|
|
|
- <div @click="getStopFace" v-if="examState == 41">3、停止人脸识别</div>
|
|
|
-
|
|
|
- <div @click="getStartOneTest" v-if="examState == 43">4、开始测试</div>
|
|
|
-
|
|
|
- <div @click="getRetest" v-if="examState == 3 || examState == 42">再测一次</div>
|
|
|
-
|
|
|
+ <!-- <div @click="getProcess">走一套流程</div> -->
|
|
|
|
|
|
+ <div v-if="needStart">
|
|
|
+ <div @click="getOpenOneTestAndStartFace" v-if="examState == 3 || examState == 40">1、开始识别</div>
|
|
|
+ <div @click="getStopFace" v-if="examState == 41">3、停止人脸识别</div>
|
|
|
+ <div @click="getStartOneTest" v-if="examState == 43">5、开始测试</div>
|
|
|
+ </div>
|
|
|
+ <div @click="getChooseStudent" v-if="examState == 41 || (examState == 43 && !faceCheckStu.student_id)">2、选择学生</div>
|
|
|
+ <div @click="getRetestFace" v-if="examState == 43 || examState == 42">4、重新识别</div>
|
|
|
+ <div @click="getRetest" v-if="(examState == 3 && faceCheckStu.student_id) || examState == 42">再测一次</div>
|
|
|
<div @click="confirmExit">退出</div>
|
|
|
-
|
|
|
<ChooseStudent ref="chooseStudentRef" @back="backStudent" />
|
|
|
</div>
|
|
|
</template>
|
|
@@ -35,16 +42,21 @@ const data = reactive<any>({
|
|
|
timerManager: {},//计时器管理
|
|
|
parameter: {},//参数
|
|
|
testTime: 60,//时长
|
|
|
+ countdownNum: 0,//计时
|
|
|
userInfo: {},//用户信息
|
|
|
examState: 0,//当前状态
|
|
|
- result_id: null,//测试ID
|
|
|
+ resultId: null,//测试ID
|
|
|
currentResultObj: {},//成绩
|
|
|
- unit: "",//单位
|
|
|
faceCheckStu: {},//人脸信息
|
|
|
+ unit: "",//单位
|
|
|
+ backReason: [],//犯规项
|
|
|
+ needStart: false,//是否需要按钮
|
|
|
});
|
|
|
-const { timerManager, parameter, testTime, userInfo, examState, result_id, currentResultObj, unit, faceCheckStu } = toRefs(data);
|
|
|
+const { timerManager, parameter, testTime, countdownNum, userInfo, examState, resultId, currentResultObj, unit, faceCheckStu, backReason, needStart } = toRefs(data);
|
|
|
|
|
|
-//接收消息
|
|
|
+/**
|
|
|
+ * 接收消息
|
|
|
+*/
|
|
|
const getMessage = (e: any) => {
|
|
|
console.log("WS响应:", e)
|
|
|
//实时状态
|
|
@@ -53,6 +65,7 @@ const getMessage = (e: any) => {
|
|
|
}
|
|
|
//工作站状态
|
|
|
if (e.cmd === 'init_result') {
|
|
|
+
|
|
|
}
|
|
|
//测试违规
|
|
|
if (e.cmd === 'warning_result') {
|
|
@@ -64,11 +77,11 @@ const getMessage = (e: any) => {
|
|
|
}
|
|
|
//错误提示
|
|
|
if (e.cmd === 'info_result') {
|
|
|
-
|
|
|
+ proxy?.$modal.msgError(e.data.message);
|
|
|
}
|
|
|
//错误提示
|
|
|
if (e.cmd === 'error_result') {
|
|
|
-
|
|
|
+ proxy?.$modal.msgError(e.data.message);
|
|
|
}
|
|
|
//测试中违规提示
|
|
|
if (e.cmd === 'warning_notify') {
|
|
@@ -81,35 +94,48 @@ const getMessage = (e: any) => {
|
|
|
//状态变更
|
|
|
if (e.cmd === 'set_exam_state') {
|
|
|
examState.value = e.data;
|
|
|
+ if (e.data === 3) {
|
|
|
+ //停止计时
|
|
|
+ getStopCountdown();
|
|
|
+ //不需要按钮的自动进入下一步
|
|
|
+ if (needStart.value == false) {
|
|
|
+ setTimeout(() => {
|
|
|
+ //再加一个判断以免和再测一次冲突
|
|
|
+ if (examState.value == 3) {
|
|
|
+ getOpenOneTestAndStartFace();
|
|
|
+ }
|
|
|
+ }, 6000)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (e.data === 40) {
|
|
|
+ cleanData();
|
|
|
+ }
|
|
|
+ if (e.data == 41) {
|
|
|
+
|
|
|
+ }
|
|
|
+ if (e.data == 43) {
|
|
|
+
|
|
|
+ }
|
|
|
+ if (e.data == 42) {
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
//新建测试后返回信息,获取result_id
|
|
|
if (e.cmd === 'open_one_test_ack') {
|
|
|
- currentResultObj.value = {};
|
|
|
- result_id.value = e.data.result_id
|
|
|
+ resultId.value = e.data.result_id;
|
|
|
}
|
|
|
//人脸识别状态
|
|
|
if (e.cmd === 'face_check_result') {
|
|
|
faceCheckStu.value = e.data[0] || e.data;
|
|
|
+ getStopFace();
|
|
|
}
|
|
|
//测试结束结果
|
|
|
if (e.cmd === 'oneresult') {
|
|
|
if (e.data.length) {
|
|
|
let data = e.data[0];
|
|
|
console.log("成绩", data);
|
|
|
- let dic: any = dataDictionary;
|
|
|
- let type = parameter.value.project;
|
|
|
- let count =
|
|
|
- data?.[dic.typeResultKey[type]]?.toFixed(0);
|
|
|
- if (["trijump", "solidball", "shotput", "longjump"].includes(type)) {
|
|
|
- count =
|
|
|
- data?.[dic.typeResultKey[type]]?.toFixed(2);
|
|
|
- count = Math.round(count) / 100;
|
|
|
- }
|
|
|
- data.count = count || "0";
|
|
|
- data.score = data.score || "0";
|
|
|
- currentResultObj.value = data;
|
|
|
+ getAchievement(data)
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
//结果生成完成(视频图片)
|
|
|
if (e.cmd === 'static_urls_finished') {
|
|
@@ -119,26 +145,27 @@ const getMessage = (e: any) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-/**
|
|
|
- * 正常流程
|
|
|
-*/
|
|
|
-const getProcess = () => {
|
|
|
- if (examState.value == 3) {
|
|
|
- openOneTest();
|
|
|
- }
|
|
|
- if (examState.value == 40) {
|
|
|
- startFace();
|
|
|
- }
|
|
|
- if (examState.value == 41) {
|
|
|
- getStopFace();
|
|
|
- }
|
|
|
- if (examState.value == 43) {
|
|
|
- startOneTest();
|
|
|
- }
|
|
|
-};
|
|
|
+
|
|
|
+// /**
|
|
|
+// * 正常流程
|
|
|
+// */
|
|
|
+// const getProcess = () => {
|
|
|
+// if (examState.value == 3) {
|
|
|
+// openOneTest();
|
|
|
+// }
|
|
|
+// if (examState.value == 40) {
|
|
|
+// startFace();
|
|
|
+// }
|
|
|
+// if (examState.value == 41) {
|
|
|
+// getStopFace();
|
|
|
+// }
|
|
|
+// if (examState.value == 43) {
|
|
|
+// getStartOneTest();
|
|
|
+// }
|
|
|
+// };
|
|
|
|
|
|
/**
|
|
|
- * 开始人脸识别
|
|
|
+ * 开始识别
|
|
|
*/
|
|
|
const getOpenOneTestAndStartFace = () => {
|
|
|
if (examState.value == 3) {
|
|
@@ -158,24 +185,59 @@ const getOpenOneTestAndStartFace = () => {
|
|
|
*/
|
|
|
const getStopFace = () => {
|
|
|
stopFace();
|
|
|
+ if (faceCheckStu.value.student_id) {
|
|
|
+ getFaceConfirmOnly();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 确定人脸信息
|
|
|
+*/
|
|
|
+const getFaceConfirmOnly = () => {
|
|
|
faceConfirmOnly({
|
|
|
- result_id: result_id.value,
|
|
|
+ result_id: resultId.value,
|
|
|
student_id: faceCheckStu.value.student_id,
|
|
|
gender: faceCheckStu.value.gender
|
|
|
+ }, () => {
|
|
|
+ //不需要按钮的自动进入下一步
|
|
|
+ if (needStart.value == false) {
|
|
|
+ getStartOneTest();
|
|
|
+ }
|
|
|
});
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * 停止人脸识别
|
|
|
+ * 重新识别
|
|
|
+*/
|
|
|
+const getRetestFace = () => {
|
|
|
+ if (needStart.value == false) {
|
|
|
+ //不需要手动操作的项目重新识别直接返回3
|
|
|
+ closeOneTest();
|
|
|
+ } else {
|
|
|
+ //需要手动操作的项目重新识别返回41
|
|
|
+ startFace();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 开始测试
|
|
|
*/
|
|
|
const getStartOneTest = () => {
|
|
|
- startOneTest()
|
|
|
+ if (!faceCheckStu.value.student_id) {
|
|
|
+ proxy?.$modal.msgError("请选择人员!");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ startOneTest(() => {
|
|
|
+ getCountdown();
|
|
|
+ })
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* 再测一次
|
|
|
*/
|
|
|
const getRetest = () => {
|
|
|
+ //预存测试人员
|
|
|
+ let student = JSON.parse(JSON.stringify(faceCheckStu.value));
|
|
|
//测试中
|
|
|
if (examState.value == 42) {
|
|
|
finishOneTest();
|
|
@@ -196,6 +258,9 @@ const getRetest = () => {
|
|
|
getStopFace();
|
|
|
}
|
|
|
if (examState.value == 43) {
|
|
|
+ faceCheckStu.value = student;
|
|
|
+ getFaceConfirmOnly();
|
|
|
+ //停止自动执行
|
|
|
clearInterval(timerManager.value.retest)
|
|
|
timerManager.value.retest = null;
|
|
|
}
|
|
@@ -209,7 +274,6 @@ const confirmExit = () => {
|
|
|
proxy?.$modal.confirm("确定退出吗?").then(() => {
|
|
|
getExit();
|
|
|
}).finally(() => {
|
|
|
-
|
|
|
});
|
|
|
};
|
|
|
|
|
@@ -238,30 +302,164 @@ const getClearTimer = () => {
|
|
|
* 选择学生
|
|
|
*/
|
|
|
const getChooseStudent = () => {
|
|
|
- if (examState.value != 41) {
|
|
|
- return false;
|
|
|
+ if (examState.value == 41 || (examState.value == 43 && !faceCheckStu.value.student_id)) {
|
|
|
+ chooseStudentRef.value.open();
|
|
|
}
|
|
|
- chooseStudentRef.value.open();
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * 被选学生
|
|
|
+ * 返回被选学生
|
|
|
*/
|
|
|
const backStudent = (data: any) => {
|
|
|
faceCheckStu.value = data;
|
|
|
+ getStopFace();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 返回被选学生
|
|
|
+*/
|
|
|
+const cleanData = () => {
|
|
|
+ countdownNum.value = testTime.value;
|
|
|
+ faceCheckStu.value = {};
|
|
|
+ currentResultObj.value = {};
|
|
|
+ backReason.value = [];
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * 时间转换
|
|
|
+*/
|
|
|
+const countdownNumFormat = computed(() => {
|
|
|
+ return proxy?.$utils.timeFormat(countdownNum.value);
|
|
|
+});
|
|
|
+
|
|
|
+/**
|
|
|
+ * 计时
|
|
|
+*/
|
|
|
+const getCountdown = () => {
|
|
|
+ timerManager.value.countdownTimer = setInterval(() => {
|
|
|
+ if (countdownNum.value <= 0) {
|
|
|
+ getStopCountdown();
|
|
|
+ } else {
|
|
|
+ countdownNum.value--;
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * 停止计时
|
|
|
+*/
|
|
|
+const getStopCountdown = () => {
|
|
|
+ clearInterval(timerManager.value.countdownTimer);
|
|
|
+ timerManager.value.countdownTimer = null;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 成绩
|
|
|
+*/
|
|
|
+const getAchievement = (data: any) => {
|
|
|
+ let dic: any = dataDictionary;
|
|
|
+ let type = parameter.value.project;
|
|
|
+ let count =
|
|
|
+ data?.[dic.typeResultKey[type]]?.toFixed(0);
|
|
|
+ if (["trijump", "solidball", "shotput", "longjump"].includes(type)) {
|
|
|
+ count =
|
|
|
+ data?.[dic.typeResultKey[type]]?.toFixed(2);
|
|
|
+ count = Math.round(count) / 100;
|
|
|
+ }
|
|
|
+ data.count = count || "0";
|
|
|
+ data.score = data.score || "0";
|
|
|
+ currentResultObj.value = data;
|
|
|
+ //违规处理
|
|
|
+ let arr = backReason.value;
|
|
|
+ if (["situp", "pullup", "sidepullup", "jumprope", "jumpingjack", "jump", "longjump", "verticaljump"]
|
|
|
+ .indexOf(type) > -1) {
|
|
|
+ if (["pullup", "situp", "jumprope", "jumpingjack"].indexOf(type) > -1) {
|
|
|
+ currentResultObj.value.back_num = data?.all_failed_num;
|
|
|
+ }
|
|
|
+ if (type === "sidepullup") {
|
|
|
+ currentResultObj.value.back_num = data?.["0"]?.hip_failed_num;
|
|
|
+ }
|
|
|
+ if (['jump', 'longjump', 'verticaljump'].includes(type)) {
|
|
|
+ if (data?.startline_check == 0) {
|
|
|
+ let txt = "踩线违规";
|
|
|
+ arr.push(txt)
|
|
|
+ }
|
|
|
+ if (data?.singleleg_jump_check == 0) {
|
|
|
+ let txt = "单脚跳违规";
|
|
|
+ arr.push(txt)
|
|
|
+ }
|
|
|
+ if (data?.outside_check == 0) {
|
|
|
+ let txt = "跳出测试区违规";
|
|
|
+ arr.push(txt)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ data?.elbow_check == false
|
|
|
+ ) {
|
|
|
+ let txt = "肘部违规";
|
|
|
+ arr.push(txt);
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ ["situp", "pullup"].indexOf(type) > -1 &&
|
|
|
+ data?.knee_check === false
|
|
|
+ ) {
|
|
|
+ let txt = "腿部违规";
|
|
|
+ if (!arr.includes(txt)) {
|
|
|
+ arr.push(txt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (["situp"].indexOf(type) > -1 && data?.hand_check === false) {
|
|
|
+ let txt = "手部违规";
|
|
|
+ if (!arr.includes(txt)) {
|
|
|
+ arr.push(txt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ ["pullup"].indexOf(type) > -1 &&
|
|
|
+ data?.["0"]?.elbow_check === false
|
|
|
+ ) {
|
|
|
+ let txt = "手部违规";
|
|
|
+ if (!arr.includes(txt)) {
|
|
|
+ arr.push(txt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (["situp"].indexOf(type) > -1 && data?.["0"]?.back_check === false) {
|
|
|
+ let txt = "背部违规";
|
|
|
+ if (!arr.includes(txt)) {
|
|
|
+ arr.push(txt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ ["sidepullup", "situp"].indexOf(type) > -1 &&
|
|
|
+ data?.["0"]?.hip_check === false
|
|
|
+ ) {
|
|
|
+ let txt = "臀部违规";
|
|
|
+ if (!arr.includes(txt)) {
|
|
|
+ arr.push(txt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ backReason.value = arr;
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
parameter.value = route.query;
|
|
|
- parameter.value.examId = `${parameter.value.project}_${parameter.value.area}`; //项目+区
|
|
|
+ let project = parameter.value.project;
|
|
|
+ let area = parameter.value.area;
|
|
|
+ parameter.value.examId = `${project}_${area}`; //项目+区
|
|
|
if (parameter.value.time) {
|
|
|
testTime.value = parameter.value.time
|
|
|
}
|
|
|
let myInfo: any = localStorage.getItem("userInfo");
|
|
|
userInfo.value = JSON.parse(myInfo);
|
|
|
let dic: any = dataDictionary;
|
|
|
- let type = parameter.value.project;
|
|
|
- unit.value = dic.unit[type]
|
|
|
+ unit.value = dic.unit[project];
|
|
|
+ //需要开始按钮的项目
|
|
|
+ if (["jumprope", "skiprope", "jumpingjack", "situp"].includes(project)) {
|
|
|
+ needStart.value = true;
|
|
|
+ }
|
|
|
//加载WS
|
|
|
initWs({ parameter: parameter.value, testTime: testTime.value }, (data: any) => {
|
|
|
getMessage(data);
|