|
@@ -4,57 +4,98 @@
|
|
<transition :enter-active-class="proxy?.animate.dialog.enter" :leave-active-class="proxy?.animate.dialog.leave">
|
|
<transition :enter-active-class="proxy?.animate.dialog.enter" :leave-active-class="proxy?.animate.dialog.leave">
|
|
<div class="time" v-show="[42].includes(examState)">{{
|
|
<div class="time" v-show="[42].includes(examState)">{{
|
|
countdownNumFormat
|
|
countdownNumFormat
|
|
- }}</div>
|
|
|
|
|
|
+ }}</div>
|
|
</transition>
|
|
</transition>
|
|
<div class="main">
|
|
<div class="main">
|
|
- <div class="main-left">
|
|
|
|
- <div class="trackItem">
|
|
|
|
- <div v-for="(item, index) in faceStudentList" :key="index" class="li">
|
|
|
|
- <div class="track">{{ item.track }}</div>
|
|
|
|
- <div class="userInfo" @click="getChooseStudent(item.track)">
|
|
|
|
- <div class="pic" v-if="item.face_pic"> <img :src="item.face_pic" /></div>
|
|
|
|
- <div class="pic" v-else>
|
|
|
|
- <img src="@/assets/images/test/profilePicture.png" />
|
|
|
|
|
|
+
|
|
|
|
+ <template v-if="isLongRun">
|
|
|
|
+ <swiper :slides-per-view="2" :space-between="20">
|
|
|
|
+ <swiper-slide v-for="(items, indexs) in testListArr " :key="indexs">
|
|
|
|
+ <div class="main-left">
|
|
|
|
+ <div class="trackItem">
|
|
|
|
+ <div v-for="(item, index) in items" :key="index" class="li">
|
|
|
|
+ <div class="track">{{ item.track }}</div>
|
|
|
|
+ <div class="userInfo" @click="getChooseStudent(item.track)">
|
|
|
|
+ <div class="pic pic2" v-if="item.face_pic"> <img :src="item.face_pic" /></div>
|
|
|
|
+ <div class="pic" v-else>
|
|
|
|
+ <img src="@/assets/images/test/profilePicture.png" />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="name">{{ item.student_name || "未检录" }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <div v-if="item.timeStr" class="score">
|
|
|
|
+ {{ item.timeStr || "-" }}
|
|
|
|
+ </div>
|
|
|
|
+ <div v-if="isBackRun && item.student_id"> 往返次数:{{ item.turns || "0" }} </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="menuBtn" v-if="isBackRun && item.student_id"> 往返次数:{{ item.turns || "0" }} </div>
|
|
|
|
+ <div class="menuBtn" v-if="examState < 42" @click="getChooseStudent(item.track)">检录</div>
|
|
|
|
+ <div class="menuBtn" v-if="examState == 43">等待开始测试</div>
|
|
|
|
+ <div class="menuBtn" v-if="examState == 42">正在测试</div>
|
|
|
|
+ <div class="menuBtn menuBtn"
|
|
|
|
+ v-if="examState == 3 && !item.timeStr && item.isfinish && item.student_id">
|
|
|
|
+ 异常
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </swiper-slide>
|
|
|
|
+ </swiper>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <div class="main-left">
|
|
|
|
+ <div class="trackItem">
|
|
|
|
+ <div v-for="(item, index) in faceStudentList" :key="index" class="li">
|
|
|
|
+ <div class="track">{{ item.track }}</div>
|
|
|
|
+ <div class="userInfo" @click="getChooseStudent(item.track)">
|
|
|
|
+ <div class="pic pic2" v-if="item.face_pic"> <img :src="item.face_pic" /></div>
|
|
|
|
+ <div class="pic" v-else>
|
|
|
|
+ <img src="@/assets/images/test/profilePicture.png" />
|
|
|
|
+ </div>
|
|
|
|
+ <div class="name">{{ item.student_name || "未检录" }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div>
|
|
|
|
+ <div v-if="item.timeStr" class="score">
|
|
|
|
+ {{ item.timeStr || "-" }}
|
|
|
|
+ </div>
|
|
|
|
+ <div v-if="isBackRun && item.student_id"> 往返次数:{{ item.turns || "0" }} </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="menuBtn" v-if="isBackRun && item.student_id"> 往返次数:{{ item.turns || "0" }} </div>
|
|
|
|
+ <div class="menuBtn" v-if="examState < 42" @click="getChooseStudent(item.track)">检录</div>
|
|
|
|
+ <div class="menuBtn" v-if="examState == 43">等待开始测试</div>
|
|
|
|
+ <div class="menuBtn" v-if="examState == 42">正在测试</div>
|
|
|
|
+ <div class="menuBtn menuBtn" v-if="examState == 3 && !item.timeStr && item.isfinish && item.student_id">
|
|
|
|
+ 异常
|
|
</div>
|
|
</div>
|
|
- <div class="name">{{ item.student_name || "未检录" }}</div>
|
|
|
|
</div>
|
|
</div>
|
|
- <view>
|
|
|
|
- <view v-if="item.timeStr" class="score">
|
|
|
|
- {{ item.timeStr || "-" }}
|
|
|
|
- </view>
|
|
|
|
- <view v-if="isBackRun && item.student_id"> 往返次数:{{ item.turns || "0" }} </view>
|
|
|
|
- </view>
|
|
|
|
- <view class="menuBtn" v-if="isBackRun && item.student_id"> 往返次数:{{ item.turns || "0" }} </view>
|
|
|
|
- <div class="menuBtn" v-if="examState < 42" @click="getChooseStudent(item.track)">检录</div>
|
|
|
|
- <div class="menuBtn" v-if="examState == 43">等待开始测试</div>
|
|
|
|
- <div class="menuBtn" v-if="examState == 42">正在测试</div>
|
|
|
|
- <view class="menuBtn menuBtn" v-if="examState == 3 && !item.timeStr && item.isfinish && item.student_id">异常
|
|
|
|
- </view>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- <div class="main-right">
|
|
|
|
- <div class="title">测试记录</div>
|
|
|
|
- <ul>
|
|
|
|
- <li v-for="(item, index) in reportList " :key="index">
|
|
|
|
- <div class="left">
|
|
|
|
- <div class="pic"><img :src="item.face_pic || item.logo_url" /></div>
|
|
|
|
- <div class="txt">
|
|
|
|
- <div>
|
|
|
|
- <div class="name">{{ item.student_name }}</div>
|
|
|
|
- <div class="className"></div>
|
|
|
|
|
|
+ <div class="main-right">
|
|
|
|
+ <div class="title">测试记录</div>
|
|
|
|
+ <ul>
|
|
|
|
+ <li v-for="(item, index) in reportList " :key="index">
|
|
|
|
+ <div class="left">
|
|
|
|
+ <div class="pic"><img :src="item.face_pic || item.logo_url" /></div>
|
|
|
|
+ <div class="txt">
|
|
|
|
+ <div>
|
|
|
|
+ <div class="name">{{ item.student_name }}</div>
|
|
|
|
+ <div class="className"></div>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
- <div class="right">
|
|
|
|
- <div class="score">{{ item.result }}
|
|
|
|
|
|
+ <div class="right">
|
|
|
|
+ <div class="score">{{ item.result }}
|
|
|
|
+ </div>
|
|
|
|
+ <div class="unit">{{ unit }}</div>
|
|
</div>
|
|
</div>
|
|
- <div class="unit">{{ unit }}</div>
|
|
|
|
- </div>
|
|
|
|
- </li>
|
|
|
|
- </ul>
|
|
|
|
- </div>
|
|
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
</div>
|
|
</div>
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
<!-- <div>当前状态:({{ examState == 3 ? "初始化完成" : examState == 40 ? "创建测试" : examState == 41 ? "正在人脸识别":examState ==43 ? "停止人脸识别" : examState == 42 ? "正在测试" : "请初始化" }})</div> -->
|
|
<!-- <div>当前状态:({{ examState == 3 ? "初始化完成" : examState == 40 ? "创建测试" : examState == 41 ? "正在人脸识别":examState ==43 ? "停止人脸识别" : examState == 42 ? "正在测试" : "请初始化" }})</div> -->
|
|
<div class="footerBtn">
|
|
<div class="footerBtn">
|
|
<template v-if="needStart">
|
|
<template v-if="needStart">
|
|
@@ -75,6 +116,10 @@ import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speec
|
|
import { initWs, examEnds, openOneTest, startFace, stopFace, faceConfirmOnly, startOneTest, finishOneTest, closeOneTest, suspendFaceRecognitionChannels, resumeFaceRecognitionChannels } from '@/utils/ws'
|
|
import { initWs, examEnds, openOneTest, startFace, stopFace, faceConfirmOnly, startOneTest, finishOneTest, closeOneTest, suspendFaceRecognitionChannels, resumeFaceRecognitionChannels } from '@/utils/ws'
|
|
import dayjs from 'dayjs'
|
|
import dayjs from 'dayjs'
|
|
import dataDictionary from "@/utils/dataDictionary"
|
|
import dataDictionary from "@/utils/dataDictionary"
|
|
|
|
+import { Swiper, SwiperSlide } from 'swiper/vue';
|
|
|
|
+import { Grid } from 'swiper/modules';
|
|
|
|
+import 'swiper/css';
|
|
|
|
+import 'swiper/css/grid';
|
|
const { proxy } = getCurrentInstance() as any;
|
|
const { proxy } = getCurrentInstance() as any;
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
@@ -95,8 +140,10 @@ const data = reactive<any>({
|
|
currentTrack: null,//当前跑道
|
|
currentTrack: null,//当前跑道
|
|
showTestAgain: false,//再测一次按钮
|
|
showTestAgain: false,//再测一次按钮
|
|
reportList: [],//测试列表
|
|
reportList: [],//测试列表
|
|
|
|
+ isLongRun: false,//是否为长跑项目
|
|
|
|
+ isBackRun: false,//是否为折返跑项目
|
|
});
|
|
});
|
|
-const { timerManager, parameter, time, userInfo, examState, resultId, faceStudentList, currentTrack, unit, needStart, showTestAgain, reportList } = toRefs(data);
|
|
|
|
|
|
+const { timerManager, parameter, time, userInfo, examState, resultId, faceStudentList, currentTrack, unit, needStart, showTestAgain, reportList, isLongRun, isBackRun } = toRefs(data);
|
|
|
|
|
|
/**
|
|
/**
|
|
* 接收消息
|
|
* 接收消息
|
|
@@ -109,13 +156,21 @@ const getMessage = (e: any) => {
|
|
}
|
|
}
|
|
//工作站状态
|
|
//工作站状态
|
|
if (e.cmd === 'init_result') {
|
|
if (e.cmd === 'init_result') {
|
|
-
|
|
|
|
|
|
+ if (isLongRun.value) {
|
|
|
|
+ let num = 70;
|
|
|
|
+ let list: any = [];
|
|
|
|
+ for (let i = 1; i <= num; i++) {
|
|
|
|
+ list.push({ track: i });
|
|
|
|
+ }
|
|
|
|
+ faceStudentList.value = list
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
//获取跑道配置
|
|
//获取跑道配置
|
|
if (e.cmd === 'exam_config') {
|
|
if (e.cmd === 'exam_config') {
|
|
|
|
+ let num = e.data.num_of_tracks;
|
|
let list: any = [];
|
|
let list: any = [];
|
|
- for (let i = 1; i <= e.data.num_of_tracks; i++) {
|
|
|
|
|
|
+ for (let i = 1; i <= num; i++) {
|
|
list.push({ track: i });
|
|
list.push({ track: i });
|
|
}
|
|
}
|
|
faceStudentList.value = list
|
|
faceStudentList.value = list
|
|
@@ -214,10 +269,18 @@ const getStopFace = async () => {
|
|
* 确定人脸信息
|
|
* 确定人脸信息
|
|
*/
|
|
*/
|
|
const getFaceConfirmOnly = (data?: any) => {
|
|
const getFaceConfirmOnly = (data?: any) => {
|
|
|
|
+ let list = [];
|
|
if (data) {
|
|
if (data) {
|
|
faceStudentList.value = data;
|
|
faceStudentList.value = data;
|
|
|
|
+ list = data.filter((item: any) => {
|
|
|
|
+ return item.student_id;
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ list = faceStudentList.value.filter((item: any) => {
|
|
|
|
+ return item.student_id;
|
|
|
|
+ });
|
|
}
|
|
}
|
|
- faceConfirmOnly(faceStudentList.value, () => {
|
|
|
|
|
|
+ faceConfirmOnly(list, () => {
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
@@ -280,7 +343,16 @@ const getStartOneTest = () => {
|
|
*/
|
|
*/
|
|
const getAgain = async () => {
|
|
const getAgain = async () => {
|
|
//预存测试人员
|
|
//预存测试人员
|
|
- let student = JSON.parse(JSON.stringify(faceStudentList.value));
|
|
|
|
|
|
+ let student = faceStudentList.value.map((item: any) => {
|
|
|
|
+ let obj = {
|
|
|
|
+ face_pic: item.face_pic,
|
|
|
|
+ student_id: item.student_id,
|
|
|
|
+ student_name: item.student_name,
|
|
|
|
+ gender: item.gender,
|
|
|
|
+ track: item.track,
|
|
|
|
+ }
|
|
|
|
+ return obj;
|
|
|
|
+ });
|
|
//测试中
|
|
//测试中
|
|
if (examState.value == 42) {
|
|
if (examState.value == 42) {
|
|
await finishOneTest();
|
|
await finishOneTest();
|
|
@@ -383,7 +455,7 @@ const cleanData = () => {
|
|
//重置全部
|
|
//重置全部
|
|
let list = faceStudentList.value.map((item: any) => {
|
|
let list = faceStudentList.value.map((item: any) => {
|
|
let obj = {
|
|
let obj = {
|
|
- student_id: -1,
|
|
|
|
|
|
+ student_id: null,
|
|
track: item.track,
|
|
track: item.track,
|
|
isfinish: false,
|
|
isfinish: false,
|
|
}
|
|
}
|
|
@@ -407,28 +479,6 @@ const countdownNumFormat = computed(() => {
|
|
return proxy?.$utils.timeFormat(time.value.countdownNum);
|
|
return proxy?.$utils.timeFormat(time.value.countdownNum);
|
|
});
|
|
});
|
|
|
|
|
|
-/**
|
|
|
|
- * 判断是否为折返跑
|
|
|
|
-*/
|
|
|
|
-const isBackRun = computed(() => {
|
|
|
|
- let project = parameter.value.project;
|
|
|
|
- return (
|
|
|
|
- project.slice(0, 3) === "run" &&
|
|
|
|
- project.includes("x")
|
|
|
|
- );
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * 判断是否为长跑
|
|
|
|
-*/
|
|
|
|
-const isLongRun = computed(() => {
|
|
|
|
- let project = parameter.value.project;
|
|
|
|
- if (project.replace('run', '') > 799) {
|
|
|
|
- return true;
|
|
|
|
- } else {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-});
|
|
|
|
/**
|
|
/**
|
|
* 倒计时
|
|
* 倒计时
|
|
*/
|
|
*/
|
|
@@ -487,7 +537,7 @@ const getAchievement = (data: any) => {
|
|
if (obj != undefined && resultId.value == obj.result_id) {
|
|
if (obj != undefined && resultId.value == obj.result_id) {
|
|
if (
|
|
if (
|
|
parseInt(obj.track) === parseInt(item.track) ||
|
|
parseInt(obj.track) === parseInt(item.track) ||
|
|
- isLongRun
|
|
|
|
|
|
+ isLongRun.value
|
|
) {
|
|
) {
|
|
faceStudentList.value[index].timeStr = obj.timeStr
|
|
faceStudentList.value[index].timeStr = obj.timeStr
|
|
faceStudentList.value[index].times = obj.times
|
|
faceStudentList.value[index].times = obj.times
|
|
@@ -524,6 +574,72 @@ const getReportList = () => {
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * 将测试列表分页
|
|
|
|
+*/
|
|
|
|
+const testListArr: any = computed(() => {
|
|
|
|
+ let list: any = [];
|
|
|
|
+ let num = 7;
|
|
|
|
+ let myLength = Math.ceil(faceStudentList.value.length / num);
|
|
|
|
+ for (let i = 0; i < myLength; i++) {
|
|
|
|
+ list[i] = [];
|
|
|
|
+ for (let j = 0; j < faceStudentList.value.length; j++) {
|
|
|
|
+ if (j >= i * num && j < (i + 1) * num) {
|
|
|
|
+ list[i].push(faceStudentList.value[j])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return list;
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+* 长跑名单
|
|
|
|
+*/
|
|
|
|
+const faceStudentListLongRun: any = computed(() => {
|
|
|
|
+ if (isLongRun.value) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ console.log("嘻嘻嘻0", faceStudentList.value)
|
|
|
|
+ let list = faceStudentList.value.filter((item: any) => {
|
|
|
|
+ return item.student_id;
|
|
|
|
+ });
|
|
|
|
+ //按圈数分组排序
|
|
|
|
+ let arr: any = [];
|
|
|
|
+ JSON.parse(JSON.stringify(list)).forEach((item: any, index: number) => {
|
|
|
|
+ let myIndex = 0;
|
|
|
|
+ if (item.times != undefined) {
|
|
|
|
+ myIndex = item.times.length;
|
|
|
|
+ }
|
|
|
|
+ if (arr[myIndex] == undefined) {
|
|
|
|
+ arr[myIndex] = [];
|
|
|
|
+ }
|
|
|
|
+ arr[myIndex].push(item);
|
|
|
|
+ if (arr[myIndex]) {
|
|
|
|
+ arr[myIndex].sort((a: any, b: any) => {
|
|
|
|
+ let val1 = a.timeTotal;
|
|
|
|
+ let val2 = b.timeTotal;
|
|
|
|
+ return val1 - val2;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ console.log("嘻嘻嘻", arr);
|
|
|
|
+ if (arr.length) {
|
|
|
|
+ console.log("嘻嘻嘻1")
|
|
|
|
+ let myList = [];
|
|
|
|
+ for (let i = arr.length - 1; i >= 0; --i) {
|
|
|
|
+ if (arr.hasOwnProperty(i)) {
|
|
|
|
+ myList.push(...arr[i]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ console.log("嘻嘻嘻3", list)
|
|
|
|
+ return myList;
|
|
|
|
+ } else {
|
|
|
|
+ console.log("嘻嘻嘻2", list)
|
|
|
|
+ return list;
|
|
|
|
+ }
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+
|
|
onBeforeMount(() => {
|
|
onBeforeMount(() => {
|
|
parameter.value = route.query;
|
|
parameter.value = route.query;
|
|
let project = parameter.value.project;
|
|
let project = parameter.value.project;
|
|
@@ -542,6 +658,15 @@ onBeforeMount(() => {
|
|
} else {
|
|
} else {
|
|
parameter.value.gesture = false
|
|
parameter.value.gesture = false
|
|
}
|
|
}
|
|
|
|
+ //是否折返跑
|
|
|
|
+ if (project.slice(0, 3) === "run" &&
|
|
|
|
+ project.includes("x")) {
|
|
|
|
+ isBackRun.value = true
|
|
|
|
+ }
|
|
|
|
+ //是否长跑
|
|
|
|
+ if (project.replace('run', '') > 799) {
|
|
|
|
+ isLongRun.value = true
|
|
|
|
+ }
|
|
//需要开始按钮的项目
|
|
//需要开始按钮的项目
|
|
needStart.value = true;
|
|
needStart.value = true;
|
|
//加载WS
|
|
//加载WS
|
|
@@ -636,8 +761,8 @@ $waiPadding: 6.51rem;
|
|
}
|
|
}
|
|
|
|
|
|
.pic {
|
|
.pic {
|
|
- width: 8vh;
|
|
|
|
- height: 8vh;
|
|
|
|
|
|
+ width: 7vh;
|
|
|
|
+ height: 7vh;
|
|
border-radius: 50%;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
display: flex;
|
|
justify-content: center;
|
|
justify-content: center;
|
|
@@ -649,9 +774,15 @@ $waiPadding: 6.51rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ .pic2 {
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.5);
|
|
|
|
+ }
|
|
|
|
+
|
|
.userInfo {
|
|
.userInfo {
|
|
display: flex;
|
|
display: flex;
|
|
- justify-content: center;
|
|
|
|
|
|
+ justify-content: flex-start;
|
|
align-items: center;
|
|
align-items: center;
|
|
|
|
|
|
.name {
|
|
.name {
|
|
@@ -660,6 +791,12 @@ $waiPadding: 6.51rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ .score {
|
|
|
|
+ color: #ffffff;
|
|
|
|
+ font-size: 2rem;
|
|
|
|
+ font-family: 'Saira-ExtraBold';
|
|
|
|
+ }
|
|
|
|
+
|
|
.menuBtn {
|
|
.menuBtn {
|
|
width: auto;
|
|
width: auto;
|
|
padding: 0 1.2rem 0 0.7rem;
|
|
padding: 0 1.2rem 0 0.7rem;
|