Bläddra i källkod

常规视康训练公共文件修改

周玉佂 1 vecka sedan
förälder
incheckning
9ebab9e79d

BIN
public/static/image/cognitiveAbility/SpeechTraining/Options-Blank.png


BIN
public/static/image/cognitiveAbility/SpeechTraining/Options-right.png


+ 231 - 141
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskVisualTraining/components/essay/index.vue

@@ -1,47 +1,110 @@
 <template>
   <!--  <my-full-screen-dialog ref="openDialogRef" close-color="#0F4DD8" @close-dialog="handleClose">-->
-  <div class="adl-container w-full h-full flex-center text-[#134FA4]">
+  <div v-if="isMainWin" class="adl-container w-full h-full flex-center text-[#134FA4]">
     <div class="center-area w-[90%] h-[90%]">
       <div
-        class="child-container bg-[#ffffff] bor-radius-[10] w-[1360px] h-[860px] mt-[100px] flex flex-col justify-center items-center gap-y-[30px] absolute left-[500px]"
+        class="child-container bg-[#ffffff] bor-radius-[10] w-[80%] h-[90%] mt-[0%] left-[12%] flex flex-col justify-center items-center gap-y-[30px] absolute"
       >
+        <h1 class="text-[32px] w-[95%] absolute top-[-10px] left-[20px]">
+          屏幕中会出现一张图片,请你从下面的选项中选出与该图片匹配的词语。
+        </h1>
         <div class="bg-1">
-          <div class="bg-1 text-[68px] w-[80%] absolute top-[30px] left-[550px] color-[#333333]">
-            <div class="question-img w-[290px] h-[290px] text-[186px]">
-              {{ onceData.question }}
+          <div class="bg-1 text-[68px] w-[80%] absolute top-[29px] left-[38%] color-[#333333]">
+            <div class="w-[990px] h-[290px] text-[186px]">
+              <!--              {{ onceData.question }}-->
+              <el-image
+                :src="onceData.question"
+                fit="contain"
+                style="width: 285px; height: 210px"
+                class="absolute top-[50px]"
+              />
             </div>
           </div>
         </div>
         <div
           id="myButton"
-          class="divMain absolute left-[165px] top-[305px] flex flex-wrap flex-row gap-x-[20px] mt-[50px] w-[1100px]"
-          :class="onceData.choices && onceData.choices.length < 3 ? 'flex-center' : ''"
+          class="divMain absolute left-[8%] top-[305px] flex flex-wrap flex-row gap-x-[20px] mt-[50px] w-[1600px] h-[300px]"
+          :class="checkItems && checkItems.length < 3 ? 'flex-center' : ''"
         >
-          <div v-for="(it, index) in onceData.choices" :key="it">
-            <div class="text-[80px] w-[350px] flex flex-wrap flex-row justify-between">
+          <div
+            v-for="(it, index) in checkItems"
+            :key="it"
+            :class="checkItems && checkItems.length <= 3 ? 'mt-[130px]' : ''"
+          >
+            <div class="text-[80px] w-[500px] h-[280px] flex flex-wrap flex-row justify-between">
               <!--              <div class="w-[450px] sab ml-[115px] mt-[30px] flex flex-wrap flex-row justify-between">-->
               <div
                 class="bg-[#000] w-[120px] h-[120px] flex-center"
-                :class="[it.active ? 'active' : 'normal']"
-                @click="checkItemFn(it, index)"
+                :class="[index === flagFlag ? 'active' : 'normal']"
+                @click="checkItemFn(it, isMainWin ? 1 : 0)"
               ></div>
-              <span class="color-[#000] fw-700 line-height-[155px]">{{ chengList[index] }}.</span
-              ><span class="color-[#333333] line-height-[155px] fw-700 mr-[60px]"> {{ it.name }}</span>
+              <!--                <span class="color-[#000] fw-700 line-height-[5px]">{{ chengList[index] }}.</span>-->
+              <!--              <el-image :src="it" fit="contain" style="width: 255px; height: 150px" class="absolute top-[-45px]" />-->
+              <span class="color-[#333333] line-height-[155px] fw-700 mr-[100px]"> {{ it }}</span>
             </div>
