林旭祥 8 ヶ月 前
コミット
78917a0805

BIN
src/assets/images/common/screen1.png


BIN
src/assets/images/common/speck1.png


BIN
src/assets/images/common/speck2.png


BIN
src/assets/images/test/ready3.png


BIN
src/assets/images/test/ready4.png


+ 23 - 9
src/components/Header/index.vue

@@ -10,14 +10,14 @@
       <img src="@/assets/images/ranking/ranking.png" />
     </div>
     <div class="logo" :class="{ logo2: logoClass == 'logo2' }" v-else>
-      <img v-if="userInfo.avatar_url" :src="userInfo.avatar_url" />
+      <img v-if="userInfo?.avatar_url" :src="userInfo.avatar_url" />
       <img v-else src="@/assets/images/logo.png" />
       <div class="title" v-if="parameter.project"><i></i><span>{{ dic.project[parameter.project] || "" }}</span></div>
     </div>
   </div>
 </template>
 <script setup lang="ts">
-import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
+import { initSpeech, speckText, playMusic, controlMusic, speckCancel, chineseNumber } from '@/utils/speech'
 import dataDictionary from "@/utils/dataDictionary"
 const { proxy } = getCurrentInstance() as any;
 const emit = defineEmits(['confirmExit']);
@@ -69,11 +69,12 @@ const setDate = () => {
 };
 
 /**
- * 屏幕模式
+ * 声音控制
 */
 const getVoice = () => {
   voice.value = !voice.value;
   localStorage.setItem("voice", voice.value);
+  controlMusic();
 };
 
 /**
@@ -95,12 +96,23 @@ const confirmExit = () => {
 onBeforeMount(() => {
   setDate();
   parameter.value = route.query;
-  initSpeech();
-
-  let voiceData = localStorage.getItem("voice");
-  voice.value = voiceData;
+  //initSpeech();
+  //音控
+  let voiceData: any = localStorage.getItem("voice");
+  if (voiceData != undefined && voiceData == 'false') {
+    voice.value = false;
+    speckCancel()
+  } else {
+    voice.value = true;
+  }
+  //屏幕
   let screenData = localStorage.getItem("screen");
-  screen.value = screenData;
+  if (screenData != undefined && screenData == 'false') {
+    screen.value = false;
+  } else {
+    screen.value = true;
+  }
+  //用户信息
   userInfo.value = JSON.parse(myInfo);
 })
 </script>
@@ -196,6 +208,7 @@ $waiPadding: 6.51rem;
   color: #00FFE8;
   font-size: 1.1rem;
   display: flex;
+  align-items: center;
 
   .li {
     margin-right: 3rem;
@@ -210,7 +223,8 @@ $waiPadding: 6.51rem;
   }
 
   .speck {
-
+    width: 1.5rem;
+    height: 1.5rem;
     background-position: center;
     background-repeat: no-repeat;
     background-size: 100% auto;

+ 9 - 6
src/components/MultipleItem/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="li">
+  <div class="li" :class="{ 'disable': !area }">
     <div class="userInfo" @click="getChooseStudent">
       <div class="userInfo-center">
         <Transition :enter-active-class="proxy?.animate.dialog.enter">
@@ -25,7 +25,7 @@
 </template>
 
 <script setup lang="ts">
-import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
+import { initSpeech, speckText, playMusic, controlMusic, speckCancel, chineseNumber } from '@/utils/speech'
 import { openOneTest, startFace, stopFace, faceConfirmOnly, startOneTest, finishOneTest, closeOneTest, suspendFaceRecognitionChannels, resumeFaceRecognitionChannels } from '@/utils/ws'
 import dataDictionary from "@/utils/dataDictionary"
 const route = useRoute();
@@ -169,10 +169,13 @@ const getOpenOneTestAndStartFace = async () => {
  * 停止人脸识别
 */
 const getStopFace = async () => {
-  if (examState.value != 41) {
-    return false;
+  // 旧版识别成功直接43了这里先屏蔽
+  // if (examState.value != 41) {
+  //   return false;
+  // }
+  if (examState.value == 41) {
+    await stopFace(examId);
   }
-  await stopFace(examId);
   if (faceCheckStu.value.student_id) {
     getFaceConfirmOnly();
   }
@@ -314,7 +317,7 @@ const initProject = () => {
     if (!faceCheckStu.value.student_id) {
       time = 500;
     } else {
-      time = 7000;
+      time = 8000;
     }
     setTimeout(() => {
       //再加一个判断以免和再测一次冲突

+ 29 - 0
src/utils/speech.ts

@@ -2,6 +2,7 @@ import Speech from 'speak-tts';
 import http from '@/api';
 let speech: any = null;
 let myAudio: any = null;
+let myMusic: any = null;
 let browserSupport: boolean = false;
 let speechText: string = '';
 
@@ -43,6 +44,11 @@ export const initSpeech = () => {
 //播放语音
 export const speckText = (text: any) => {
   //console.log('text', text);
+  //静音
+  let voiceData: any = localStorage.getItem('voice');
+  if (voiceData != undefined && voiceData == 'false') {
+    return false;
+  }
   console.log('speechText', speechText);
   if (speechText == text) {
     return false;
@@ -122,6 +128,18 @@ export const speckText = (text: any) => {
   }
 };
 
+//播放音乐
+export const playMusic = (url: any) => {
+  let state = true;
+  let voiceData: any = localStorage.getItem('voice');
+  if (voiceData != undefined && voiceData == 'false') {
+    state = false;
+  }
+  myMusic = new Audio(url);
+  myMusic.muted = state ? false : true;
+  myMusic.play();
+};
+
 //取消播放
 export const speckCancel = () => {
   if (speech && browserSupport == true) {
@@ -129,6 +147,17 @@ export const speckCancel = () => {
   } else {
     myAudio?.pause();
   }
+  myMusic?.pause();
+};
+
+//控制音乐
+export const controlMusic = () => {
+  let state = true;
+  let voiceData: any = localStorage.getItem('voice');
+  if (voiceData != undefined && voiceData == 'false') {
+    state = false;
+  }
+  myMusic.muted = state ? false : true;
 };
 
 //小数播报格式

+ 40 - 2
src/views/train/multiple.vue

@@ -11,7 +11,7 @@
       <div class="testBox"
         :class="{ 'testBox1': styleType == 1, 'testBox2': styleType == 2, 'testBox3': styleType == 3 }">
         <div class="ul"
-          :class="{ 'overlap': (examState == 43 && time.ready) || [42].includes(examState) || (showTestAgain && ![41].includes(examState)), 'ready': [41].includes(examState) }"
+          :class="{ 'overlap': (examState == 43 && time.ready) || [42].includes(examState) || (showTestAgain && ![41].includes(examState)), 'ready': [41].includes(examState), 'hands': parameter.gesture }"
           v-for="(items, indexs) in testListArr " :key="indexs">
           <MultipleItem :ref="(el: any) => { multipleItemRef(el, item.itemNumber, item.area) }"
             v-for="(item, index) in items" :query="parameter" :area="item.area" :key="index" @returnData="returnData"
@@ -65,7 +65,7 @@
 </template>
 
 <script setup name="Multiple" lang="ts">
-import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
+import { initSpeech, speckText, playMusic, controlMusic, speckCancel, chineseNumber } from '@/utils/speech'
 import { initWs, examEnds, openOneTest, startFace, stopFace, faceConfirmOnly, startOneTest, finishOneTest, closeOneTest, suspendFaceRecognitionChannels, resumeFaceRecognitionChannels } from '@/utils/ws'
 import { handWs } from '@/utils/handController'
 const { proxy } = getCurrentInstance() as any;
@@ -160,6 +160,9 @@ const getStartOneTest = () => {
     }
   }
   speckText("哨声");
+  if (parameter.value.music) {
+    playMusic(parameter.value.music);
+  }
   //显示再测一次按钮
   showTestAgain.value = true;
   //时间为0的为正计时,大于0的为倒计时
@@ -916,6 +919,14 @@ $waiPadding: 6.51rem;
       }
     }
 
+    .disable {
+
+      .userInfo,
+      .score {
+        opacity: 0.5;
+      }
+    }
+
     &:nth-child(1) {
       justify-content: space-between;
     }
@@ -966,6 +977,25 @@ $waiPadding: 6.51rem;
     }
   }
 
+  .hands.ul {
+
+    &:nth-child(1) {
+      .li:nth-child(2) {
+        &::after {
+          background-image: url("@/assets/images/test/ready4.png");
+        }
+      }
+    }
+
+    &:nth-child(2) {
+      .li {
+        &::after {
+          background-image: url("@/assets/images/test/ready4.png");
+        }
+      }
+    }
+  }
+
   .overlap.ul {
     transition: all 0.5s;
 
@@ -1116,6 +1146,10 @@ $waiPadding: 6.51rem;
         }
       }
     }
+
+    .disable {
+      opacity: 0.5;
+    }
   }
 
   .overlap {
@@ -1272,6 +1306,10 @@ $waiPadding: 6.51rem;
         line-height: 1;
       }
     }
