Explorar el Código

言语康复训练 - 听 - 77%

JutarryWu hace 1 semana
padre
commit
47fa1b6c5a
Se han modificado 15 ficheros con 341 adiciones y 19 borrados
  1. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/1.mp3
  2. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/书-tips.mp3
  3. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/书.mp3
  4. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/杯子-tips.mp3
  5. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/杯子.mp3
  6. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/松树-tips.mp3
  7. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/松树.mp3
  8. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/电视-tips.mp3
  9. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/电视.mp3
  10. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/筷子-tips.mp3
  11. BIN
      public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/筷子.mp3
  12. 219 0
      src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingImgWordMatching/index.vue
  13. 30 0
      src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingImgWordMatching/topics.json
  14. 81 13
      src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingWordImgMatching/index.vue
  15. 11 6
      src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingWordImgMatching/topics.json

BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/1.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/书-tips.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/书.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/杯子-tips.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/杯子.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/松树-tips.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/松树.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/电视-tips.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/电视.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/筷子-tips.mp3


BIN
public/static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/筷子.mp3


+ 219 - 0
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingImgWordMatching/index.vue

@@ -0,0 +1,219 @@
+<template>
+  <section class="auditory-word-img-matching-container flex-center flex-col wh-full relative">
+    <water-title title="词图匹配" />
+    <div v-if="isMainWin" class="text-[42px] text-[#0F308C]">
+      {{ Topics.question }}
+    </div>
+
+    <div v-if="!isMainWin && showTopics" class="flex-center flex-col text-100px text-[#0F308C]">
+      {{ TopicsVal[currentIndex].correct }}
+    </div>
+    <div class="w-80% h-60% my-30px flex-center flex-col">
+      <template v-if="showTopics">
+        <el-image
+          v-if="isMainWin"
+          src="/static/image/cognitiveAbility/SpeechTraining/Auditory/play.png"
+          fit="contain"
+          class="w-[300px] h-[160px] mb-40px cursor-pointer hover:scale-101"
+          @click="handlePlay"
+        />
+        <div class="w-full flex flex-row justify-around">
+          <div v-for="(item, index) in TopicsVal[currentIndex].choices" :key="index" class="flex flex-col items-center">
+            <div class="w-180px h-180px flex-center cursor-pointer" @click="handleItemClick(item, index)">
+              <el-image
+                :src="`/static/image/cognitiveAbility/SpeechTraining/Visual/${item}.jpg`"
+                fit="contain"
+                class="w-[120px] h-[120px] cursor-pointer mt-30px"
+              />
+            </div>
+            <el-image
+              :src="`/static/image/cognitiveAbility/SpeechTraining/${useClickIndex === index || item === TopicsVal[currentIndex].userAnswer ? 'Options-right' : 'Options-Blank'}.png`"
+              fit="contain"
+              class="w-[100px] h-[100px] mt-30px"
+            />
+          </div>
+        </div>
+      </template>
+    </div>
+
+    <div v-if="!isMainWin" class="w-[300px] h-[140px]">
+      <el-image
+        v-if="showSubmitBtn"
+        src="/static/image/cognitiveAbility/SpeechTraining/verify-bg.png"
+        fit="contain"
+        class="w-[300px] h-[140px] cursor-pointer hover:scale-101"
+        @click="handleSubmit"
+      />
+    </div>
+
+    <el-image
+      v-if="showNextBtn"
+      src="/static/image/cognitiveAbility/SpeechTraining/next.png"
+      fit="contain"
+      class="!absolute bottom-[24px] right-[140px] w-[300px] h-[140px] cursor-pointer hover:scale-101"
+      @click="handleNext()"
+    />
+
+    <VoiceImp ref="VoiceImpRef" />
+  </section>
+</template>
+
+<script setup lang="ts">
+/*
+ * 组件名: CATAuditoryTrainingWordImgMatching
+ * 组件用途: 常规听康复训练 - 词图匹配
+ * 创建日期: 2024/11/12
+ * 编写者: JutarryWu
+ */
+
+import { formatSeconds, isJSON } from '@/utils'
+
+defineOptions({
+  name: 'CATAuditoryTrainingWordImgMatching',
+  inheritAttrs: false
+})
+
+import Topics from './topics.json'
+
+interface TopicsType {
+  choices: string[]
+  correct: string
+  userAnswer: string
+}
+
+const props = defineProps({})
+const emits = defineEmits(['gameOver'])
+
+const isMainWin = ref(false)
+const showNextBtn = ref(false) // 主屏 - 显示下一题按钮标识
+const showSubmitBtn = ref(false) // 副屏 - 显示确定按钮标识
+let isSubmitting = false // 是否正在提交标识
+const showTopics = ref(false) // 显示题目选项标识
+const VoiceImpRef = ref()
+const currentIndex = ref(0) // 当前题目索引
+const TopicsVal = ref<TopicsType[]>([])
+const useClickIndex = ref(-1) // 副屏 - 用户点击的选项索引
+let taskBeginTime = 0 // 任务开始时间
+
+const handleNext = () => {
+  if (TopicsVal.value[currentIndex.value].userAnswer === '') {
+    showTopics.value = true
+    showNextBtn.value = false
+    localStorage.setItem('tow-win-auditory-word-img-matching-show-topics', currentIndex.value + '')
+  } else {
+    let tempCount = TopicsVal.value.filter((item) => item.userAnswer !== '').length
+    if (tempCount === TopicsVal.value.length) {
+      isSubmitting = true
+      localStorage.setItem('tow-win-auditory-word-img-matching-isSubmitting', 'YES')
+    } else {
+      currentIndex.value++
+      handleNext()
+    }
+  }
+}
+
+const handlePlay = () => {
+  localStorage.setItem('two-win-auditory-word-img-matching-item-check', TopicsVal.value[currentIndex.value].correct)
+}
+
+const handleItemClick = (item: string, index: number) => {
+  if (isSubmitting) return // 如果再提交进程中,不响应点击事件
+  if (!isMainWin.value) {
+    VoiceImpRef.value.videoPlay()
+    TopicsVal.value[currentIndex.value].userAnswer = item
+    useClickIndex.value = index
+    showSubmitBtn.value = true
+    localStorage.setItem(
+      'two-win-auditory-word-img-matching-submit-answer',
+      TopicsVal.value[currentIndex.value].userAnswer
+    )
+  }
+}
+
+const handleSubmit = () => {
+  if (TopicsVal.value[currentIndex.value].userAnswer === '') {
+    ElMessage.warning('请先完成当前题目!')
+    return
+  }
+  VoiceImpRef.value.videoPlay(
+    TopicsVal.value[currentIndex.value].userAnswer === TopicsVal.value[currentIndex.value].correct ? 'right' : 'error'
+  )
+  showSubmitBtn.value = false
+  localStorage.setItem('two-win-auditory-word-img-matching-try-over', 'YES')
+}
+
+async function exec() {
+  isMainWin.value = window.location.href.includes('win=main')
+  if (isMainWin.value) {
+    TopicsVal.value = Topics.topics
+      .map((item) => {
+        item.choices = item.choices.sort(() => Math.random() - 0.5)
+        return item
+      })
+      .sort(() => Math.random() - 0.5)
+    localStorage.setItem('two-win-auditory-word-img-matching-init-data', JSON.stringify(TopicsVal.value))
+    setTimeout(() => {
+      showNextBtn.value = true
+    }, 6600)
+  } else {
+    taskBeginTime = Date.now()
+    VoiceImpRef.value.videoPlay(
+      'Speech-Auditory',
+      'static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/1.mp3'
+    )
+  }
+}
+
+onMounted(() => {
+  exec()
+
+  window.addEventListener('storage', (val) => {
+    if (isMainWin.value) {
+      if (val.key === 'two-win-auditory-word-img-matching-submit-answer') {
+        TopicsVal.value[currentIndex.value].userAnswer = val.newValue!
+        localStorage.removeItem('two-win-auditory-word-img-matching-submit-answer')
+      }
+
+      if (val.key === 'two-win-auditory-word-img-matching-try-over') {
+        showNextBtn.value = true
+        localStorage.removeItem('two-win-auditory-word-img-matching-try-over')
+      }
+    } else {
+      if (val.key === 'two-win-auditory-word-img-matching-init-data' && isJSON(val.newValue!)) {
+        TopicsVal.value = JSON.parse(val.newValue!) as TopicsType[]
+        localStorage.removeItem('two-win-auditory-word-img-matching-init-data')
+      }
+
+      if (val.key === 'tow-win-auditory-word-img-matching-show-topics') {
+        showTopics.value = true
+        currentIndex.value = Number(val.newValue!)
+        useClickIndex.value = -1
+        localStorage.removeItem('tow-win-auditory-word-img-matching-show-topics')
+      }
+
+      if (val.key === 'two-win-auditory-word-img-matching-item-check') {
+        VoiceImpRef.value.videoPlay(
+          'Speech-Auditory',
+          `static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/${val.newValue}.mp3`
+        )
+        localStorage.removeItem('two-win-auditory-word-img-matching-item-check')
+      }
+
+      if (val.key === 'tow-win-auditory-word-img-matching-isSubmitting' && val.newValue === 'YES') {
+        isSubmitting = true
+        emits('gameOver', {
+          min: formatSeconds(Date.now() - taskBeginTime),
+          content: JSON.stringify({
+            question: Topics.question,
+            topics: TopicsVal.value
+          }),
+          score: TopicsVal.value.filter((item) => item.userAnswer === item.correct).length + ''
+        })
+        localStorage.removeItem('tow-win-auditory-word-img-matching-isSubmitting')
+      }
+    }
+  })
+})
+</script>
+
+<style scoped lang="scss"></style>