-            <!--            </div>-->
-            <div
-              class="question-imgStart w-[290px] h-[90px] text-[186px] absolute bottom-[-170px] left-[405px]"
-              @click="handleClick(it, index)"
-            ></div>
+            <el-image
+              v-if="confirmation"
+              src="/static/image/cognitiveAbility/SpeechTraining/next.png"
+              fit="contain"
+              class="!absolute w-[290px] h-[90px] bottom-[-100%] left-[37%] cursor-pointer hover:scale-101"
+              @click="handleClick(it, index, isMainWin ? 1 : 0)"
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div v-else class="adl-container w-full h-full flex-center text-[#134FA4]">
+    <div class="center-area w-[90%] h-[90%]">
+      <div
+        class="child-container bg-[#ffffff] bor-radius-[10] w-[80%] h-[90%] mt-[0%] flex flex-col justify-center items-center gap-y-[30px] absolute left-[12%]"
+      >
+        <div class="bg-1">
+          <div class="bg-1 text-[68px] w-[80%] absolute top-[10px] left-[38%] color-[#333333]">
+            <div class="w-[990px] h-[290px] text-[186px]">
+              <!--              {{ onceData.question }}-->
+              <el-image
+                :src="onceData.question"
+                fit="contain"
+                style="width: 285px; height: 210px"
+                class="absolute top-[50px]"
+              />
+            </div>
+          </div>
+        </div>
+        <div
+          id="myButton"
+          class="divMain absolute left-[8%] top-[305px] flex flex-wrap flex-row gap-x-[20px] mt-[50px] w-[1600px] h-[300px]"
+          :class="checkItems && checkItems.length < 3 ? 'flex-center' : ''"
+        >
+          <div
+            v-for="(it, index) in checkItems"
+            :key="it"
+            :class="checkItems && checkItems.length <= 3 ? 'mt-[130px]' : ''"
+          >
+            <div class="text-[80px] w-[500px] h-[280px] flex flex-wrap flex-row justify-between">
+              <!--              <div class="w-[450px] sab ml-[115px] mt-[30px] flex flex-wrap flex-row justify-between">-->
+              <div
+                class="bg-[#000] w-[120px] h-[120px] flex-center"
+                :class="[index === flagFlag ? 'active' : 'normal']"
+                @click="checkItemFn(it, isMainWin ? 1 : 0)"
+              ></div>
+              <!--                <span class="color-[#000] fw-700 line-height-[5px]">{{ chengList[index] }}.</span>-->
+              <!--              <el-image :src="it" fit="contain" style="width: 255px; height: 150px" class="absolute top-[-45px]" />-->
+              <span class="color-[#333333] line-height-[155px] fw-700 mr-[100px]"> {{ it }}</span>
+            </div>
+            <el-image
+              v-if="!confirmation"
+              src="/static/image/cognitiveAbility/SpeechTraining/verify-bg.png"
+              fit="contain"
+              class="!absolute w-[290px] h-[90px] bottom-[-125%] left-[40%] cursor-pointer hover:scale-101"
+              @click="handleClick(it, index, isMainWin ? 1 : 0)"
+            />
           </div>
         </div>
       </div>
     </div>
   </div>
-
-  <!--  <div class="dialog-footer text-right absolute bottom-[0px] right-[0px]">-->
-  <!--    <el-button type="text" @click="handleSubmit">结束测验</el-button>-->
-  <!--  </div>-->
   <VoiceImp ref="VoiceImpRef" />
   <!--  </my-full-screen-dialog>-->
 </template>
@@ -54,7 +117,7 @@
  * 编写者: JutarryWu
  */
 import { getCurrentInstance, ref } from 'vue'
-import { getRandomInt } from '@/utils'
+import { getRandomInt, isJSON } from '@/utils'
 import AchievementAPI from '@/api/tester/rehabilitation/training/achievement'
 import { RTPlanMgrQuery } from '@/api/tester/rehabilitation/training/plain'
 import { useUserStore } from '@/store'
@@ -68,18 +131,18 @@ interface LevelData {
 }
 interface OnceItem {
   question: string
-  active: boolean
-  questions: string[]
   choices: string[]
   answer: string
+  correct: string
+  userAnswer: string
 }
