|
@@ -4,13 +4,14 @@
|
|
<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">
|
|
<template v-if="isLongRun">
|
|
<template v-if="isLongRun">
|
|
<!--长跑-->
|
|
<!--长跑-->
|
|
<swiper :slides-per-view="testListArr.length >= 2 ? 2 : 1" :slides-per-group="testListArr.length >= 2 ? 2 : 1"
|
|
<swiper :slides-per-view="testListArr.length >= 2 ? 2 : 1" :slides-per-group="testListArr.length >= 2 ? 2 : 1"
|
|
- :space-between="20">
|
|
|
|
|
|
+ :space-between="20" :speed="1200" :modules="[Navigation]"
|
|
|
|
+ :navigation="{ prevEl: '.swiper-button-prev', nextEl: ' .swiper-button-next' }">
|
|
<swiper-slide v-for="(items, indexs) in testListArr " :key="indexs">
|
|
<swiper-slide v-for="(items, indexs) in testListArr " :key="indexs">
|
|
<div class="main-left main-left2">
|
|
<div class="main-left main-left2">
|
|
<div class="trackItem">
|
|
<div class="trackItem">
|
|
@@ -48,6 +49,11 @@
|
|
</div>
|
|
</div>
|
|
</swiper-slide>
|
|
</swiper-slide>
|
|
</swiper>
|
|
</swiper>
|
|
|
|
+ <!-- 如果需要导航按钮 -->
|
|
|
|
+ <div v-show="testListArr.length > 2" class="swiper-button-prev swiper-btn swiper-btn-left" slot="button-prev">
|
|
|
|
+ </div>
|
|
|
|
+ <div v-show="testListArr.length > 2" class="swiper-button-next swiper-btn swiper-btn-right" slot="button-next">
|
|
|
|
+ </div>
|
|
</template>
|
|
</template>
|
|
<template v-else>
|
|
<template v-else>
|
|
<!--短跑-->
|
|
<!--短跑-->
|
|
@@ -58,12 +64,10 @@
|
|
<div class="left">
|
|
<div class="left">
|
|
<div class="track">{{ item.track }}</div>
|
|
<div class="track">{{ item.track }}</div>
|
|
<div class="userInfo" @click="getChooseStudent(item.track)">
|
|
<div class="userInfo" @click="getChooseStudent(item.track)">
|
|
-
|
|
|
|
<div class="pic pic2" v-if="item.student_id"> <img :src="item.face_pic" /></div>
|
|
<div class="pic pic2" v-if="item.student_id"> <img :src="item.face_pic" /></div>
|
|
<div class="pic" v-else>
|
|
<div class="pic" v-else>
|
|
<img src="@/assets/images/test/profilePicture.png" />
|
|
<img src="@/assets/images/test/profilePicture.png" />
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
<div class="nameBox">
|
|
<div class="nameBox">
|
|
<div class="name">{{ item.student_name || "未检录" }}</div>
|
|
<div class="name">{{ item.student_name || "未检录" }}</div>
|
|
</div>
|
|
</div>
|
|
@@ -113,12 +117,13 @@
|
|
<script setup name="TrainTest" lang="ts">
|
|
<script setup name="TrainTest" lang="ts">
|
|
import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
|
|
import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
|
|
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 { handWs } from '@/utils/handController'
|
|
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 { Swiper, SwiperSlide } from 'swiper/vue';
|
|
-import { Grid } from 'swiper/modules';
|
|
|
|
|
|
+import { Navigation } from 'swiper/modules';
|
|
import 'swiper/css';
|
|
import 'swiper/css';
|
|
-import 'swiper/css/grid';
|
|
|
|
|
|
+import 'swiper/scss/navigation';
|
|
const { proxy } = getCurrentInstance() as any;
|
|
const { proxy } = getCurrentInstance() as any;
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
@@ -141,8 +146,9 @@ const data = reactive<any>({
|
|
showTestAgain: false,//再测一次按钮
|
|
showTestAgain: false,//再测一次按钮
|
|
isLongRun: false,//是否为长跑项目
|
|
isLongRun: false,//是否为长跑项目
|
|
isBackRun: false,//是否为折返跑项目
|
|
isBackRun: false,//是否为折返跑项目
|
|
|
|
+ exit: 0,//退出响应次数
|
|
});
|
|
});
|
|
-const { timerManager, parameter, time, userInfo, examState, resultId, faceStudentList, currentTrack, unit, needStart, showTestAgain, isLongRun, isBackRun } = toRefs(data);
|
|
|
|
|
|
+const { timerManager, parameter, time, userInfo, examState, resultId, faceStudentList, currentTrack, unit, needStart, showTestAgain, isLongRun, isBackRun, exit } = toRefs(data);
|
|
|
|
|
|
/**
|
|
/**
|
|
* 接收消息
|
|
* 接收消息
|
|
@@ -766,6 +772,69 @@ const faceStudentListLongRun: any = computed(() => {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * 加载手势WS
|
|
|
|
+*/
|
|
|
|
+const initHand = () => {
|
|
|
|
+ handWs((e: any) => {
|
|
|
|
+ //左滑动
|
|
|
|
+ if (e.data.result == "next_item") {
|
|
|
|
+ }
|
|
|
|
+ //举左手
|
|
|
|
+ if (e.data.result == "left_hand") {
|
|
|
|
+ getStartOneTest();
|
|
|
|
+ }
|
|
|
|
+ //退出
|
|
|
|
+ if (e.data.result == "exit") {
|
|
|
|
+ // console.log("exit.value", exit.value)
|
|
|
|
+ if (exit.value == 0) {
|
|
|
|
+ console
|
|
|
|
+ //第一次才弹出
|
|
|
|
+ confirmExit();
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ let keyEvent = null;
|
|
|
|
+ let myKey = null;
|
|
|
|
+ //如果交叉手两秒后返回超过4次就确认退出
|
|
|
|
+ if (exit.value >= 4) {
|
|
|
|
+ myKey = 'Enter';
|
|
|
|
+ } else {
|
|
|
|
+ myKey = 'Esc';
|
|
|
|
+ exit.value = 0;
|
|
|
|
+ }
|
|
|
|
+ if (myKey == 'Esc') {
|
|
|
|
+ keyEvent = new KeyboardEvent('keydown', {
|
|
|
|
+ key: 'Escape', // 键值
|
|
|
|
+ code: 'Escape', // 键盘代码
|
|
|
|
+ keyCode: 27, // 旧的键盘代码
|
|
|
|
+ which: 27, // 新的键盘代码
|
|
|
|
+ shiftKey: false, // 是否按下Shift键
|
|
|
|
+ ctrlKey: false, // 是否按下Ctrl键
|
|
|
|
+ metaKey: false, // 是否按下Meta键(Win键或Command键)
|
|
|
|
+ bubbles: true, // 事件是否冒泡
|
|
|
|
+ cancelable: true // 是否可以取消事件的默认行为
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ if (myKey == 'Enter') {
|
|
|
|
+ keyEvent = new KeyboardEvent('keydown', {
|
|
|
|
+ key: 'Enter', // 键值
|
|
|
|
+ code: 'Enter', // 键盘代码
|
|
|
|
+ keyCode: 13, // 旧的键盘代码
|
|
|
|
+ which: 13, // 新的键盘代码
|
|
|
|
+ shiftKey: false, // 是否按下Shift键
|
|
|
|
+ ctrlKey: false, // 是否按下Ctrl键
|
|
|
|
+ metaKey: false, // 是否按下Meta键(Win键或Command键)
|
|
|
|
+ bubbles: true, // 事件是否冒泡
|
|
|
|
+ cancelable: true // 是否可以取消事件的默认行为
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ document.activeElement.dispatchEvent(keyEvent);
|
|
|
|
+ }, 2500)
|
|
|
|
+ }
|
|
|
|
+ exit.value = exit.value + 1
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+
|
|
onBeforeMount(() => {
|
|
onBeforeMount(() => {
|
|
parameter.value = route.query;
|
|
parameter.value = route.query;
|
|
let project = parameter.value.project;
|
|
let project = parameter.value.project;
|
|
@@ -799,7 +868,10 @@ onBeforeMount(() => {
|
|
initWs({ parameter: parameter.value, testTime: time.value.testTime }, (data: any) => {
|
|
initWs({ parameter: parameter.value, testTime: time.value.testTime }, (data: any) => {
|
|
getMessage(data);
|
|
getMessage(data);
|
|
});
|
|
});
|
|
|
|
+ //初始化语音
|
|
initSpeech();
|
|
initSpeech();
|
|
|
|
+ //初始化手势
|
|
|
|
+ initHand();
|
|
})
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
onUnmounted(() => {
|
|
@@ -1027,6 +1099,26 @@ $waiPadding: 6.51rem;
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ .swiper-btn {
|
|
|
|
+ width: 2.5rem;
|
|
|
|
+ height: 2.5rem;
|
|
|
|
+ display: block;
|
|
|
|
+
|
|
|
|
+ &::after {
|
|
|
|
+ display: none;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .swiper-btn-left {
|
|
|
|
+ background: url("@/assets/images/ranking/btn-left.png") left center no-repeat;
|
|
|
|
+ background-size: 100% 100%;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .swiper-btn-right {
|
|
|
|
+ background: url("@/assets/images/ranking/btn-right.png") left center no-repeat;
|
|
|
|
+ background-size: 100% 100%;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
.footerBtn {
|
|
.footerBtn {
|