林旭祥 9 місяців тому
батько
коміт
10a5eaeaac

+ 0 - 0
src/assets/images/common/screen.png → src/assets/images/common/screen1.png


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


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


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


+ 213 - 0
src/assets/styles/index.scss

@@ -31,3 +31,216 @@ ol {
 ul li {
   list-style: none;
 }
+
+.sports {
+  .el-loading-spinner {
+    &::before {
+      content: '';
+      width: 120px;
+      height: 120px;
+      display: block;
+      margin: 0 auto;
+      background-repeat: no-repeat;
+      background-position: center center;
+      background-size: contain;
+    }
+    .circular {
+      display: none;
+    }
+  }
+}
+
+.basketballv1 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/basketballv1.png');
+    }
+  }
+}
+.footballv1 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/footballv1.png');
+    }
+  }
+}
+.heartbeat {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/heartbeat.png');
+    }
+  }
+}
+.jump {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/jump.png');
+    }
+  }
+}
+.jumpingjack {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/jumpingjack.png');
+    }
+  }
+}
+.jumprope {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/jumprope.png');
+    }
+  }
+}
+
+.longjump {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/longjump.png');
+    }
+  }
+}
+
+.pullup {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/pullup.png');
+    }
+  }
+}
+
+.run10x4 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run10x4.png');
+    }
+  }
+}
+
+.run15x4 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run15x4.png');
+    }
+  }
+}
+
+.run50 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run50.png');
+    }
+  }
+}
+
+.run50x8 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run50x8.png');
+    }
+  }
+}
+
+.run100 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run100.png');
+    }
+  }
+}
+
+.run200 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run200.png');
+    }
+  }
+}
+
+.run400 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run400.png');
+    }
+  }
+}
+
+.run800 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run800.png');
+    }
+  }
+}
+
+.run1000 {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/run1000.png');
+    }
+  }
+}
+
+.shotput {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/shotput.png');
+    }
+  }
+}
+
+.sidepullup {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/sidepullup.png');
+    }
+  }
+}
+
+.situp {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/situp.png');
+    }
+  }
+}
+
+.skiprope {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/skiprope.png');
+    }
+  }
+}
+
+.solidball {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/solidball.png');
+    }
+  }
+}
+
+.trijump {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/trijump.png');
+    }
+  }
+}
+
+.verticaljump {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/verticaljump.png');
+    }
+  }
+}
+
+.volleyball {
+  .el-loading-spinner {
+    &::before {
+      background-image: url('/src/assets/images/train/volleyball.png');
+    }
+  }
+}

+ 1 - 1
src/components/ChooseStudent/index.vue

@@ -196,7 +196,7 @@ defineExpose({
   optionWindow
 })
 </script>