-const gameData = ref(Topics as OnceItem[][])
+const gameData = ref(Topics as OnceItem[])
 // 当前游戏等级
 let currentLevel = 0
 // 得分列表
 const scoreList = [10, 30, 60, 100, 150, 210]
 
-const chengList = ref(['1', '2', '3', '4'])
+const chengList = ref(['1', '2', '3', '4', '5', '6', '7', '8', '9'])
 // 响应开始时间戳
 let responseStartTime = 0
 // 游戏收集的数据
@@ -90,11 +153,10 @@ let gameStartTime_record = 0
 // 游戏结束时间
 let gameEndTime = 0
 // 最大游戏等级 6
-const maxLevel = 2
+const maxLevel = 0
 // 当前试次
 let currentNumber = 0
 // 每个等级的最大试次 15
-const maxNumber = 3
 let timerId: any
 const $emits = defineEmits(['close'])
 const openDialogRef = ref()
@@ -103,89 +165,78 @@ const VoiceImpRef = ref()
 const handleClose = (done: () => void) => {
   $emits('close', '')
 }
-
+const isMainWin = ref(false)
 const instance = getCurrentInstance()
 const planInfo = ref<RTPlanMgrQuery>()
 const userStore = useUserStore()
 // 当前试次的游戏图片数据
 const onceData = ref({} as OnceItem)
