|
@@ -1,23 +1,30 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
- <div @click="confirmExit">退出</div>
|
|
|
- <div style="text-align: center;">{{
|
|
|
- countdownNumFormat
|
|
|
- }}</div>
|
|
|
- <div style="display: flex; justify-content: space-between; margin-bottom: 40px;">
|
|
|
- <MultipleItem :ref="(el: any) => { multipleItemRef(el, index, item.area) }" v-for="(item, index) in testList"
|
|
|
- :query="parameter" :area="item.area" :key="index" @returnData="returnData" :examState="examState"
|
|
|
- :needStart="needStart" />
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- <div v-if="needStart">
|
|
|
- <div @click="getAgain" v-if="examState == 42 || showTestAgain">再测一次</div>
|
|
|
- <div @click="getOpenOneTestAndStartFace" v-if="examState < 41">1、开始识别</div>
|
|
|
- <div @click="getStopFace" v-if="examState == 41">2、停止人脸识别</div>
|
|
|
- <div @click="getStartOneTest" v-if="examState == 43">3、开始测试</div>
|
|
|
+ <Header @confirmExit="confirmExit"></Header>
|
|
|
+ <div class="main">
|
|
|
+ <transition :enter-active-class="proxy?.animate.dialog.enter" :leave-active-class="proxy?.animate.dialog.leave">
|
|
|
+ <div class="time" v-show="[42].includes(examState)">{{
|
|
|
+ time.countdownNum
|
|
|
+ }}</div>
|
|
|
+ </transition>
|
|
|
+
|
|
|
+ <div class="startBtn">{{ examState }} --- {{ time.ready }}</div>
|
|
|
+ <div class="box">
|
|
|
+ <MultipleItem :ref="(el: any) => { multipleItemRef(el, index, item.area) }" v-for="(item, index) in testList"
|
|
|
+ :query="parameter" :area="item.area" :key="index" :itemNumber="index + 1" @returnData="returnData"
|
|
|
+ :examState="examState" :needStart="needStart" />
|
|
|
</div>
|
|
|
- <div v-else>
|
|
|
- <div @click="getStartOneTest">3、开始测试</div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <div v-if="needStart">
|
|
|
+ <div @click="getAgain" v-if="examState == 42 || showTestAgain">再测一次</div>
|
|
|
+ <div @click="getOpenOneTestAndStartFace" v-if="examState < 41">1、开始识别</div>
|
|
|
+ <div @click="getStopFace" v-if="examState == 41">2、停止人脸识别</div>
|
|
|
+ <div @click="getStartOneTest" v-if="examState == 43">3、开始测试</div>
|
|
|
+ </div>
|
|
|
+ <div v-else>
|
|
|
+ <div @click="getReady" v-if="examState == 43" class="startBtn">开始测试</div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -35,6 +42,7 @@ const data = reactive<any>({
|
|
|
time: {
|
|
|
testTime: 60,//时长
|
|
|
countdownNum: 0,//计时
|
|
|
+ ready: 0,//预备
|
|
|
},
|
|
|
userInfo: {},//用户信息
|
|
|
examState: 0,//当前状态
|
|
@@ -100,6 +108,8 @@ const getStartOneTest = () => {
|
|
|
proxy?.$modal.msgWarning("请选择人员!");
|
|
|
return false;
|
|
|
}
|
|
|
+ getClearTimer("readyTimer");
|
|
|
+ time.value.ready = 0;
|
|
|
examState.value = 42;
|
|
|
for (let i = 0; i < multipleItemRefList.value.length; i++) {
|
|
|
if (testList.value[i].examState == 41) {
|
|
@@ -110,10 +120,9 @@ const getStartOneTest = () => {
|
|
|
multipleItemRefList.value[i].getStartOneTest()
|
|
|
}
|
|
|
}
|
|
|
+ speckText("哨声");
|
|
|
//显示再测一次按钮
|
|
|
showTestAgain.value = true;
|
|
|
- //停止播报;
|
|
|
- speckCancel()
|
|
|
//时间为0的为正计时,大于0的为倒计时
|
|
|
if (time.value.testTime == 0) {
|
|
|
getCounting("+");
|
|
@@ -184,9 +193,10 @@ const cleanData = () => {
|
|
|
/**
|
|
|
* 时间转换
|
|
|
*/
|
|
|
-const countdownNumFormat = computed(() => {
|
|
|
- return proxy?.$utils.timeFormat(time.value.countdownNum);
|
|
|
-});
|
|
|
+// const countdownNumFormat = computed(() => {
|
|
|
+// return time.value.countdownNum;
|
|
|
+// //return proxy?.$utils.timeFormat(time.value.countdownNum);
|
|
|
+// });
|
|
|
|
|
|
/**
|
|
|
* 倒计时
|
|
@@ -215,27 +225,55 @@ const returnData = (data: any) => {
|
|
|
let index = testList.value.findIndex((item: any) => {
|
|
|
return item.area == data.area;
|
|
|
});
|
|
|
- testList.value[index] = Object.assign(testList.value[index], data);
|
|
|
+ let obj = Object.assign(testList.value[index], data);
|
|
|
+ testList.value[index] = JSON.parse(JSON.stringify(obj));
|
|
|
console.log("testList.value", testList.value)
|
|
|
- //测试完成后回退状态
|
|
|
- if (examState.value == 42) {
|
|
|
+
|
|
|
+ if (examState.value == 0) {
|
|
|
let flag = false;
|
|
|
//只监听人脸识别的区
|
|
|
- let newList = testList.value.filter((item: any) => {
|
|
|
- return item?.faceCheckStu?.student_id;
|
|
|
- })
|
|
|
+ let newList = testList.value;
|
|
|
for (let i = 0; i < newList.length; i++) {
|
|
|
- if (newList[i] && newList[i].faceCheckStu?.student_id && newList[i].examState == 3) {
|
|
|
+ if (newList[i] && newList[i].examState == 3) {
|
|
|
flag = true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
}
|
|
|
}
|
|
|
if (flag) {
|
|
|
+ console.log("变更状态:", 3)
|
|
|
examState.value = 3;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (examState.value == 3) {
|
|
|
+ let flag = false;
|
|
|
+ //只监听人脸识别的区
|
|
|
+ let newList = testList.value;
|
|
|
+ for (let i = 0; i < newList.length; i++) {
|
|
|
+ if (newList[i] && newList[i].examState == 40) {
|
|
|
+ flag = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (flag) {
|
|
|
+ console.log("变更状态:", 40)
|
|
|
+ examState.value = 40;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (examState.value == 40) {
|
|
|
+ let flag = false;
|
|
|
+ //只监听人脸识别的区
|
|
|
+ let newList = testList.value;
|
|
|
+ for (let i = 0; i < newList.length; i++) {
|
|
|
+ if (newList[i] && newList[i].examState == 41) {
|
|
|
+ flag = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (flag) {
|
|
|
+ console.log("变更状态:", 41)
|
|
|
+ examState.value = 41;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (examState.value == 41) {
|
|
|
let flag = false;
|
|
|
//只监听人脸识别的区
|
|
@@ -245,32 +283,35 @@ const returnData = (data: any) => {
|
|
|
for (let i = 0; i < newList.length; i++) {
|
|
|
if (newList[i] && newList[i].faceCheckStu?.student_id && newList[i].examState == 43) {
|
|
|
flag = true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
}
|
|
|
}
|
|
|
if (flag) {
|
|
|
+ console.log("变更状态:", 43)
|
|
|
examState.value = 43;
|
|
|
+ cleanData();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (examState.value == 0) {
|
|
|
+ //测试完成后回退状态
|
|
|
+ if (examState.value == 42) {
|
|
|
let flag = false;
|
|
|
//只监听人脸识别的区
|
|
|
let newList = testList.value.filter((item: any) => {
|
|
|
return item?.faceCheckStu?.student_id;
|
|
|
})
|
|
|
for (let i = 0; i < newList.length; i++) {
|
|
|
- if (newList[i] && newList[i].faceCheckStu?.student_id && newList[i].examState == 41) {
|
|
|
+ if (newList[i] && newList[i].faceCheckStu?.student_id && newList[i].examState == 3) {
|
|
|
flag = true;
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
if (flag) {
|
|
|
- examState.value = 41;
|
|
|
+ console.log("变更状态:", 3)
|
|
|
+ examState.value = 3;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
//如果全部状态为0就退出
|
|
|
if (examState.value >= 0) {
|
|
|
let flag = false;
|
|
@@ -290,6 +331,26 @@ const returnData = (data: any) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+/**
|
|
|
+ * 准备开始
|
|
|
+*/
|
|
|
+const getReady = () => {
|
|
|
+ //停止播报;
|
|
|
+ speckCancel()
|
|
|
+ time.value.ready = 5;
|
|
|
+ speckText(time.value.ready);
|
|
|
+ timerManager.value.readyTimer = setInterval(() => {
|
|
|
+ time.value.ready--;
|
|
|
+ if (time.value.ready < 1) {
|
|
|
+ getClearTimer("readyTimer");
|
|
|
+ getStartOneTest();
|
|
|
+ } else {
|
|
|
+ speckText(time.value.ready);
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+};
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
parameter.value = route.query;
|
|
|
let project = parameter.value.project;
|
|
@@ -325,6 +386,12 @@ onMounted(() => {
|
|
|
multipleItemRefList.value[index]?.getMessage(data);
|
|
|
});
|
|
|
initSpeech();
|
|
|
+ setTimeout(() => {
|
|
|
+ //30秒还在0状态就算超时
|
|
|
+ if (examState.value == 0) {
|
|
|
+ getExit();
|
|
|
+ }
|
|
|
+ }, 30000);
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
@@ -332,4 +399,100 @@ onUnmounted(() => {
|
|
|
})
|
|
|
</script>
|
|
|
|
|
|
-<style scoped lang="scss"></style>
|
|
|
+<style scoped lang="scss">
|
|
|
+$topPadding: 5.19rem;
|
|
|
+$waiPadding: 6.51rem;
|
|
|
+
|
|
|
+.main {
|
|
|
+ width: calc(100% - ($waiPadding * 2));
|
|
|
+ height: 78vh;
|
|
|
+ padding-top: 10rem;
|
|
|
+ margin: 0 auto;
|
|
|
+ display: flex;
|
|
|
+ overflow: hidden;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .time {
|
|
|
+ width: 28vh;
|
|
|
+ height: 28vh;
|
|
|
+ line-height: 28vh;
|
|
|
+ border-radius: 50%;
|
|
|
+ color: #FF9402;
|
|
|
+ font-size: 11vh;
|
|
|
+ text-align: center;
|
|
|
+ background-image: url("@/assets/images/test/time.png");
|
|
|
+ background-position: center;
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ position: absolute;
|
|
|
+ right: 50%;
|
|
|
+ top: 0;
|
|
|
+ margin-right: -28vh;
|
|
|
+ font-family: 'Saira-BlackItalic';
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|
|
|
+<style lang="scss">
|
|
|
+$topPadding: 5.19rem;
|
|
|
+$waiPadding: 6.51rem;
|
|
|
+
|
|
|
+.box {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ $listWidth: calc((100% - ($waiPadding * 2)) /5);
|
|
|
+ $listMargin: 4vw;
|
|
|
+
|
|
|
+ .list {
|
|
|
+ width: $listWidth;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .ready {
|
|
|
+ position: absolute;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:nth-child(2) {
|
|
|
+ margin-left: calc($listWidth + $listMargin);
|
|
|
+ margin-right: calc($listWidth + $listMargin);
|
|
|
+
|
|
|
+
|
|
|
+ .ready {}
|
|
|
+ }
|
|
|
+
|
|
|
+ &:nth-child(4) {
|
|
|
+ margin-left: calc(($listWidth + $listMargin) /2);
|
|
|
+ margin-right: calc(($listWidth + $listMargin) /2);
|
|
|
+
|
|
|
+ .ready {
|
|
|
+
|
|
|
+ top: -100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:nth-child(5) {
|
|
|
+ margin-left: calc(($listWidth + $listMargin) /2);
|
|
|
+ margin-right: calc(($listWidth + $listMargin) /2);
|
|
|
+
|
|
|
+ .ready {
|
|
|
+ top: -100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.startBtn {
|
|
|
+ width: 200px;
|
|
|
+ height: 2rem;
|
|
|
+ font-size: 2rem;
|
|
|
+ border-radius: 15px;
|
|
|
+ background: radial-gradient(159% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
|
|
|
+ box-shadow: 3px 6px 4px 1px rgba(0, 0, 0, 0.1874), inset 0px 1px 0px 2px rgba(255, 255, 255, 0.5577);
|
|
|
+}
|
|
|
+</style>
|