|
@@ -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>
|