-const handleClick = (answer: string) => {
-  console.log(answer)
-  const correct = false
-  // const correct = onceData.value.answer === answer
-  // VoiceImpRef.value.videoPlay('click')
-  // setTimeout(() => {
-  //   if (correct) {
-  //     console.log(VoiceImpRef.value, 'hbbbbbbbbbbbbbbbbbbbbbbbbbdf=============>')
-  //     if (VoiceImpRef.value) {
-  //       VoiceImpRef.value.videoPlay('right')
-  //     }
-  //   } else {
-  //     if (VoiceImpRef.value) {
-  //       VoiceImpRef.value.videoPlay('error')
-  //     }
-  //   }
-  // }, 200)
-  // 收集当前试次的用户操作数据
-  gameList.push({
-    level: currentLevel,
-    correct: correct,
-    score: correct ? scoreList[currentLevel] : 0,
-    responseEndTime: performance.now(),
-    responseStartTime: responseStartTime
-  })
-  console.log(gameList)
+const checkItems = ref([])
+const sumbitData = ref([])
 
+const confirmation = ref(false)
+const flagFlag = ref(-1) //选中标志
+const handleClick = (answer: string, index, flag) => {
   // 开始下一次
-  nextOnce()
+  if (flag === 1) {
+    nextOnce()
+    confirmation.value = false
+    flagFlag.value = -1
+    localStorage.setItem('two-win-Visual-item-confirmation', 'false')
+    localStorage.setItem('two-win-Visual-item-next', 'true')
+  } else {
+    console.log(answer, '用户操作数据', index, flag)
+    const correct = false
+    confirmation.value = true
+    localStorage.setItem('two-win-Visual-item-confirmation', 'true')
+    // const correct = onceData.value.answer === answer
+    // VoiceImpRef.value.videoPlay('click')
+    // setTimeout(() => {
+    //   if (correct) {
+    //     console.log(VoiceImpRef.value, 'hbbbbbbbbbbbbbbbbbbbbbbbbbdf=============>')
+    //     if (VoiceImpRef.value) {
+    //       VoiceImpRef.value.videoPlay('right')
+    //     }
+    //   } else {
+    //     if (VoiceImpRef.value) {
+    //       VoiceImpRef.value.videoPlay('error')
+    //     }
+    //   }
+    // }, 200)
+    console.log(onceData.value, 'onceData.value')
+    let params = {
+      question: '接下来会给你听一些声音,请在这些声音中选择出屏幕中呈现的词语',
+      choices: ['雷电', '狗叫', '葡萄'],
+      correct: '葡萄',
+      userAnswer: ''
+    }
+    // 收集当前试次的用户操作数据
+    gameList.push(params)
+    console.log(gameList)
+    localStorage.setItem('two-win-Visual-item-submitList', JSON.stringify(gameList))
+  }
 }
-const checkItemFn = (item: any, index: number) => {
+const checkItemFn = (item: any, flag: number = 0) => {
   // if (modeSelect.value === 0) {
-  onceData.value.choices.forEach((item2) => {
-    item2.active = false
+  console.log(item, '参数')
+  if (flag === 1) return
+  confirmation.value = false
+  let tempIndex = -1
+  console.log()
+  checkItems.value.forEach((item2, index) => {
+    if (item2 === item) tempIndex = index
   })
-  //   VoiceImpRef.value.videoPlay()
-  console.log(item)
-  item.active = !item.active
-  //   itemActive.value = item.key
-  // }
+  flagFlag.value = tempIndex
+  if (!isMainWin.value) {
+    localStorage.setItem('two-win-Visual-item-List', JSON.stringify(item))
+    localStorage.setItem('two-win-Visual-item-confirmation', 'false')
+  }
 }
 const nextOnce = () => {
-  console.log(onceData.value.choices, 'onceData392')
   gameEndTime = performance.now()
   const gameDuration = gameEndTime - gameStartTime
-  console.log(gameDuration, 'gameDuration')
-  console.log(gameEndTime, 'gameEndTime')
-  console.log(gameStartTime, 'gameStartTime')
-  const currentLevelList = gameList.filter((it) => it.level === currentLevel)
-  // 当前等级进行 10 个试次以上时,计算正确率
-  if (currentLevelList.length >= 3) {
-    // 当前等级正确试次个数
-    const count = currentLevelList.reduce((acc, curr) => {
-      if (curr.correct) {
-        acc++
-      }
-      return acc
-    }, 0)
-    // 当前等级正确率
-    const accuracy = (count / currentLevelList.length) * 100
-    // 升降级规则:正确率达到80%难度升级,低于40%降级
-    if (accuracy >= 80) {
-      if (currentLevel < maxLevel) {
-        currentLevel++
-        // 删除升级之后的已有数据
-        gameList = gameList.filter((it) => it.level !== currentLevel)
-        // 重置当前等级试次索引
-        currentNumber = 0
-        console.log('80%难度升级')
-      }
-    } else if (accuracy < 40) {
-      sendData()
-      return
-    }
-  }
-
   // 如果当前等级的试次小于最大试次,则试次加一,否则应该进入下一等级
+  let maxNumber = gameData.value.length - 1
   if (currentNumber < maxNumber) {
     currentNumber++
   } else {
@@ -199,6 +250,7 @@ const nextOnce = () => {
     } else {
       // 游戏结束
       console.log('游戏结束2')
+      console.log(gameList, '用户操作总数据')
       sendData()
       return
     }
@@ -209,6 +261,7 @@ const nextOnce = () => {
 }
 // 发送请求
 const sendData = () => {
+  console.log(sumbitData.value, '用户操作总数据主屏')
   if (planInfo.value) {
     // 计算正确反应数和总反应时
     let { correctCount, totalResponseTime, totalScore } = gameList.reduce(
@@ -233,40 +286,40 @@ const sendData = () => {
 
     const { gameId, gameName, id: planId } = planInfo.value
     const data = {
-      finish: '1',
-      gameId,
-      gameName,
-      paramList: [
-        {
-          code: 'score',
-          name: '得分',
-          value: totalScore
-        },
-        {
-          code: 'correctCount',
-          name: '正确反应数',
-          value: correctCount
-        },
-        {
-          code: 'avrResponseTime',
-          name: '平均反应时',
-          value: avrResponseTime
-        },
-        {
-          code: 'avrResponseTime',
-          name: '最大难度',
-          value: currentLevel + 1
-        },
-        {
-          code: 'gameTotalTime',
-          name: '游戏总时长',
-          value: Date.now() - gameStartTime_record / 1000
-        }
-      ],
-      planId,
-      gamelevel: currentLevel + 1,
-      score: totalScore,
-      userId: userStore.user.id
+      // finish: '1',
+      // gameId,
+      // gameName,
+      // paramList: [
+      //   {
+      //     code: 'score',
+      //     name: '得分',
+      //     value: totalScore
+      //   },
+      //   {
+      //     code: 'correctCount',
+      //     name: '正确反应数',
+      //     value: correctCount
+      //   },
+      //   {
+      //     code: 'avrResponseTime',
+      //     name: '平均反应时',
+      //     value: avrResponseTime
+      //   },
+      //   {
+      //     code: 'avrResponseTime',
+      //     name: '最大难度',
+      //     value: currentLevel + 1
+      //   },
+      //   {
+      //     code: 'gameTotalTime',
+      //     name: '游戏总时长',
+      //     value: Date.now() - gameStartTime_record / 1000
+      //   }
+      // ],
+      // planId,
+      // gamelevel: currentLevel + 1,
+      // score: totalScore,
+      // userId: userStore.user.id
     }
     console.log('发送数据', data)
 
@@ -288,7 +341,8 @@ const sendData = () => {
 }
 async function exec() {
   // openDialogRef.value.openDialog()
-  const tempPlan = sessionStorage.getItem('currentPlanInfo')
+  isMainWin.value = window.location.href.includes('win=main') // 主副屏标志
+  const tempPlan = sessionStorage.getItem('currentPlanInfo') // 取患者数据
   if (tempPlan) {
     planInfo.value = JSON.parse(tempPlan)
   }
@@ -310,14 +364,13 @@ async function exec() {
   })
 }
 const setOnceData = () => {
-  // currentLevel
-  // currentNumber
-  // gameMode
   // 记录响应开始时间
   responseStartTime = performance.now()
-  onceData.value = gameData.value[currentLevel][currentNumber]
+  // onceData.value = gameData.value[currentLevel][currentNumber]
+  onceData.value = gameData.value[currentNumber]
   console.log(currentLevel, currentNumber, '1.2')
-  onceData.value.choices = shuffleArray(onceData.value.choices)
+  // onceData.value.choices = shuffleArray(onceData.value.choices)
+  checkItems.value = onceData.value.choices
 }
 // 随机排列数组
 function shuffleArray(array: any) {
@@ -330,6 +383,33 @@ function shuffleArray(array: any) {
 }
 onMounted(() => {
   exec()
+  window.addEventListener('storage', (val) => {
+    if (isMainWin.value) {
+      if (val.key === 'two-win-Visual-item-List') {
+        let tempVal = JSON.parse(localStorage.getItem('two-win-Visual-item-List'))
+        checkItemFn(tempVal, 0)
+        localStorage.removeItem('two-win-Visual-item-List')
+      }
+      if (val.key === 'two-win-Visual-item-confirmation') {
+        let a = localStorage.getItem('two-win-Visual-item-confirmation')
+        confirmation.value = a == 'true'
+        // flagFlag.value = -1
+        localStorage.removeItem('two-win-Visual-item-confirmation')
+      }
+      if (val.key === 'two-win-Visual-item-submitList') {
+        sumbitData.value = JSON.parse(localStorage.getItem('two-win-Visual-item-submitList'))
+        localStorage.removeItem('two-win-Visual-item-submitList')
+        console.log(sumbitData.value, '主屏接收用户操作数据')
+      }
+    } else {
+      console.log('')
+      if (val.key === 'two-win-Visual-item-next') {
+        nextOnce()
+        flagFlag.value = -1
+        localStorage.removeItem('two-win-Visual-item-next')
+      }
+    }
+  })
 })
 </script>
 
@@ -346,8 +426,18 @@ onMounted(() => {
     //font-family: 楷体;
     text-align: center;
   }
-  .question-imgStart {
-    background-image: url('/static/image/cognitiveAbility/SpeechTraining/verify-bg.png');
+  .question-imgStartZ {
+    cursor: pointer;
+    background-image: url('/static/image/cognitiveAbility/SpeechTraining/next.png');
+    background-size: 100% 100%;
+    background-position: center center;
+    background-repeat: repeat;
+    //font-family: 楷体;
+    text-align: center;
+  }
+  .question-imgStartF {
+    cursor: pointer;
+    background-image: url('/static/image/cognitiveAbility/SpeechTraining/Visual/verify-bg.png');
     background-size: 100% 100%;
     background-position: center center;
     background-repeat: repeat;
@@ -355,11 +445,11 @@ onMounted(() => {
     text-align: center;
   }
   .active {
-    background: url('/static/image/cognitiveAbility/SpeechTraining/Visual/Options-right.png') no-repeat 0 0 / 100% 100%;
+    background: url('/static/image/cognitiveAbility/SpeechTraining/Options-right.png') no-repeat 0 0 / 100% 100%;
     //background-position: 90% 54%; /* 可选,让图片居中对齐 */
   }
   .normal {
-    background: url('/static/image/cognitiveAbility/SpeechTraining/Visual/Options-Blank.png') no-repeat 0 0 / 70% 70%;
+    background: url('/static/image/cognitiveAbility/SpeechTraining/Options-Blank.png') no-repeat 0 0 / 70% 70%;
     background-position: 10% 90%; /* 可选,让图片居中对齐 */
   }
 }

+ 55 - 54
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskVisualTraining/components/essay/topics.json

@@ -1,56 +1,57 @@
 [
-  [
-    {
-      "question": "手",
-      "active": false,
-      "questions": [""],
-      "choices": [
-        {
-          "name":"手",
-          "active": false
-        }, {
-          "name":"脚",
-          "active": false
-        }],
-      "answer": "手"
-    },
-    {
-      "question": "梨",
-      "active": false,
-      "questions": [""],
-      "choices": [
-        {
-          "name":"柚",
-          "active": false
-        }, {
-          "name":"香",
-          "active": false
-        }, {
-          "name":"梨",
-          "active": false
-        }],
-      "answer": "梨"
-    },
-    {
-      "question": "纸",
-      "active": false,
-      "questions": [""],
-      "choices": [
-        {
-          "name":"笔",
-          "active": false
-        }, {
-          "name":"纸",
-          "active": false
-        }, {
-          "name":"本",
-          "active": false
-        }, {
-          "name":"书",
-          "active": false
-        }],
-      "answer": "纸"
-    }
-  ]
+  {
+    "question": "/static/image/cognitiveAbility/SpeechTraining/Visual/yagao.png",
+    "choices": [
+      "牙刷",
+      "牙膏"
+    ],
+    "correct": "牙膏",
+    "userAnswer": ""
+  },
+  {
+    "question": "/static/image/cognitiveAbility/SpeechTraining/Visual/chabei.jpg",
+    "choices": [
+      "碗",
+      "筷子",
+      "茶杯"
+    ],
+    "correct": "茶杯",
+    "userAnswer": ""
+  },
+  {
+    "question": "/static/image/cognitiveAbility/SpeechTraining/Visual/shubao.png",
+    "choices": [
+      "书包",
+      "本子",
+      "笔",
+      "铅笔盒"
+    ],
+    "correct": "书包",
+    "userAnswer": ""
+  },
+  {
+    "question": "/static/image/cognitiveAbility/SpeechTraining/Visual/pingguo.png",
+    "choices": [
+      "香蕉",
+      "葡萄",
+      "橘子",
+      "苹果",
+      "柚子"
+    ],
+    "correct": "苹果",
+    "userAnswer": ""
+  },
+  {
+    "question": "/static/image/cognitiveAbility/SpeechTraining/Visual/niunai.png",
+    "choices": [
+      "牛奶",
+      "面包",
+      "鸡蛋",
+      "米饭",
+      "饼干",
+      "可乐"
+    ],
+    "correct": "牙膏",
+    "userAnswer": ""
+  }
 ]
-

+ 1 - 0
src/views/tester/components/RehabilitationEvaluation/CognitiveAbilityTask/CognitiveAbilityTaskVisualTraining/index.vue

@@ -69,6 +69,7 @@
     <map-word v-if="gameActive === '3'" @close="handleClose" />
     <diagram-map v-if="gameActive === '4'" @close="handleClose" />
     <execute v-if="gameActive === '5'" @close="handleClose" />
+    <essay v-if="gameActive === '6'" @close="handleClose" />
     <VoiceImp ref="VoiceImpRef" />
   </section>
 </template>