소스 검색

日常开发

林旭祥 7 달 전
부모
커밋
e2ee47017b
7개의 변경된 파일411개의 추가작업 그리고 27개의 파일을 삭제
  1. 1 0
      src/router/index.ts
  2. 45 0
      src/utils/deviceWs.ts
  3. 35 22
      src/utils/handWs.ts
  4. 42 3
      src/views/gesture/index.vue
  5. 286 0
      src/views/test/index.vue
  6. 1 1
      src/views/train/multiple.vue
  7. 1 1
      src/views/train/test.vue

+ 1 - 0
src/router/index.ts

@@ -16,6 +16,7 @@ const router = createRouter({
         { path: '/train/test', component: () => import('@/views/train/test.vue') },
         { path: '/train/run', component: () => import('@/views/train/run.vue') },
         { path: '/train/multiple', component: () => import('@/views/train/multiple.vue') },
+        { path: '/test', component: () => import('@/views/test/index.vue') },
         { path: '/set', component: () => import('@/views/set/index.vue') },
         { path: '/set/config', component: () => import('@/views/set/config.vue') },
         { path: '/ranking', component: () => import('@/views/ranking/index.vue') },

+ 45 - 0
src/utils/deviceWs.ts

@@ -0,0 +1,45 @@
+import io from 'socket.io-client';
+const address: any = import.meta.env.VITE_APP_BASE_API;
+const token: any = localStorage.getItem('token');
+let socket: any = {}; //ws实例对象
+
+export const deviceWs = (callback: any) => {
+  socket = io(address + '/', {
+    transports: ['websocket', 'polling'],
+    query: {
+      Authorization: token
+    }
+  });
+  socket.on('connect', (e: any) => {
+    callback(e);
+  });
+  socket.on('my_response', (e: any) => {
+    callback(e);
+  });
+  socket.on('fe_device_init_result', (e: any) => {
+    callback(e);
+  });
+  socket.on('disconnect', (e: any) => {
+    callback(e);
+  });
+};
+
+export const sendMessage = (type: string, data: any, callback?: () => void) => {
+  if (socket.connected) {
+    callback = callback || function () {};
+    socket.emit(type, data, callback);
+  }
+};
+
+/**
+ * 开始连接
+ */
+export const startDevice = (data?: any, callback?: any) => {
+  sendMessage(
+    'fe_device_init',
+    {
+      data: data
+    },
+    () => {}
+  );
+};

+ 35 - 22
src/utils/handController.ts → src/utils/handWs.ts

@@ -11,35 +11,20 @@ export const handWs = (callback: any) => {
     }
   });
   socket.on('connect', (e: any) => {
-    sendMessage(
-      'handcontroller',
-      {
-        hctrl_name: 'handcontroller_2',
-        cmd: 'open_handcontroller'
-      },
-      () => {}
-    );
+    callback(e);
+  });
+  socket.on('my_response', (e: any) => {
+    callback(e);
   });
-
   socket.on('handcontroller_ack', (e: any) => {
     callback(e);
-    if (e.code == 94210) {
-      sendMessage(
-        'handcontroller',
-        {
-          hctrl_name: 'handcontroller_2',
-          cmd: 'terminate_handcontroller'
-        },
-        () => {}
-      );
-    }
   });
-
   socket.on('handcontroller_result', (e: any) => {
     callback(e);
   });
-
-  socket.on('disconnect', (e: any) => {});
+  socket.on('disconnect', (e: any) => {
+    callback(e);
+  });
 };
 
 export const sendMessage = (type: string, data: any, callback?: () => void) => {
@@ -48,3 +33,31 @@ export const sendMessage = (type: string, data: any, callback?: () => void) => {
     socket.emit(type, data, callback);
   }
 };
+
+/**
+ * 开始连接
+ */
+export const startHand = (data?: any, callback?: any) => {
+  sendMessage(
+    'handcontroller',
+    {
+      hctrl_name: `handcontroller_${data}`,
+      cmd: 'open_handcontroller'
+    },
+    () => {}
+  );
+};
+
+/**
+ * 关闭连接
+ */
+export const closeHand = (data?: any, callback?: any) => {
+  sendMessage(
+    'handcontroller',
+    {
+      hctrl_name: `handcontroller_${data}`,
+      cmd: 'terminate_handcontroller'
+    },
+    () => {}
+  );
+};

+ 42 - 3
src/views/gesture/index.vue

@@ -19,7 +19,8 @@
 </template>
 
 <script setup name="Gesture" lang="ts">
-import { handWs } from '@/utils/handController'
+import { handWs, startHand, closeHand } from '@/utils/handWs'
+import { deviceWs, startDevice } from '@/utils/deviceWs'
 import { Swiper, SwiperSlide } from 'swiper/vue';
 import { Navigation } from 'swiper/modules';
 import 'swiper/css';
@@ -31,8 +32,9 @@ const mySwiper = ref();
 const data = reactive<any>({
   projectList: [],
   timerManager: {},
+  device_info: {}
 });