+
+    .disable {
+      opacity: 0.5;
+    }
   }
 }
 </style>

+ 2 - 2
src/views/train/run.vue

@@ -4,7 +4,7 @@
     <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>
+      }}</div>
     </Transition>
     <div class="main">
       <template v-if="isLongRun">
@@ -115,7 +115,7 @@
 </template>
 
 <script setup name="TrainTest" lang="ts">
-import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
+import { initSpeech, speckText, playMusic, controlMusic, 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"

+ 10 - 4
src/views/train/test.vue

@@ -113,7 +113,7 @@
 </template>
 
 <script setup name="TrainTest" lang="ts">
-import { initSpeech, speckText, speckCancel, chineseNumber } from '@/utils/speech'
+import { initSpeech, speckText, playMusic, controlMusic, speckCancel, chineseNumber } from '@/utils/speech'
 import { initWs, examEnds, openOneTest, startFace, stopFace, faceConfirmOnly, startOneTest, finishOneTest, closeOneTest, suspendFaceRecognitionChannels, resumeFaceRecognitionChannels } from '@/utils/ws'
 import { handWs } from '@/utils/handController'
 import dayjs from 'dayjs'
@@ -258,7 +258,9 @@ const getStopFace = async () => {
     let txt = parameter.value.gesture === true ? ",请举左手开始测试" : ",请准备";
     speckText(faceCheckStu.value.name + txt);
   }
-  await stopFace();
+  if (examState.value == 41) {
+    await stopFace();
+  }
   if (faceCheckStu.value.student_id) {
     getFaceConfirmOnly();
   }
@@ -324,6 +326,9 @@ const getStartOneTest = () => {
     //计时项目才开
     if (needStart.value == true) {
       speckText("哨声");
+      if (parameter.value.music) {
+        playMusic(parameter.value.music);
+      }
       //时间为0的为正计时,大于0的为倒计时
       if (time.value.testTime == 0) {
         getCounting("+");
@@ -419,6 +424,7 @@ const getChooseStudent = () => {
  * 返回被选学生
 */
 const returnStudent = (data: any) => {
+  speckCancel();
   chooseStudentRef.value.close();
   faceCheckStu.value = data;
   faceWindowRef.value.open();
@@ -667,7 +673,7 @@ const initHand = () => {
         //第一次才弹出
         confirmExit();
         setTimeout(() => {
-          let keyEvent = null;
+          let keyEvent: any = null;
           let myKey = null;
           //如果交叉手两秒后返回超过4次就确认退出
           if (exit.value >= 4) {
@@ -702,7 +708,7 @@ const initHand = () => {
               cancelable: true // 是否可以取消事件的默认行为
             });
           }
-          document.activeElement.dispatchEvent(keyEvent);
+          document.activeElement?.dispatchEvent(keyEvent);
         }, 2500)
       }
       exit.value = exit.value + 1