+ 30 - 0
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingImgWordMatching/topics.json

@@ -0,0 +1,30 @@
+{
+  "question": "屏幕中会出现一个词语,请你从下面的选项中选出与该词语匹配的图片",
+  "topics": [
+    {
+      "choices": ["杯子", "小碗"],
+      "correct": "杯子",
+      "userAnswer": ""
+    },
+    {
+      "choices": ["勺子", "筷子", "叉子"],
+      "correct": "筷子",
+      "userAnswer": ""
+    },
+    {
+      "choices": ["笔", "橡皮", "书包", "书"],
+      "correct": "书",
+      "userAnswer": ""
+    },
+    {
+      "choices": ["冰箱", "茶桌", "电视", "衣柜", "床"],
+      "correct": "电视",
+      "userAnswer": ""
+    },
+    {
+      "choices": ["小草", "松树", "玫瑰", "向日葵", "苹果", "花花"],
+      "correct": "松树",
+      "userAnswer": ""
+    }
+  ]
+}

+ 81 - 13
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingWordImgMatching/index.vue

@@ -14,7 +14,7 @@
           v-if="isMainWin"
           src="/static/image/cognitiveAbility/SpeechTraining/Auditory/play.png"
           fit="contain"
-          class="w-[300px] h-[160px] mb-40px cursor-pointer hover:scale-101"
+          class="w-[140px] h-[140px] mb-40px cursor-pointer hover:scale-101"
           @click="handlePlay"
         />
         <div class="w-full flex flex-row justify-around">
