|
@@ -1,46 +1,71 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
- <div v-if="needStart">{{
|
|
|
- countdownNumFormat
|
|
|
- }}</div>
|
|
|
- <div class="trackItem">
|
|
|
- <div v-for="(item, index) in faceStudentList" :key="index" class="li">
|
|
|
- <div>{{ item.track }}</div>
|
|
|
- <div><el-avatar :src="item.face_pic" @click="getChooseStudent(item.track)" />
|
|
|
+ <Header @confirmExit="confirmExit"></Header>
|
|
|
+ <transition :enter-active-class="proxy?.animate.dialog.enter" :leave-active-class="proxy?.animate.dialog.leave">
|
|
|
+ <div class="time" v-show="[42].includes(examState)">{{
|
|
|
+ countdownNumFormat
|
|
|
+ }}</div>
|
|
|
+ </transition>
|
|
|
+ <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" />
|
|
|
+ </div>
|
|
|
+ <div class="name">{{ item.student_name || "未检录" }}</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>{{ item.student_name || "未检录" }}</div>
|
|
|
-
|
|
|
- <view>
|
|
|
- <view v-if="item.timeStr" class="achievement">
|
|
|
- {{ 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 btn3" v-if="examState == 3 && !item.timeStr && item.isfinish && item.student_id">异常
|
|
|
- </view>
|
|
|
+ </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 class="right">
|
|
|
+ <div class="score">{{ item.result }}
|
|
|
+ </div>
|
|
|
+ <div class="unit">{{ unit }}</div>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div>当前状态:({{ examState == 3 ? "初始化完成" : examState == 40 ? "创建测试" : examState == 41 ? "正在人脸识别"
|
|
|
- :
|
|
|
- examState ==
|
|
|
- 43 ? "停止人脸识别" : examState == 42 ? "正在测试" : "请初始化" }})</div>
|
|
|
-
|
|
|
- <div v-if="needStart">
|
|
|
- <div @click="getOpenOneTestAndStartFace" v-if="examState == 3 || examState == 40">1、开始识别</div>
|
|
|
- <div @click="getStopFace" v-if="examState == 41">2、停止人脸识别</div>
|
|
|
- <div @click="getStartOneTest" v-if="examState == 43">3、开始测试</div>
|
|
|
+ <!-- <div>当前状态:({{ examState == 3 ? "初始化完成" : examState == 40 ? "创建测试" : examState == 41 ? "正在人脸识别":examState ==43 ? "停止人脸识别" : examState == 42 ? "正在测试" : "请初始化" }})</div> -->
|
|
|
+ <div class="footerBtn">
|
|
|
+ <template v-if="needStart">
|
|
|
+ <div class="btn" @click="getOpenOneTestAndStartFace" v-if="examState == 3 || examState == 40">开始识别</div>
|
|
|
+ <div class="btn" @click="getStopFace" v-if="examState == 41">停止识别</div>
|
|
|
+ <div class="btn startBtn" @click="getStartOneTest" v-if="examState == 43">开始测试</div>
|
|
|
+ </template>
|
|
|
+ <template v-else> </template>
|
|
|
+ <div class="btn" @click="getRetestFace" v-if="examState == 43">重新识别</div>
|
|
|
+ <div class="btn" @click="getAgain" v-if="examState == 42 || showTestAgain">再测一次</div>
|
|
|
</div>
|
|
|
- <div @click="getRetestFace" v-if="examState == 43 || examState == 42">重新识别</div>
|
|
|
- <div @click="getAgain" v-if="examState == 42 || showTestAgain">再测一次</div>
|
|
|
- <div @click="confirmExit">退出</div>
|
|
|
<ChooseStudent ref="chooseStudentRef" @returnData="returnStudent" />
|
|
|
</div>
|
|
|
</template>
|
|
@@ -48,6 +73,7 @@
|
|
|
<script setup name="TrainTest" lang="ts">
|
|
|
import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
|
|
|
import { initWs, examEnds, openOneTest, startFace, stopFace, faceConfirmOnly, startOneTest, finishOneTest, closeOneTest, suspendFaceRecognitionChannels, resumeFaceRecognitionChannels } from '@/utils/ws'
|
|
|
+import dayjs from 'dayjs'
|
|
|
import dataDictionary from "@/utils/dataDictionary"
|
|
|
const { proxy } = getCurrentInstance() as any;
|
|
|
const router = useRouter();
|
|
@@ -68,8 +94,9 @@ const data = reactive<any>({
|
|
|
faceStudentList: [],//跑道和人信息
|
|
|
currentTrack: null,//当前跑道
|
|
|
showTestAgain: false,//再测一次按钮
|
|
|
+ reportList: [],//测试列表
|
|
|
});
|
|
|
-const { timerManager, parameter, time, userInfo, examState, resultId, faceStudentList, currentTrack, unit, needStart, showTestAgain } = toRefs(data);
|
|
|
+const { timerManager, parameter, time, userInfo, examState, resultId, faceStudentList, currentTrack, unit, needStart, showTestAgain, reportList } = toRefs(data);
|
|
|
|
|
|
/**
|
|
|
* 接收消息
|
|
@@ -356,7 +383,7 @@ const cleanData = () => {
|
|
|
//重置全部
|
|
|
let list = faceStudentList.value.map((item: any) => {
|
|
|
let obj = {
|
|
|
- student_id: null,
|
|
|
+ student_id: -1,
|
|
|
track: item.track,
|
|
|
isfinish: false,
|
|
|
}
|
|
@@ -478,7 +505,26 @@ const getAchievement = (data: any) => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
-onMounted(() => {
|
|
|
+/**
|
|
|
+ * 当天成绩列表
|
|
|
+*/
|
|
|
+const getReportList = () => {
|
|
|
+ let params: any = {
|
|
|
+ start_date: dayjs().format("YYYY-MM-DD"),
|
|
|
+ end_date: dayjs().format("YYYY-MM-DD"),
|
|
|
+ exam_name: parameter.value.project,
|
|
|
+
|
|
|
+ page: 1,
|
|
|
+ per_page: 9000
|
|
|
+ };
|
|
|
+ proxy?.$http.common.reportList(params).then((res: any) => {
|
|
|
+ if (res.data.length > 0) {
|
|
|
+ reportList.value = res.data;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+onBeforeMount(() => {
|
|
|
parameter.value = route.query;
|
|
|
let project = parameter.value.project;
|
|
|
let area = parameter.value.area;
|
|
@@ -503,6 +549,7 @@ onMounted(() => {
|
|
|
getMessage(data);
|
|
|
});
|
|
|
initSpeech();
|
|
|
+ getReportList();
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
@@ -511,12 +558,269 @@ onUnmounted(() => {
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.trackItem {
|
|
|
- .li {
|
|
|
+$topPadding: 5.19rem;
|
|
|
+$waiPadding: 6.51rem;
|
|
|
+
|
|
|
+.time {
|
|
|
+ width: 20vh;
|
|
|
+ height: 20vh;
|
|
|
+ line-height: 20vh;
|
|
|
+ border-radius: 50%;
|
|
|
+ color: #FF9402;
|
|
|
+ font-size: 8vh;
|
|
|
+ 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: -4vh;
|
|
|
+ margin-right: -10vh;
|
|
|
+ font-family: 'Saira-BlackItalic';
|
|
|
+}
|
|
|
+
|
|
|
+.main {
|
|
|
+ width: calc(100% - ($waiPadding * 2));
|
|
|
+ height: 70vh;
|
|
|
+ padding-top: 10rem;
|
|
|
+ margin: 0 auto;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ .main-left {
|
|
|
+ width: 71.5%;
|
|
|
display: flex;
|
|
|
+ background: linear-gradient(58deg, #092941 -85%, #2A484B 96%);
|
|
|
+ box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.4);
|
|
|
+ border-radius: 1.6rem;
|
|
|
+
|
|
|
+ .trackItem {
|
|
|
+ width: 100%;
|
|
|
+ overflow-y: hidden;
|
|
|
+ padding: 0px 10px;
|
|
|
+
|
|
|
+ .li {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ border-bottom: 1px solid #475557;
|
|
|
+
|
|
|
+ .track {
|
|
|
+ color: #13ED84;
|
|
|
+ font-size: 2rem;
|
|
|
+ font-family: 'Saira-ExtraBold';
|
|
|
+ }
|
|
|
+
|
|
|
+ .pic {
|
|
|
+ width: 8vh;
|
|
|
+ height: 8vh;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .userInfo {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: 2rem;
|
|
|
+ color: #ffffff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .menuBtn {
|
|
|
+ width: auto;
|
|
|
+ padding: 0 1.2rem 0 0.7rem;
|
|
|
+ height: 3rem;
|
|
|
+ line-height: 3rem;
|
|
|
+ border-radius: 1.5rem;
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 1.7rem;
|
|
|
+ margin-left: 1rem;
|
|
|
+ background: linear-gradient(180deg, #FFB200 0%, #ED7905 72%);
|
|
|
+ box-shadow: inset 0px 1px 0px 1px rgba(255, 255, 255, 0.5);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .main-right {
|
|
|
+ width: 27%;
|
|
|
+ border-radius: 1.6rem;
|
|
|
+ background: linear-gradient(29deg, #092941 -82%, #2A484B 94%);
|
|
|
+ box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.4);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ height: 7.05vh;
|
|
|
+ line-height: 7.05vh;
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ color: #1A293A;
|
|
|
+ font-size: 1.65rem;
|
|
|
+ background: radial-gradient(120% 126% at 5% 93%, #8EFFA9 0%, #07FFE7 100%);
|
|
|
+ }
|
|
|
+
|
|
|
+ ul {
|
|
|
+ height: 100%;
|
|
|
+ overflow-y: scroll;
|
|
|
+
|
|
|
+ li {
|
|
|
+ border-bottom: 1px solid #48677E;
|
|
|
+ padding: 8px 30px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: rgba(255, 255, 255, 0.4);
|
|
|
+ }
|
|
|
+
|
|
|
+ .left {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ .pic {
|
|
|
+ width: 7.5vh;
|
|
|
+ height: 7.5vh;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ overflow: hidden;
|
|
|
+ box-sizing: border-box;
|
|
|
+ border: 1px solid rgba(255, 255, 255, 0.5);
|
|
|
+ margin-right: 13px;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .txt {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ color: #F9F9F9;
|
|
|
+ font-size: 1.38rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ .className {
|
|
|
+ color: #13ED84;
|
|
|
+ font-size: 1.1rem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ display: flex;
|
|
|
+ font-weight: bold;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .score {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 1.1rem;
|
|
|
+ font-family: 'Saira-ExtraBold';
|
|
|
+ }
|
|
|
+
|
|
|
+ .unit {
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 0.8rem;
|
|
|
+ margin-left: 2px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: 0px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ border-width: 2px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border-style: dashed;
|
|
|
+ border-color: transparent;
|
|
|
+ background-color: rgba(216, 216, 216, 0.8);
|
|
|
+ background-clip: padding-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ &::-webkit-scrollbar-button:hover {
|
|
|
+ border-radius: 6px;
|
|
|
+ background: rgba(216, 216, 216, 0.8);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .erweima {
|
|
|
+ text-align: center;
|
|
|
+ padding: 1vh 0;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 5rem;
|
|
|
+ }
|
|
|
+
|
|
|
+ span {
|
|
|
+ display: block;
|
|
|
+ color: #FFFFFF;
|
|
|
+ font-size: 1.1rem;
|
|
|
+ padding-top: 3px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.footerBtn {
|
|
|
+ width: 100%;
|
|
|
+ padding: 0 calc(13.02rem /2);
|
|
|
+ box-sizing: border-box;
|
|
|
+ position: fixed;
|
|
|
+ bottom: 3vh;
|
|
|
+ display: flex;
|
|
|
+ justify-content: end;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ width: 14.6vw;
|
|
|
+ height: 6.1vh;
|
|
|
+ line-height: 6.1vh;
|
|
|
+ font-size: 3vh;
|
|
|
+ color: #1A293A;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 1vh;
|
|
|
+ margin-left: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ 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);
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #8EFFA9;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .startBtn {
|
|
|
+ color: #ffffff;
|
|
|
+ background: radial-gradient(159% 126% at 5% 93%, #F99F02 0%, #ED7905 100%);
|
|
|
+ box-shadow: 3px 6px 4px 1px rgba(0, 0, 0, 0.1874), inset 0px 1px 0px 2px rgba(255, 255, 255, 0.5577);
|
|
|
|
|
|
- .menuBtn {
|
|
|
- margin-left: 20px;
|
|
|
+ &:hover {
|
|
|
+ background: #F99F02;
|
|
|
}
|
|
|
}
|
|
|
}
|