Ver código fonte

Merge branch 'refs/heads/20240604-dev' into 20240904-zyy

# Conflicts:
#	src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskVisualTraining/index.vue
周玉佂 1 semana atrás
pai
commit
f0d9b9c8a1

BIN
public/static/image/cognitiveAbility/SpeechTraining/OralExpression/bg.png


+ 46 - 23
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/index.vue

@@ -20,23 +20,21 @@
       <!--模式选择-->
       <div v-if="modeSelect === -1" class="absolute wh-full top-0 left-0 bg-[#ffffff9f] z-3999 flex-center">
         <div class="choice-bg w-800px h-400px flex-center flex-col">
-          <span class="inline-block text-45px text-black mb-36px mt-28px">请选择任务模式:</span>
+          <span class="inline-block text-45px text-black mb-36px mt-28px">请选择任务模式:</span>
           <div class="flex flex-row w-76% justify-between mt-18px">
             <el-image
-              v-if="!isMainWin"
               src="/static/image/cognitiveAbility/SpeechTraining/tips-one.png"
               fit="contain"
               class="w-[280px] h-[90px] cursor-pointer"
               :class="{ 'scale-113': modeActive === 0 }"
-              @click="modeSelectFn(0)"
+              @click="modeSelectFn(0, isMainWin ? 1 : 0)"
             />
             <el-image
-              v-if="!isMainWin"
               src="/static/image/cognitiveAbility/SpeechTraining/tips-all.png"
               fit="contain"
               class="w-[280px] h-[90px] cursor-pointer"
               :class="{ 'scale-113': modeActive === 1 }"
-              @click="modeSelectFn(1)"
+              @click="modeSelectFn(1, isMainWin ? 1 : 0)"
             />
           </div>
         </div>
@@ -50,9 +48,9 @@
         <div
           v-for="(item, index) in checkItems"
           :key="index"
-          class="w-[300px] h-[70px] flex-center fw-700 text-[38px] color-[#ffffff] mb-[18px] cursor-pointer hover:scale-102"
+          class="w-[300px] h-[70px] flex-center fw-700 text-[34px] color-[#ffffff] mb-[18px] cursor-pointer hover:scale-102"
           :class="[item.active ? 'active' : 'normal']"
-          @click="checkItemFn(item, index)"
+          @click="checkItemFn(item, isMainWin ? 1 : 0)"
         >
           {{ item.name }}
         </div>
@@ -77,7 +75,9 @@
  * 编写者: JutarryWu
  */
 import EvaluationSTRecordInfoAPI from '@/api/tester/evaluation/stRecord'
+import { useThrottleFn } from '@vueuse/core'
 import { useUserStore } from '@/store'