-const { projectList, timerManager } = toRefs(data);
+const { projectList, timerManager, device_info } = toRefs(data);
 
 /**
  * 清空定时任务
@@ -97,9 +99,22 @@ const slideNext = () => {
   mySwiper.value.slideNext();
 };
 
-onBeforeMount(() => {
+/**
+ * 手势
+*/
+const getHandWs = () => {
   //加载手势WS
   handWs((e: any) => {
+
+    //发送设备
+    if (e?.wksid) {
+      console.log("e.wksid", e.wksid)
+      if (device_info.value.handcontroller_id) {
+        startHand(device_info.value.handcontroller_id)
+      } else {
+        proxy?.$modal.msgError("请配置手势ID");
+      }
+    }
     //左滑动
     if (e?.data?.result == "next_item") {
       slideNext();
@@ -113,6 +128,30 @@ onBeforeMount(() => {
 
     }
   });
+};
+
+
+onBeforeMount(() => {
+  //加载设备WS
+  deviceWs((e: any) => {
+    //发送设备
+    if (e?.wksid) {
+      console.log("e.wksid", e.wksid)
+      startDevice({ deviceid: '53986765' })
+    }
+    //接收百度语音token
+    if (e?.bdapi_token) {
+      console.log("e.bdapi_token", e.bdapi_token)
+      let tok = e.bdapi_token;
+      localStorage.setItem('tok', tok);
+    }
+    //接收参数
+    if (e?.device_info) {
+      console.log("e.device_info", e.device_info)
+      device_info.value = e.device_info
+      getHandWs();
+    }
+  });
   getInitExam();
 })
 onMounted(() => {

+ 286 - 0
src/views/test/index.vue

@@ -0,0 +1,286 @@
+<template>
+  <div class="train">
+    <Header @confirmExit="getExit" :showTool="false" closeClass="close2"></Header>
+
+    <div class="main">
+      <div class="left"></div>
+      <div class="menu" v-if="projectList.length" :class="projectList.length <= 10 ? 'menu1' : 'menu2'">
+        <swiper :slides-per-view="5" :modules="[Grid]" :grid="{
+          fill: projectList.length <= 10 ? 'row' : 'column',
+          rows: 2,
+        }" :space-between="20" :slides-per-group="10">
+          <swiper-slide v-for="(item, index) in projectList " :key="index" @click="getOption(item)">
+            <div class="li">
+              <div class="pic"><img :src="'static/images/train/' + item.key + '.png'"></div>
+              <div class="name">
+                {{ item.name }}
+              </div>
+            </div>
+          </swiper-slide>
+        </swiper>
+      </div>
+    </div>
+
+    <OptionWindow ref="optionWindowRef" :projectList="projectList" />
+  </div>
+</template>
+
+<script setup name="TrainIndex" lang="ts">
+import { Swiper, SwiperSlide } from 'swiper/vue';
+import { Grid } from 'swiper/modules';
+import 'swiper/css';
+import 'swiper/css/grid';
+
+const router = useRouter();
+const { proxy } = getCurrentInstance() as any;
+const optionWindowRef = ref();
+
+const data = reactive<any>({
+  projectList: [],
+  timerManager: {},
+});
+const { projectList, timerManager } = toRefs(data);
+
+/**
+ * 获取项目
+*/
+const getExam = () => {
+  proxy?.$http.train.projectList().then((res: any) => {
+    projectList.value = proxy?.$utils.getProject(res.exams).filter((item: any) => {
+      //只显示能开的
+      return item.area.length > 0;
+    });
+  });
+};
+
+/**
+ * 弹出选项窗口
+*/
+const getOption = (data: any) => {
+  optionWindowRef.value.open(data);
+};
+
+/**
+ * 清空定时任务
+*/
+const getClearTimer = () => {
+  for (let key in timerManager.value) {
+    if (timerManager.value.hasOwnProperty(key)) {
+      clearInterval(timerManager.value[key])
+      timerManager.value[key] = null;
+    }
+  }
+};
+
+/**
+ * 初始化项目
+*/
+const getInitExam = () => {
+  getExam();
+  //定时刷新
+  timerManager.value.exam = setInterval(() => {
+    getExam();
+  }, 5000)
+};
+
+/**
+ * 退出
+*/
+const getExit = () => {
+  router.go(-1);
+};
+
+onBeforeMount(() => {
+  getInitExam();
+})
+
+onBeforeUnmount(() => {
+  getClearTimer();
+})
+</script>
+
+<style lang="scss" scoped>
+$topPadding: 5.19rem;
+$waiPadding: 6.51rem;
+
+.main {
+  width: calc(100% - ($waiPadding * 2));
+  height: 72vh;
+  padding-top: 10rem;
+  margin: 0 auto;
+  display: flex;
+  justify-content: space-between;
+}
+
+.left {
+  width: calc(23.4% - 20px);
+  height: 72vh;
+}
+
+.menu {
+  width: calc(100% - 23.4% - 20px);
+  height: 72vh;
+
+  .li {
+    // width: calc((100% / 6) - 1rem + (1rem/6));
+    // margin-right: 1rem;
+    // margin-bottom: 1rem;
+    width: 100%;
+    height: calc((72vh / 2) - 10px);
+    padding: 2.2vh 0;
+    border-radius: 1.6rem;
+    box-sizing: border-box;
+    box-shadow: inset 0px 1px 0px 2px rgba(255, 255, 255, 0.9046), inset 0px 3px 6px 0px rgba(0, 0, 0, 0.0851);
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: center;
+    text-align: center;
+
+    flex-shrink: 0;
+    cursor: pointer;
+
+    .name {
+      width: 100%;
+      font-size: 2.48rem;
+      color: #1A293A;
+      padding: 0.5rem 0;
+    }
+
+
+    .pic {
+      width: 11.36vw;
+      height: 11.36vw;
+      border-radius: 50%;
+      background: radial-gradient(78% 78% at 53% 50%, #07121A 0%, #2A4256 49%, #5180A9 100%);
+      box-shadow: 0px 0px 2px 2px #FFFFFF;
+      margin-bottom: 2vh;
+      overflow: hidden;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      flex-shrink: 0;
+
+      img {
+        max-width: 88%;
+        max-height: 88%;
+        transition: all 1s;
+      }
+    }
+
+    &:hover {
+      img {
+        transform: translateY(-0.5vw);
+      }
+    }
+  }
+
+  .swiper-slide {
+    border-radius: 1.6rem;
+    overflow: hidden;
+  }
+}
+
+.menu1 {
+  .swiper-slide {
+    margin-bottom: 20px;
+
+    .li {
+      background: radial-gradient(96% 96% at 2% 32%, #FFFFFF 0%, #FCFDFD 54%, #E1E4E7 100%);
+    }
+
+    &:nth-child(2),
+    &:nth-child(4),
+    &:nth-child(6),
+    &:nth-child(7),
+    &:nth-child(9),
+    &:nth-child(11) {
+      .li {
+        background: radial-gradient(167% 126% at 97% 6%, #35FFC6 0%, #00FFE8 100%);
+      }
+    }
+  }
+}
+
+.menu2 {
+  display: flex;
+
+  .swiper-slide {
+
+    &:nth-child(1),
+    &:nth-child(4),
+    &:nth-child(5),
+    &:nth-child(8),
+    &:nth-child(9),
+    &:nth-child(12),
+    &:nth-child(13),
+    &:nth-child(16),
+    &:nth-child(17),
+    &:nth-child(20),
+    &:nth-child(21),
+    &:nth-child(24),
+    &:nth-child(25),
+    &:nth-child(28),
+    &:nth-child(29),
+    &:nth-child(32),
+    &:nth-child(33),
+    &:nth-child(36),
+    &:nth-child(37),
+    &:nth-child(40),
+    &:nth-child(41),
+    &:nth-child(44) {
+      .li {
+        background: radial-gradient(96% 96% at 2% 32%, #FFFFFF 0%, #FCFDFD 54%, #E1E4E7 100%);
+      }
+    }
+
+    &:nth-child(2),
+    &:nth-child(3),
+    &:nth-child(6),
+    &:nth-child(7),
+    &:nth-child(10),
+    &:nth-child(11),
+    &:nth-child(14),
+    &:nth-child(15),
+    &:nth-child(18),
+    &:nth-child(19),
+    &:nth-child(22),
+    &:nth-child(23),
+    &:nth-child(26),
+    &:nth-child(27),
+    &:nth-child(30),
+    &:nth-child(31),
+    &:nth-child(34),
+    &:nth-child(35),
+    &:nth-child(38),
+    &:nth-child(39),
+    &:nth-child(42),
+    &:nth-child(43) {
+      .li {
+        background: radial-gradient(167% 126% at 97% 6%, #35FFC6 0%, #00FFE8 100%);
+      }
+    }
+  }
+}
+
+::v-deep(.menu) {
+  .swiper-horizontal {
+    width: 100%;
+  }
+}
+
+@media screen and (max-width: 1450px) {
+  .menu {
+
+    .li {
+      .name {
+        font-size: 1.8rem;
+      }
+
+      .pic {
+        width: 10vw;
+        height: 10vw;
+      }
+    }
+  }
+}
+</style>

+ 1 - 1
src/views/train/multiple.vue

@@ -67,7 +67,7 @@
 <script setup name="Multiple" lang="ts">
 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 { handWs } from '@/utils/handWs'
 const { proxy } = getCurrentInstance() as any;
 const router = useRouter();
 const route = useRoute();

+ 1 - 1
src/views/train/test.vue

@@ -115,7 +115,7 @@
 <script setup name="TrainTest" lang="ts">
 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 { handWs } from '@/utils/handWs'
 import dayjs from 'dayjs'
 import dataDictionary from "@/utils/dataDictionary"
 const { proxy } = getCurrentInstance() as any;