97 lines
3.7 KiB
Vue
97 lines
3.7 KiB
Vue
|
|
<script setup lang="ts">
|
|||
|
|
import type { QuestionContent, UiTemplateType } from '../types'
|
|||
|
|
import { computed } from 'vue'
|
|||
|
|
|
|||
|
|
const props = defineProps<{
|
|||
|
|
template: UiTemplateType
|
|||
|
|
content: QuestionContent
|
|||
|
|
}>()
|
|||
|
|
|
|||
|
|
const pinyinChars = computed(() => {
|
|||
|
|
if (props.template === 'TEMPLATE_WORD_DICTATION' && props.content.pinyin) {
|
|||
|
|
return props.content.pinyin.split(' ')
|
|||
|
|
}
|
|||
|
|
return []
|
|||
|
|
})
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<template>
|
|||
|
|
<div class="min-h-[400px] w-full flex items-center justify-center p-10">
|
|||
|
|
<!-- 模板A: 汉字听写-提示 (拼音+提示) -->
|
|||
|
|
<div v-if="template === 'TEMPLATE_DICTATION_HINT'" class="text-center">
|
|||
|
|
<div class="mb-6 inline-block text-[120px] text-red-500 font-bold leading-none" style="text-shadow: 2px 2px 4px rgba(0,0,0,0.1);">
|
|||
|
|
“{{ content.pinyin }}”
|
|||
|
|
</div>
|
|||
|
|
<!-- <div class="text-4xl text-gray-800 font-bold">
|
|||
|
|
{{ content.hint }}
|
|||
|
|
</div> -->
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 模板B: 汉字听写-同音字 (大字) -->
|
|||
|
|
<div v-else-if="template === 'TEMPLATE_DICTATION_HOMOPHONE'" class="text-center">
|
|||
|
|
<div class="text-[100px] text-red-600 font-bold">
|
|||
|
|
“{{ content.mainText }}”
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 模板C: 汉字加一加 (提示+部件) -->
|
|||
|
|
<div v-else-if="template === 'TEMPLATE_COMPONENT_ADD'" class="text-center">
|
|||
|
|
<div class="text-[100px] text-red-600 font-bold">
|
|||
|
|
{{ content.component }}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 模板D: 词语听写 (拼音+提示) -->
|
|||
|
|
<div v-else-if="template === 'TEMPLATE_WORD_DICTATION'" class="flex flex-col items-center">
|
|||
|
|
<div class="mb-8 flex flex-wrap justify-center gap-6">
|
|||
|
|
<div
|
|||
|
|
v-for="(char, index) in pinyinChars"
|
|||
|
|
:key="index"
|
|||
|
|
class="relative h-32 w-32 flex select-none items-center justify-center border-2 border-red-500 bg-white"
|
|||
|
|
>
|
|||
|
|
<!-- 米字格背景 -->
|
|||
|
|
<div class="pointer-events-none absolute inset-0 z-0 h-full w-full">
|
|||
|
|
<!-- 横虚线 -->
|
|||
|
|
<div class="absolute left-0 top-1/2 h-[1px] w-full border-t border-red-400 border-dashed opacity-60" />
|
|||
|
|
<!-- 竖虚线 -->
|
|||
|
|
<div class="absolute left-1/2 top-0 h-full w-[1px] border-l border-red-400 border-dashed opacity-60" />
|
|||
|
|
<!-- 斜虚线 (SVG) -->
|
|||
|
|
<svg width="100%" height="100%" class="absolute inset-0 opacity-60">
|
|||
|
|
<line x1="0" y1="0" x2="100%" y2="100%" stroke="#f87171" stroke-width="1" stroke-dasharray="4 2" />
|
|||
|
|
<line x1="100%" y1="0" x2="0" y2="100%" stroke="#f87171" stroke-width="1" stroke-dasharray="4 2" />
|
|||
|
|
</svg>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 文字 -->
|
|||
|
|
<span class="z-10 text-5xl text-gray-800 font-bold font-sans">{{ char }}</span>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 模板E: 成语-文字要求 -->
|
|||
|
|
<div v-else-if="template === 'TEMPLATE_IDIOM_TEXT_REQ'" class="text-center">
|
|||
|
|
<div class="mb-8 text-4xl text-gray-800 font-bold">
|
|||
|
|
{{ content.requirement }}
|
|||
|
|
</div>
|
|||
|
|
<!-- <div class="rounded bg-gray-100 px-4 py-2 text-xl text-gray-500">
|
|||
|
|
示例:{{ content.example }}
|
|||
|
|
</div> -->
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<!-- 模板F: 成语-看图 (使用Div占位) -->
|
|||
|
|
<div v-else-if="template === 'TEMPLATE_IDIOM_IMAGE'" class="flex flex-col items-center text-center">
|
|||
|
|
<div class="mb-6 h-60 w-80 flex items-center justify-center">
|
|||
|
|
<!-- <span class="text-gray-400">图片展示区域<br></span> -->
|
|||
|
|
<img :src="content.image" alt="idiom image" class="h-full w-full object-contain">
|
|||
|
|
</div>
|
|||
|
|
<!-- <div class="text-xl text-gray-600 font-bold">
|
|||
|
|
提示:{{ content.hint }}
|
|||
|
|
</div> -->
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div v-else class="text-red-500">
|
|||
|
|
未知的题目模板: {{ template }}
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</template>
|