+import { isJSON } from '@/utils'
 interface CheckItem {
   key: string
   name: string
@@ -133,23 +133,38 @@ const handleClose = () => {
   emits('close')
 }
 
-const checkItemFn = (item: CheckItem, index: number) => {
+/**
+ * 任务选择
+ * @param item
+ * @param flag 0: 副屏点击,1:主屏点击
+ */
+const checkItemFn = useThrottleFn((item: CheckItem, flag: number = 0) => {
+  if (flag === 1) return
   if (modeSelect.value === 0) {
-    checkItems.value.forEach((item2) => {
+    let tempIndex = -1
+    checkItems.value.forEach((item2, index) => {
       item2.active = false
+      if (item2.key === item.key) tempIndex = index
     })
-    VoiceImpRef.value.videoPlay()
-    item.active = !item.active
+    checkItems.value[tempIndex].active = true
+    if (!isMainWin.value) {
+      VoiceImpRef.value.videoPlay()
+      localStorage.setItem('two-win-auditory-item-check', JSON.stringify(item))
+    }
   }
-}
+})
 
 /**
  * 选择模式
  * @param mode 0: 单流程模式,1: 全流程模式
+ * @param flag 0: 副屏点击,1:主屏点击
  */
-const modeSelectFn = (mode: number) => {
-  if (modeActive.value !== -1) return
-  VoiceImpRef.value.videoPlay('right')
+const modeSelectFn = useThrottleFn((mode: number, flag: number = 0) => {
+  if (modeActive.value !== -1 || flag === 1) return
+  if (!isMainWin.value) {
+    VoiceImpRef.value.videoPlay('right')
+    localStorage.setItem('two-win-auditory-mode-select', mode + '')
+  }
   modeActive.value = mode
   setTimeout(() => {
     modeSelect.value = mode
@@ -159,18 +174,17 @@ const modeSelectFn = (mode: number) => {
       })
     }
   }, 800)
-}
+})
 
-const startTask = () => {
-  // TODO 开始任务
-}
+const startTask = useThrottleFn(() => {
+  if (!isMainWin.value) {
+    // TODO 开始任务
+  }
+})
 
 const countDownEnd = () => {
   countDownBegin.value = false
   showCountDown.value = false
-  setTimeout(() => {
-    console.log('')
-  }, 1000)
 }
 
 async function exec() {
@@ -189,7 +203,16 @@ onMounted(() => {
 
   window.addEventListener('storage', (val) => {
     if (isMainWin.value) {
-      console.log('')
+      console.log(val.key)
+      if (val.key === 'two-win-auditory-mode-select') {
+        modeSelectFn(Number(val.newValue))
+        localStorage.removeItem('two-win-auditory-mode-select')
+      }
+      if (val.key === 'two-win-auditory-item-check' && isJSON(val.newValue!)) {
+        let tempVal = JSON.parse(val.newValue!) as CheckItem
+        checkItemFn(tempVal)
+        localStorage.removeItem('two-win-auditory-item-check')
+      }
     } else {
       console.log('')
     }

+ 57 - 34
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskOralExpression/index.vue

@@ -20,29 +20,27 @@
       <!--模式选择-->
       <div v-if="modeSelect === -1" class="absolute wh-full top-0 left-0 bg-[#ffffff9f] z-3999 flex-center">
         <div class="choice-bg w-800px h-400px flex-center flex-col">
-          <span class="inline-block text-45px text-black mb-36px mt-28px">请选择任务模式:</span>
+          <span class="inline-block text-45px text-black mb-36px mt-28px">请选择任务模式:</span>
           <div class="flex flex-row w-76% justify-between mt-18px">
             <el-image
-              v-if="!isMainWin"
               src="/static/image/cognitiveAbility/SpeechTraining/tips-one.png"
               fit="contain"
               class="w-[280px] h-[90px] cursor-pointer"
               :class="{ 'scale-113': modeActive === 0 }"
-              @click="modeSelectFn(0)"
+              @click="modeSelectFn(0, isMainWin ? 1 : 0)"
             />
             <el-image
-              v-if="!isMainWin"
               src="/static/image/cognitiveAbility/SpeechTraining/tips-all.png"
               fit="contain"
               class="w-[280px] h-[90px] cursor-pointer"
               :class="{ 'scale-113': modeActive === 1 }"
-              @click="modeSelectFn(1)"
+              @click="modeSelectFn(1, isMainWin ? 1 : 0)"
             />
           </div>
         </div>
       </div>
       <el-image
-        src="/static/image/cognitiveAbility/SpeechTraining/Visual/bg-title.png"
+        src="/static/image/cognitiveAbility/SpeechTraining/OralExpression/bg-title.png"
         fit="contain"
         class="w-[1120px] h-[160px]"
       />
@@ -50,9 +48,9 @@
         <div
           v-for="(item, index) in checkItems"
           :key="index"
-          class="w-[300px] h-[70px] flex-center fw-700 text-[38px] color-[#ffffff] mb-[18px] cursor-pointer hover:scale-102"
+          class="w-[300px] h-[70px] flex-center fw-700 text-[34px] color-[#ffffff] mb-[18px] cursor-pointer hover:scale-102"
           :class="[item.active ? 'active' : 'normal']"
-          @click="checkItemFn(item, index)"
+          @click="checkItemFn(item, isMainWin ? 1 : 0)"
         >
           {{ item.name }}
         </div>
@@ -61,6 +59,7 @@
         src="/static/image/cognitiveAbility/SpeechTraining/start-bg.png"
         fit="contain"
         class="w-[280px] h-[90px] mt-140px cursor-pointer hover:scale-101"
+        @click="startTask"
       />
     </div>
 
@@ -70,13 +69,15 @@
 
 <script setup lang="ts">
 /*
- * 组件名: CognitiveAbilityTaskOralExpression
- * 组件用途: 常规康复训练
+ * 组件名: CognitiveAbilityTaskOralExpressionTraining
+ * 组件用途: 常规康复训练 - 口语练习
  * 创建日期: 2024/7/16
  * 编写者: JutarryWu
  */
 import EvaluationSTRecordInfoAPI from '@/api/tester/evaluation/stRecord'
+import { useThrottleFn } from '@vueuse/core'
 import { useUserStore } from '@/store'
+import { isJSON } from '@/utils'
 interface CheckItem {
   key: string
   name: string
@@ -86,7 +87,7 @@ interface CheckItem {
 const isMainWin = ref(false)
 
 defineOptions({
-  name: 'CognitiveAbilityTaskOralExpression',
+  name: 'CognitiveAbilityTaskOralExpressionTraining',
   inheritAttrs: false
 })
 
@@ -110,13 +111,12 @@ const modeActive = ref(-1) // -1: 未选择,0: 单流程模式,1: 全流程
 
 const dialogVisible = ref(false) // 学历弹窗
 const checkItems = ref<CheckItem[]>([
-  { key: '1', name: '字字匹配', active: false },
+  { key: '1', name: '语音辨识', active: false },
   { key: '2', name: '词图匹配', active: false },
-  { key: '3', name: '图匹配', active: false },
-  { key: '4', name: '句图匹配', active: false },
+  { key: '3', name: '图匹配', active: false },
+  { key: '4', name: '是非反应', active: false },
   { key: '5', name: '执行指令', active: false },
-  { key: '6', name: '词语组句', active: false },
-  { key: '7', name: '短文理解', active: false }
+  { key: '6', name: '听短文回答故事', active: false }
 ])
 
 const closeDialog = () => {
@@ -133,23 +133,38 @@ const handleClose = () => {
   emits('close')
 }
 
-const checkItemFn = (item: CheckItem, index: number) => {
+/**
+ * 任务选择
+ * @param item
+ * @param flag 0: 副屏点击,1:主屏点击
+ */
+const checkItemFn = useThrottleFn((item: CheckItem, flag: number = 0) => {
+  if (flag === 1) return
   if (modeSelect.value === 0) {
-    checkItems.value.forEach((item2) => {
+    let tempIndex = -1
+    checkItems.value.forEach((item2, index) => {
       item2.active = false
+      if (item2.key === item.key) tempIndex = index
     })
-    VoiceImpRef.value.videoPlay()
-    item.active = !item.active
+    checkItems.value[tempIndex].active = true
+    if (!isMainWin.value) {
+      VoiceImpRef.value.videoPlay()
+      localStorage.setItem('two-win-OralExpression-item-check', JSON.stringify(item))
+    }
   }
-}
+})
 
 /**
  * 选择模式
  * @param mode 0: 单流程模式,1: 全流程模式
+ * @param flag 0: 副屏点击,1:主屏点击
  */
-const modeSelectFn = (mode: number) => {
-  if (modeActive.value !== -1) return
-  VoiceImpRef.value.videoPlay('right')
+const modeSelectFn = useThrottleFn((mode: number, flag: number = 0) => {
+  if (modeActive.value !== -1 || flag === 1) return
+  if (!isMainWin.value) {
+    VoiceImpRef.value.videoPlay('right')
+    localStorage.setItem('two-win-OralExpression-mode-select', mode + '')
+  }
   modeActive.value = mode
   setTimeout(() => {
     modeSelect.value = mode
@@ -159,18 +174,17 @@ const modeSelectFn = (mode: number) => {
       })
     }
   }, 800)
-}
+})
 
-const startTask = () => {
-  // TODO 开始任务
-}
+const startTask = useThrottleFn(() => {
+  if (!isMainWin.value) {
+    // TODO 开始任务
+  }
+})
 
 const countDownEnd = () => {
   countDownBegin.value = false
   showCountDown.value = false
-  setTimeout(() => {
-    console.log('')
-  }, 1000)
 }
 
 async function exec() {
@@ -189,7 +203,16 @@ onMounted(() => {
 
   window.addEventListener('storage', (val) => {
     if (isMainWin.value) {
-      console.log('')
+      console.log(val.key)
+      if (val.key === 'two-win-OralExpression-mode-select') {
+        modeSelectFn(Number(val.newValue))
+        localStorage.removeItem('two-win-OralExpression-mode-select')
+      }
+      if (val.key === 'two-win-OralExpression-item-check' && isJSON(val.newValue!)) {
+        let tempVal = JSON.parse(val.newValue!) as CheckItem
+        checkItemFn(tempVal)
+        localStorage.removeItem('two-win-OralExpression-item-check')
+      }
     } else {
       console.log('')
     }
@@ -199,8 +222,8 @@ onMounted(() => {
 
 <style scoped lang="scss">
 .boston-container {
-  background: url('/static/image/cognitiveAbility/SpeechTraining/Visual/bg.png') no-repeat 0 0 / 100% 100% border-box
-    fixed;
+  background: url('/static/image/cognitiveAbility/SpeechTraining/OralExpression/bg.png') no-repeat 0 0 / 100% 100%
+    border-box fixed;
 
   .el-button + .el-button {
     margin-left: 0;

+ 89 - 69
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskVisualTraining/index.vue

@@ -8,65 +8,63 @@
       @click="handleClose"
     />
     <div v-if="gameActive === '0'">
-      <div v-if="showCountDown" class="absolute top-[50%] left-[50%] translate-[-50%] w-[400px] h-[200px] flex-center">
-        <div class="w-[120px] h-[120px] relative">
-          <wu-count-down :begin="countDownBegin" :num="5" @count-down-end="countDownEnd" />
-        </div>
-        <span v-if="!countDownBegin" class="font-600 text-[36px] text-[#089BAB]">{{ countDownStr }}</span>
+    <div v-if="showCountDown" class="absolute top-[50%] left-[50%] translate-[-50%] w-[400px] h-[200px] flex-center">
+      <div class="w-[120px] h-[120px] relative">
+        <wu-count-down :begin="countDownBegin" :num="5" @count-down-end="countDownEnd" />
       </div>
-      <div
-        v-else
-        class="absolute top-[50%] left-[50%] translate-[-50%] w-[1600px] h-[960px] rounded-[8px] bg-[#ffffffff] shadow-lg flex-center flex-col"
-      >
-        <!--模式选择-->
-        <div v-if="modeSelect === -1" class="absolute wh-full top-0 left-0 bg-[#ffffff9f] z-3999 flex-center">
-          <div class="choice-bg w-800px h-400px flex-center flex-col">
-            <span class="inline-block text-45px text-black mb-36px mt-28px">请选择您任务模式:</span>
-            <div class="flex flex-row w-76% justify-between mt-18px">
-              <el-image
-                v-if="!isMainWin"
-                src="/static/image/cognitiveAbility/SpeechTraining/tips-one.png"
-                fit="contain"
-                class="w-[280px] h-[90px] cursor-pointer"
-                :class="{ 'scale-113': modeActive === 0 }"
-                @click="modeSelectFn(0)"
-              />
-              <el-image
-                v-if="!isMainWin"
-                src="/static/image/cognitiveAbility/SpeechTraining/tips-all.png"
-                fit="contain"
-                class="w-[280px] h-[90px] cursor-pointer"
-                :class="{ 'scale-113': modeActive === 1 }"
-                @click="modeSelectFn(1)"
-              />
-            </div>
+      <span v-if="!countDownBegin" class="font-600 text-[36px] text-[#089BAB]">{{ countDownStr }}</span>
+    </div>
+    <div
+      v-else
+      class="absolute top-[50%] left-[50%] translate-[-50%] w-[1600px] h-[960px] rounded-[8px] bg-[#ffffffff] shadow-lg flex-center flex-col"
+    >
+      <!--模式选择-->
+      <div v-if="modeSelect === -1" class="absolute wh-full top-0 left-0 bg-[#ffffff9f] z-3999 flex-center">
+        <div class="choice-bg w-800px h-400px flex-center flex-col">
+          <span class="inline-block text-45px text-black mb-36px mt-28px">请您选择任务模式:</span>
+          <div class="flex flex-row w-76% justify-between mt-18px">
+            <el-image
+              src="/static/image/cognitiveAbility/SpeechTraining/tips-one.png"
+              fit="contain"
+              class="w-[280px] h-[90px] cursor-pointer"
+              :class="{ 'scale-113': modeActive === 0 }"
+              @click="modeSelectFn(0, isMainWin ? 1 : 0)"
+            />
+            <el-image
+              src="/static/image/cognitiveAbility/SpeechTraining/tips-all.png"
+              fit="contain"
+              class="w-[280px] h-[90px] cursor-pointer"
+              :class="{ 'scale-113': modeActive === 1 }"
+              @click="modeSelectFn(1, isMainWin ? 1 : 0)"
+            />
           </div>
         </div>
-        <el-image
-          src="/static/image/cognitiveAbility/SpeechTraining/Visual/bg-title.png"
-          fit="contain"
-          class="w-[1120px] h-[160px]"
-        />
-        <div class="w-[1120px] mt-100px flex flex-wrap flex-row justify-between">
-          <div
-            v-for="(item, index) in checkItems"
-            :key="index"
-            class="w-[300px] h-[70px] flex-center fw-700 text-[38px] color-[#ffffff] mb-[18px] cursor-pointer hover:scale-102"
-            :class="[item.active ? 'active' : 'normal']"
-            @click="checkItemFn(item, index)"
-          >
-            {{ item.name }}
-          </div>
+      </div>
+      <el-image
+        src="/static/image/cognitiveAbility/SpeechTraining/Visual/bg-title.png"
+        fit="contain"
+        class="w-[1120px] h-[160px]"
+      />
+      <div class="w-[1120px] mt-100px flex flex-wrap flex-row justify-between">
+        <div
+          v-for="(item, index) in checkItems"
+          :key="index"
+          class="w-[300px] h-[70px] flex-center fw-700 text-[34px] color-[#ffffff] mb-[18px] cursor-pointer hover:scale-102"
+          :class="[item.active ? 'active' : 'normal']"
+          @click="checkItemFn(item, isMainWin ? 1 : 0)"
+        >
+          {{ item.name }}
         </div>
-        <el-image
-          src="/static/image/cognitiveAbility/SpeechTraining/start-bg.png"
-          fit="contain"
-          class="w-[280px] h-[90px] mt-140px cursor-pointer hover:scale-101"
-          @click="startTask()"
-        />
       </div>
+      <el-image
+        src="/static/image/cognitiveAbility/SpeechTraining/start-bg.png"
+        fit="contain"
+        class="w-[280px] h-[90px] mt-140px cursor-pointer hover:scale-101"
+        @click="startTask"
+      />
+    </div>
     </div>
-    <div>
+      <div>
       <Word-word v-if="gameActive === '1'" />
     </div>
     <VoiceImp ref="VoiceImpRef" />
@@ -81,7 +79,9 @@
  * 编写者: JutarryWu
  */
 import EvaluationSTRecordInfoAPI from '@/api/tester/evaluation/stRecord'
+import { useThrottleFn } from '@vueuse/core'
 import { useUserStore } from '@/store'
+import { isJSON } from '@/utils'
 interface CheckItem {
   key: string
   name: string
@@ -140,24 +140,39 @@ const handleClose = () => {
   emits('close')
 }
 
-const checkItemFn = (item: CheckItem, index: number) => {
+/**
+ * 任务选择
+ * @param item
+ * @param flag 0: 副屏点击,1:主屏点击
+ */
+const checkItemFn = useThrottleFn((item: CheckItem, flag: number = 0) => {
+  if (flag === 1) return
   if (modeSelect.value === 0) {
-    checkItems.value.forEach((item2) => {
+    let tempIndex = -1
+    checkItems.value.forEach((item2, index) => {
       item2.active = false
+      if (item2.key === item.key) tempIndex = index
     })
-    VoiceImpRef.value.videoPlay()
-    item.active = !item.active
+    checkItems.value[tempIndex].active = true
     itemActive.value = item.key
+    if (!isMainWin.value) {
+      VoiceImpRef.value.videoPlay()
+      localStorage.setItem('two-win-Visual-item-check', JSON.stringify(item))
+    }
   }
-}
+})
 
 /**
  * 选择模式
  * @param mode 0: 单流程模式,1: 全流程模式
+ * @param flag 0: 副屏点击,1:主屏点击
  */
-const modeSelectFn = (mode: number) => {
-  if (modeActive.value !== -1) return
-  VoiceImpRef.value.videoPlay('right')
+const modeSelectFn = useThrottleFn((mode: number, flag: number = 0) => {
+  if (modeActive.value !== -1 || flag === 1) return
+  if (!isMainWin.value) {
+    VoiceImpRef.value.videoPlay('right')
+    localStorage.setItem('two-win-Visual-mode-select', mode + '')
+  }
   modeActive.value = mode
   setTimeout(() => {
     modeSelect.value = mode
@@ -167,20 +182,16 @@ const modeSelectFn = (mode: number) => {
       })
     }
   }, 800)
-}
+})
 
-const startTask = () => {
-  // TODO 开始任务
+const startTask = useThrottleFn(() => {
   gameActive.value = itemActive.value
   console.log('开始任务', gameActive.value)
-}
+})
 
 const countDownEnd = () => {
   countDownBegin.value = false
   showCountDown.value = false
-  setTimeout(() => {
-    console.log('')
-  }, 1000)
 }
 
 async function exec() {
@@ -199,7 +210,16 @@ onMounted(() => {
 
   window.addEventListener('storage', (val) => {
     if (isMainWin.value) {
-      console.log('')
+      console.log(val.key)
+      if (val.key === 'two-win-Visual-mode-select') {
+        modeSelectFn(Number(val.newValue))
+        localStorage.removeItem('two-win-Visual-mode-select')
+      }
+      if (val.key === 'two-win-Visual-item-check' && isJSON(val.newValue!)) {
+        let tempVal = JSON.parse(val.newValue!) as CheckItem
+        checkItemFn(tempVal)
+        localStorage.removeItem('two-win-Visual-item-check')
+      }
     } else {
       console.log('')
     }