@@ -29,7 +29,7 @@
             <el-image
               :src="`/static/image/cognitiveAbility/SpeechTraining/${useClickIndex === index || item === TopicsVal[currentIndex].userAnswer ? 'Options-right' : 'Options-Blank'}.png`"
               fit="contain"
-              class="w-[100px] h-[100px] mt-30px"
+              class="w-[60px] h-[60px] mt-30px"
             />
           </div>
         </div>
@@ -46,13 +46,46 @@
       />
     </div>
 
-    <el-image
-      v-if="showNextBtn"
-      src="/static/image/cognitiveAbility/SpeechTraining/next.png"
-      fit="contain"
-      class="!absolute bottom-[24px] right-[140px] w-[300px] h-[140px] cursor-pointer hover:scale-101"
-      @click="handleNext()"
-    />
+    <div
+      v-if="isMainWin"
+      class="absolute bottom-[24px] left-10% w-80% h-140px flex flex-row items-center justify-between"
+    >
+      <div class="flex flex-row items-center">
+        <template v-if="showScoreArea">
+          <span class="text-[#0F308C] text-[42px]">请评分:</span>
+          <div
+            v-for="(item, index) in [0, 1, 2]"
+            :key="index"
+            class="w-[140px] flex flex-row items-center cursor-pointer"
+            @click="handleScore(item)"
+          >
+            <el-image
+              :src="`/static/image/cognitiveAbility/SpeechTraining/${
+                index === scoreIndex ? 'Options-right' : 'Options-Blank'
+              }.png`"
+              fit="contain"
+              class="w-[40px] h-[40px] cursor-pointer"
+            />
+            <span class="text-[36px] text-[#0F308C] ml-12px">{{ item }}</span>
+          </div>
+        </template>
+      </div>
+      <el-image
+        v-if="showNextBtn"
+        src="/static/image/cognitiveAbility/SpeechTraining/next.png"
+        fit="contain"
+        class="w-[300px] h-[140px] cursor-pointer hover:scale-101"
+        @click="handleNext()"
+      />
+    </div>
+    <div
+      v-if="!isMainWin && showScoreArea"
+      class="absolute bottom-[44px] left-10% w-240px h-140px flex flex-row items-end justify-between"
+    >
+      <span class="text-[#0F308C] text-[42px] mb-12px">得分:</span>
+      <span class="text-[#b1b1b1] text-[72px] score-text">{{ TopicsVal[currentIndex].score }}</span>
+      <span class="text-[#0F308C] text-[42px] mb-12px">分</span>
+    </div>
 
     <VoiceImp ref="VoiceImpRef" />
   </section>
@@ -79,6 +112,7 @@ interface TopicsType {
   choices: string[]
   correct: string
   userAnswer: string
+  score: string
 }
 
 const props = defineProps({})
@@ -86,15 +120,26 @@ const emits = defineEmits(['gameOver'])
 
 const isMainWin = ref(false)
 const showNextBtn = ref(false) // 主屏 - 显示下一题按钮标识
+const showScoreArea = ref(false) // 主屏 - 显示评分标识
 const showSubmitBtn = ref(false) // 副屏 - 显示确定按钮标识
 let isSubmitting = false // 是否正在提交标识
 const showTopics = ref(false) // 显示题目选项标识
 const VoiceImpRef = ref()
 const currentIndex = ref(0) // 当前题目索引
 const TopicsVal = ref<TopicsType[]>([])
-const useClickIndex = ref(-1) // 副屏 - 用户点击的选项索引
+const useClickIndex = ref(-1) // 副屏 - 患者点击的选项索引
+const scoreIndex = ref(-1) // 主屏 - 医生评分选项索引
 let taskBeginTime = 0 // 任务开始时间
 
+const handleScore = (index: number) => {
+  TopicsVal.value[currentIndex.value].score = index + ''
+  showNextBtn.value = true
+  if (isMainWin.value) {
+    scoreIndex.value = index
+    localStorage.setItem('tow-win-auditory-word-img-matching-score', index + '')
+  }
+}
+
 const handleNext = () => {
   if (TopicsVal.value[currentIndex.value].userAnswer === '') {
     showTopics.value = true
@@ -107,6 +152,8 @@ const handleNext = () => {
       localStorage.setItem('tow-win-auditory-word-img-matching-isSubmitting', 'YES')
     } else {
       currentIndex.value++
+      showScoreArea.value = false
+      scoreIndex.value = -1
       handleNext()
     }
   }
@@ -175,7 +222,8 @@ onMounted(() => {
       }
 
       if (val.key === 'two-win-auditory-word-img-matching-try-over') {
-        showNextBtn.value = true
+        // showNextBtn.value = true
+        showScoreArea.value = true
         localStorage.removeItem('two-win-auditory-word-img-matching-try-over')
       }
     } else {
@@ -188,17 +236,29 @@ onMounted(() => {
         showTopics.value = true
         currentIndex.value = Number(val.newValue!)
         useClickIndex.value = -1
+        showScoreArea.value = false
+        scoreIndex.value = -1
+        VoiceImpRef.value.videoPlay(
+          'Speech-Auditory',
+          `static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/${TopicsVal.value[currentIndex.value].correct}.mp3`
+        )
         localStorage.removeItem('tow-win-auditory-word-img-matching-show-topics')
       }
 
       if (val.key === 'two-win-auditory-word-img-matching-item-check') {
         VoiceImpRef.value.videoPlay(
           'Speech-Auditory',
-          `static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/${val.newValue}.mp3`
+          `static/voice/cognitiveAbility/SpeechTraining/Auditory/WordImgMatching/${val.newValue}-tips.mp3`
         )
         localStorage.removeItem('two-win-auditory-word-img-matching-item-check')
       }
 
+      if (val.key === 'tow-win-auditory-word-img-matching-score') {
+        showScoreArea.value = true
+        handleScore(Number(val.newValue))
+        localStorage.removeItem('tow-win-auditory-word-img-matching-score')
+      }
+
       if (val.key === 'tow-win-auditory-word-img-matching-isSubmitting' && val.newValue === 'YES') {
         isSubmitting = true
         emits('gameOver', {
@@ -216,4 +276,12 @@ onMounted(() => {
 })
 </script>
 
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+.score-text {
+  text-shadow:
+    0 3px 0 #b2a98f,
+    0 10px 16px rgba(0, 0, 0, 0.15),
+    0 10px 2px rgba(0, 0, 0, 0.1),
+    0 10px 20px rgba(0, 0, 0, 0.1);
+}
+</style>

+ 11 - 6
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskAuditoryTraining/CATAuditoryTrainingWordImgMatching/topics.json

@@ -1,30 +1,35 @@
 {
-  "question": "屏幕中会出现一个词语,请你从下面的选项中选出与该词语匹配的图片",
+  "question": "请仔细听播放的词语,请你从下面的选项中选出与该词语匹配的图片",
   "topics": [
     {
       "choices": ["杯子", "小碗"],
       "correct": "杯子",
-      "userAnswer": ""
+      "userAnswer": "",
+      "score": ""
     },
     {
       "choices": ["勺子", "筷子", "叉子"],
       "correct": "筷子",
-      "userAnswer": ""
+      "userAnswer": "",
+      "score": ""
     },
     {
       "choices": ["笔", "橡皮", "书包", "书"],
       "correct": "书",
-      "userAnswer": ""
+      "userAnswer": "",
+      "score": ""
     },
     {
       "choices": ["冰箱", "茶桌", "电视", "衣柜", "床"],
       "correct": "电视",
-      "userAnswer": ""
+      "userAnswer": "",
+      "score": ""
     },
     {
       "choices": ["小草", "松树", "玫瑰", "向日葵", "苹果", "花花"],
       "correct": "松树",
-      "userAnswer": ""
+      "userAnswer": "",
+      "score": ""
     }
   ]
 }