-<style lang="scss">
+<style lang="scss" scoped>
 .mask {
   position: fixed;
   height: 100vh;

+ 32 - 15
src/components/Header/index.vue

@@ -2,8 +2,8 @@
   <div class="close" @click="confirmExit"></div>
   <div class="toolList">
     <div class="li">{{ date }}</div>
-    <div class="li btn speck" @click="speckCancel"></div>
-    <div class="li btn screen" @click="getFullScreen"></div>
+    <div class="li btn speck" :class="{ 'on': voice, 'off': !voice }" @click="getVoice"></div>
+    <div class="li btn screen" :class="{ 'on': screen, 'off': !screen }" @click="getFullScreen"></div>
   </div>
   <div class="logo"> <img src="@/assets/images/logo.png">
     </img>
@@ -22,8 +22,10 @@ const data = reactive<any>({
   timerManager: {},//计时器管理
   parameter: {},//参数
   date: "",//当前时间
+  voice: true,
+  screen: true
 });
-const { timerManager, parameter, date } = toRefs(data);
+const { timerManager, parameter, date, voice, screen } = toRefs(data);
 
 /**
  * 更新时间
@@ -36,13 +38,21 @@ const setDate = () => {
 /**
  * 屏幕模式
 */
-const getFullScreen = () => {
-  date.value = proxy?.$utils.fullScreen();
+const getVoice = () => {
+  voice.value = !voice.value;
 };
 
 /**
  * 屏幕模式
 */
+const getFullScreen = () => {
+  screen.value = !screen.value;
+  proxy?.$utils.fullScreen();
+};
+
+/**
+ * 确定退出
+*/
 const confirmExit = () => {
   emit('confirmExit', {});
 };
@@ -50,14 +60,6 @@ const confirmExit = () => {
 onBeforeMount(() => {
   setDate();
   parameter.value = route.query;
-  let project = parameter.value.project;
-  let area = parameter.value.area;
-  parameter.value.examId = `${project}_${area}`; //项目+区
-  if (parameter.value.gesture == 'true') {
-    parameter.value.gesture = true
-  } else {
-    parameter.value.gesture = false
-  }
   initSpeech();
 })
 </script>
@@ -147,17 +149,32 @@ $waiPadding: 6.51rem;
   }
 
   .speck {
-    background-image: url("@/assets/images/common/speck.png");
+
     background-position: center;
     background-repeat: no-repeat;
     background-size: 100% auto;
   }
 
+  .speck.on {
+    background-image: url("@/assets/images/common/speck1.png");
+  }
+
+  .speck.off {
+    background-image: url("@/assets/images/common/speck2.png");
+  }
+
   .screen {
-    background-image: url("@/assets/images/common/screen.png");
     background-position: center;
     background-repeat: no-repeat;
     background-size: 100% auto;
   }
+
+  .screen.on {
+    background-image: url("@/assets/images/common/screen1.png");
+  }
+
+  .screen.off {
+    background-image: url("@/assets/images/common/screen2.png");
+  }
 }
 </style>

+ 69 - 17
src/components/MultipleItem/index.vue

@@ -8,15 +8,20 @@
         <div class="pic" :class="{ 'pic2': faceCheckStu.student_id }" v-if="faceCheckStu.student_id"> <img
             :src="faceCheckStu.face_pic || faceCheckStu.logo_url" /></div>
         <div class="pic" v-else>
-          <div>{{ area }}</div>
-          <img src="@/assets/images/test/profilePicture.png" />
+          <div class="area">{{ area }}</div>
+          <img src="@/assets/images/test/profilePicture2.png" />
         </div>
         <div class="name" :class="{ 'name2': faceCheckStu.student_id }">
-          {{ faceCheckStu.student_id ? faceCheckStu.name : "虚以待" }}
+          {{ faceCheckStu.student_id ? faceCheckStu.name : "虚以待" }}
         </div>
       </div>
     </div>
-    <div class="score" v-if="resultId && faceCheckStu.student_id">{{ currentResultObj.count || 0 }}</div>
+    <div class="score" v-if="faceCheckStu.student_id || [43, 42].includes(props.examState)">
+
+      <i></i>
+      {{ currentResultObj.count
+        || 0 }}
+    </div>
     <div class="ready" v-if="[2].includes(itemNumber) && examState == 41"><img src="@/assets/images/test/ready3.png" />
     </div>
     <!-- <div>当前状态:({{ examState == 3 ? "初始化完成" : examState == 40 ? "创建测试" : examState == 41 ? "正在人脸识别" :examState == 43 ? "停止人脸识别" : examState == 42 ? "正在测试" : "离线状态" }})</div> -->
@@ -91,11 +96,11 @@ const getMessage = (e: any) => {
   }
   //错误提示
   if (e.cmd === 'info_result') {
-    proxy?.$modal.msgError(e.data.message);
+    proxy?.$modal.msgError(`【${area}】${e.data.message}`);
   }
   //错误提示
   if (e.cmd === 'error_result') {
-    proxy?.$modal.msgError(e.data.message);
+    proxy?.$modal.msgError(`【${area}】${e.data.message}`);
   }
   //测试中违规提示
   if (e.cmd === 'warning_notify') {
@@ -105,8 +110,10 @@ const getMessage = (e: any) => {
   if (e.cmd === 'disconnect_request') {
     examState.value = 0;
     emit('returnData', { examState: examState.value, area: area });
-    if (e.data.message) {
-      speckText(e.data.message);
+    let message = e.data.message;
+    if (message) {
+      proxy?.$modal.msgError(`【${area}】${message}`);
+      //speckText(e.data.message);
     }
   }
   //状态变更
@@ -252,6 +259,11 @@ const getAgain = async () => {
  * 选择学生
 */
 const getChooseStudent = () => {
+  if (props.examState == 42) {
+    proxy?.$modal.msgWarning(`【${area}】正在测试请结束后再操作`);
+    return false;
+  }
+
   if (examState.value == 41) {
     chooseStudentRef.value.open();
   }
@@ -292,7 +304,7 @@ const initProject = () => {
     }
     setTimeout(() => {
       //再加一个判断以免和再测一次冲突
-      if (examState.value == 3) {
+      if (examState.value == 3 || examState.value == 43) {
         getOpenOneTestAndStartFace();
       }
     }, time)
@@ -411,6 +423,15 @@ watch(() => faceCheckStu.value, (newVal, oldVal) => {
   emit('returnData', { faceCheckStu: faceCheckStu.value, area: area });
 }, { deep: true });
 
+/**
+ * 如果结束了仍然在43就重新执行一次
+*/
+watch(() => props.examState, (newVal, oldVal) => {
+  if (newVal == 3 && examState.value == 43) {
+    initProject();
+  }
+}, { deep: true });
+
 onMounted(() => {
   let dic: any = dataDictionary;
   unit.value = dic.unit[project];
@@ -430,7 +451,7 @@ defineExpose({
 .top-left {
   width: 100%;
   height: 100%;
-  border-radius: 29px;
+  border-radius: 1.6rem;
   background: radial-gradient(122% 126% at 97% 6%, #35FFC6 0%, #00FFE8 100%);
   text-align: center;
   display: flex;
@@ -441,14 +462,26 @@ defineExpose({
 
   .top-left-center {
     .pic {
-      width: 12vw;
-      height: 12vw;
+      width: 21vh;
+      height: 21vh;
       border-radius: 50%;
       display: flex;
       justify-content: center;
       align-items: center;
       overflow: hidden;
       margin: 0 auto 2vh auto;
+      position: relative;
+
+      .area {
+        position: absolute;
+        top: 6vh;
+        color: #203C52;
+        font-size: 5.2vh;
+        line-height: 1;
+        font-family: 'Saira-ExtraBold';
+        text-align: center;
+
+      }
 
       img {
         width: 100%;
@@ -478,15 +511,34 @@ defineExpose({
 }
 
 .score {
-  font-size: 8.5rem;
-  line-height: 12vw;
+  height: 18vh;
+  line-height: 18vh;
+  font-size: 12vh;
   font-family: 'Saira-BlackItalic';
   background: #ffffff;
   box-sizing: border-box;
-  border: 10px solid #13ED84;
-  height: 12vw;
+  border: 0.55rem solid #13ED84;
   text-align: center;
-  border-radius: 29px;
+  border-radius: 1.6rem;
   box-sizing: content-box;
+  color: #1A293A;
+  position: relative;
+
+  i {
+    width: 2vw;
+    height: 2vw;
+    display: block;
+    position: absolute;
+    top: -1.5vw;
+    left: 50%;
+    margin-left: -1vw;
+    background-image: url("@/assets/images/home/test_icon.png");
+    background-position: center;
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+    border-radius: 50%;
+    flex-shrink: 0;
+    transition: all 0.5s;
+  }
 }
 </style>

+ 3 - 7
src/utils/ws.ts

@@ -15,7 +15,7 @@ let testList: any = []; //区列表
 let wkList: any = []; //工作站列表
 
 export const initWs = (data: any, callback: any) => {
-  loading = ElLoading.service({ text: '正在初始化,请稍候', background: 'rgba(0, 0, 0, 0.7)' });
+  loading = ElLoading.service({ text: '正在初始化,请稍候', background: 'rgba(0, 0, 0, 0.8)', customClass: `sports ${data.parameter.project}` });
   parameter = data.parameter;
   testTime = data.testTime;
   version = data.version || '';
@@ -108,13 +108,9 @@ export const initWs = (data: any, callback: any) => {
     }
     //断线状态
     if (e.cmd === 'disconnect_request') {
-      let message = e.data.message;
-      if (message) {
-        ElMessage({ message: message, type: 'error', duration: 5 * 1000 });
-      }
-      let examId = e?.exam_id || '';
       if (testList.length == 1) {
         getExit();
+        //let examId = e?.exam_id || '';
         //getExit(examId);
       }
     }
@@ -449,7 +445,7 @@ export const resumeFaceRecognitionChannels = (data: any) => {
  * 心跳
  */
 export const getNetWork = (data: any, callback?: any) => {
-  timerManager.beat = setInterval(() => {
+  timerManager[data] = setInterval(() => {
     let obj = wkList.find((item: any) => {
       return item.examId == data;
     });

+ 213 - 59
src/views/train/multiple.vue

@@ -5,28 +5,46 @@
       <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>
+          }}</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>
-        <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 class="testBox" :class="{ 'overlap': ![0, 3, 40, 41].includes(examState) }">
+        <div class="row" 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"
+            :itemNumber="item.itemNumber" @returnData="returnData" :examState="examState" :needStart="needStart" />
         </div>
       </div>
     </div>
+    <div class="footerBtn">
+      <template v-if="needStart">
+        <div @click="getAgain" v-if="examState == 42 || showTestAgain">再测一次</div>
+        <div @click="getOpenOneTestAndStartFace" v-if="examState < 41">开始识别</div>
+        <div @click="getStopFace" v-if="examState == 41">停止人脸识别</div>
+        <div @click="getStartOneTest" v-if="examState == 43">开始测试</div>
+      </template>
+      <template v-else>
+        <div @click="getReady" v-if="examState == 43" class="startBtn">开始测试</div>
+      </template>
+    </div>
+    <!--倒计时开始-->
+    <div>
+      <transition :enter-active-class="proxy?.animate.mask.enter" :leave-active-class="proxy?.animate.mask.leave">
+        <div class="mask" v-show="examState == 43 && time.ready"></div>
+      </transition>
+      <transition :enter-active-class="proxy?.animate.face.enter" :leave-active-class="proxy?.animate.face.leave2">
+        <div class="confirmDiaBg" v-show="examState == 43 && time.ready">
+          <div class="confirmDiaWindow">
+            <div class="confirmDiaWindow-con">
+              <div class="readyBox">
+                <div class="value">{{ time.ready }}</div>
+                <div class="lable">倒计时</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </transition>
+    </div>
+    <!--倒计时结束-->
   </div>
 </template>
 
@@ -57,7 +75,7 @@ const { timerManager, parameter, time, userInfo, examState, needStart, showTestA
  * 创建组件实例
 */
 const multipleItemRef = (el: any, index: number, area: any) => {
-  multipleItemRefList.value[index] = el;
+  multipleItemRefList.value[index - 1] = el;
 }
 
 /**
@@ -338,6 +356,12 @@ const returnData = (data: any) => {
 const getReady = () => {
   //停止播报;
   speckCancel()
+  //正在识别的停止识别
+  for (let i = 0; i < multipleItemRefList.value.length; i++) {
+    if (testList.value[i].examState == 41) {
+      multipleItemRefList.value[i].getStopFace()
+    }
+  }
   time.value.ready = 5;
   speckText(time.value.ready);
   timerManager.value.readyTimer = setInterval(() => {
@@ -351,6 +375,24 @@ const getReady = () => {
   }, 1000);
 };
 
+/**
+ * 将测试列表转为多行
+*/
+const testListArr = computed(() => {
+  let list: any = [];
+  let num = 3;
+  let myLength = Math.ceil(testList.value.length / num);
+  for (let i = 0; i < myLength; i++) {
+    list[i] = [];
+    for (let j = 0; j < testList.value.length; j++) {
+      if (j >= i * num && j < (i + 1) * num) {
+        list[i].push(testList.value[j])
+      }
+    }
+  }
+  return list;
+});
+
 onMounted(() => {
   parameter.value = route.query;
   let project = parameter.value.project;
@@ -367,9 +409,10 @@ onMounted(() => {
   } else {
     parameter.value.gesture = false
   }
-  testList.value = parameter.value.area.split(',').map((item: any) => {
+  testList.value = parameter.value.area.split(',').map((item: any, index: number) => {
     let obj = {
-      area: item
+      area: item,
+      itemNumber: index + 1
     }
     return obj;
   });
@@ -387,11 +430,11 @@ onMounted(() => {
   });
   initSpeech();
   setTimeout(() => {
-    //30秒还在0状态就算超时
+    //10秒还在0状态就算超时
     if (examState.value == 0) {
       getExit();
     }
-  }, 30000);
+  }, 10000);
 })
 
 onUnmounted(() => {
@@ -405,7 +448,7 @@ $waiPadding: 6.51rem;
 
 .main {
   width: calc(100% - ($waiPadding * 2));
-  height: 78vh;
+  height: 76vh;
   padding-top: 10rem;
   margin: 0 auto;
   display: flex;
@@ -427,72 +470,183 @@ $waiPadding: 6.51rem;
     position: absolute;
     right: 50%;
     top: 0;
-    margin-right: -28vh;
+    margin-right: -24vw;
     font-family: 'Saira-BlackItalic';
   }
 }
+
+.footerBtn {
+  width: 100%;
+  padding: 0 calc(13.02rem /2);
+  box-sizing: border-box;
+  position: fixed;
+  bottom: 3vh;
+  display: flex;
+  justify-content: end;
+}
 </style>
 <style lang="scss">
 $topPadding: 5.19rem;
 $waiPadding: 6.51rem;
 
-.box {
+.testBox {
   display: flex;
   flex-wrap: wrap;
-  justify-content: center;
+  align-items: center;
 
-  $listWidth: calc((100% - ($waiPadding * 2)) /5);
-  $listMargin: 4vw;
 
-  .list {
-    width: $listWidth;
-    position: relative;
 
-    .ready {
-      position: absolute;
+  .row {
+    width: 100%;
+    height: 35vh;
+    display: flex;
+    $listMargin: 10vw;
+    $listWidth: calc((100% - $listMargin) / 5);
 
-      img {
-        width: 100%;
-      }
-    }
-
-    &:nth-child(2) {
-      margin-left: calc($listWidth + $listMargin);
-      margin-right: calc($listWidth + $listMargin);
+    .list {
+      width: $listWidth;
+      position: relative;
 
+      .ready {
+        position: absolute;
 
-      .ready {}
+        img {
+          width: 100%;
+        }
+      }
     }
 
-    &:nth-child(4) {
-      margin-left: calc(($listWidth + $listMargin) /2);
-      margin-right: calc(($listWidth + $listMargin) /2);
+    &:nth-child(1) {
+      justify-content: space-between;
+    }
 
-      .ready {
+    &:nth-child(2) {
+      justify-content: space-evenly;
 
-        top: -100%;
+      .list {
+        margin-left: calc($listMargin/4);
+        margin-right: calc($listMargin/4);
       }
     }
+  }
 
-    &:nth-child(5) {
-      margin-left: calc(($listWidth + $listMargin) /2);
-      margin-right: calc(($listWidth + $listMargin) /2);
+}
 
-      .ready {
-        top: -100%;
-      }
-    }
+.overlap {
+  .row {
+    transition: all 0.5s;
 
+    &:nth-child(1) {
+      margin-top: 5vh;
+    }
 
+    &:nth-child(2) {
+      margin-top: -21vh;
+    }
   }
 }
 
 .startBtn {
-  width: 200px;
-  height: 2rem;
-  font-size: 2rem;
-  border-radius: 15px;
+  width: 14.6vw;
+  height: 6.1vh;
+  line-height: 6.1vh;
+  font-size: 3vh;
+  color: #1A293A;
+  text-align: center;
+  border-radius: 1vh;
+  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;
+  }
+}
+
+.mask {
+  position: fixed;
+  height: 100vh;
+  width: 100vw;
+  top: 0;
+  left: 0;
+  background: rgba(0, 0, 0, 0.3);
+  z-index: 998;
+}
+
+.confirmDiaBg {
+  width: 100%;
+  height: 100vh;
+  position: fixed;
+  left: 0;
+  top: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 999;
+
+  .confirmDiaWindow {
+    width: 23.5%;
+    height: 43.4%;
+    border-radius: 29px;
+    opacity: 1;
+    background: radial-gradient(122% 126% at 97% 6%, #35FFC6 0%, #00FFE8 100%);
+    text-align: center;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    position: fixed;
+
+    .confirmDiaWindow-con {
+      .pic {
+        width: 22.3vh;
+        height: 22.3vh;
+        border-radius: 50%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        overflow: hidden;
+        position: relative;
+        margin: 0 auto 2vh auto;
+
+        .shine {
+          position: absolute;
+          left: -5vh;
+          top: 0;
+          width: 5vh;
+          height: 22.3vh;
+          animation: shineani 3s infinite;
+          -webkit-animation: shineani 3s infinite;
+          z-index: 1;
+
+          img {
+            width: 100%;
+            height: 100%;
+          }
+        }
+
+        img {
+          width: 100%;
+        }
+      }
+
+      .pic2 {
+        box-sizing: border-box;
+        border: 0.44rem solid rgba(26, 41, 58, 0.6315);
+      }
+
+      .name {
+        width: 100%;
+        color: #1A293A;
+        font-size: 2.21rem;
+      }
+
+      .name2 {
+        padding: 0 0.3rem;
+        border-radius: 1.1rem;
+        background: radial-gradient(96% 96% at 2% 32%, #FFFFFF 0%, #FCFDFD 54%, #E1E4E7 100%);
+        box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.9046), inset 0px 3px 6px 0px rgba(0, 0, 0, 0.0851);
+      }
+    }
+  }
 }
 </style>

+ 7 - 5
src/views/train/test.vue

@@ -12,7 +12,7 @@
                 <img src="@/assets/images/test/profilePicture.png" />
               </div>
               <div class="name" :class="{ 'name2': faceCheckStu.student_id }">
-                {{ faceCheckStu.student_id ? faceCheckStu.name : "虚以待" }}
+                {{ faceCheckStu.student_id ? faceCheckStu.name : "虚以待" }}
               </div>
             </div>
           </div>
@@ -200,8 +200,10 @@ const getMessage = (e: any) => {
   }
   //断线状态
   if (e.cmd === 'disconnect_request') {
-    if (e.data.message) {
-      speckText(e.data.message);
+    let message = e.data.message;
+    if (message) {
+      proxy?.$modal.msgError(`${message}`);
+      speckText(message);
     }
     getExit();
   }
@@ -326,7 +328,7 @@ const getStartOneTest = () => {
     return false;
   }
   if (!faceCheckStu.value.student_id) {
-    proxy?.$modal.msgError("请选择人员!");
+    proxy?.$modal.msgWarning("请选择人员!");
     return false;
   }
   startOneTest(data == null, () => {
@@ -795,7 +797,7 @@ $waiPadding: 6.51rem;
       }
 
       .top-right {
-        width: 25vw;
+        width: 62%;
         height: 100%;
         border-radius: 29px;
         opacity: 1;