diff --git a/apps/admin/src/assets/imgs/q5-img.png b/apps/admin/src/assets/imgs/q5-img.png new file mode 100644 index 0000000..111116d Binary files /dev/null and b/apps/admin/src/assets/imgs/q5-img.png differ diff --git a/apps/admin/src/assets/imgs/tianzige.svg b/apps/admin/src/assets/imgs/tianzige.svg new file mode 100644 index 0000000..d1596fb --- /dev/null +++ b/apps/admin/src/assets/imgs/tianzige.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/apps/admin/src/constants/business.ts b/apps/admin/src/constants/business.ts index 3f6a0dd..893b5d4 100644 --- a/apps/admin/src/constants/business.ts +++ b/apps/admin/src/constants/business.ts @@ -26,4 +26,24 @@ export const menuIconTypeRecord: Record = { 2: '本地图标', } +/** + * 题目分数类型 + */ +export const scoreTypeRecord: Record = { + 1: '固定分数', + 2: '答题个数', +} + +/** + * 轮次类型 + */ +export const roundTypeRecord: Record = { + 1: '题包环节', + 2: '加时环节', +} + +export const roundTypeOptions = transformRecordToOption(roundTypeRecord) + +export const scoreTypeOptions = transformRecordToOption(scoreTypeRecord) + export const menuIconTypeOptions = transformRecordToOption(menuIconTypeRecord) diff --git a/apps/admin/src/router/elegant/imports.ts b/apps/admin/src/router/elegant/imports.ts index 3188df6..6421027 100644 --- a/apps/admin/src/router/elegant/imports.ts +++ b/apps/admin/src/router/elegant/imports.ts @@ -29,4 +29,5 @@ export const views: Record Promise import("@/views/rank/rank-list/index.vue"), results: () => import("@/views/results/index.vue"), template: () => import("@/views/template/index.vue"), + user: () => import("@/views/user/index.vue"), }; diff --git a/apps/admin/src/router/elegant/routes.ts b/apps/admin/src/router/elegant/routes.ts index 1724702..6f7bb9b 100644 --- a/apps/admin/src/router/elegant/routes.ts +++ b/apps/admin/src/router/elegant/routes.ts @@ -188,5 +188,16 @@ export const generatedRoutes: GeneratedRoute[] = [ icon: 'material-symbols:settings-motion-mode-outline-rounded', order: 4 } + }, + { + name: 'user', + path: '/user', + component: 'layout.blank$view.user', + meta: { + title: 'user', + i18nKey: 'route.user', + icon: 'material-symbols:account-circle', + order: 6 + } } ]; diff --git a/apps/admin/src/router/elegant/transform.ts b/apps/admin/src/router/elegant/transform.ts index 162a3bf..68c225f 100644 --- a/apps/admin/src/router/elegant/transform.ts +++ b/apps/admin/src/router/elegant/transform.ts @@ -178,7 +178,8 @@ const routeMap: RouteMap = { "rank_rank-detail": "/rank/rank-detail", "rank_rank-list": "/rank/rank-list", "results": "/results", - "template": "/template" + "template": "/template", + "user": "/user" }; /** diff --git a/apps/admin/src/typings/api/Competition.d.ts b/apps/admin/src/typings/api/Competition.d.ts new file mode 100644 index 0000000..3dc34a1 --- /dev/null +++ b/apps/admin/src/typings/api/Competition.d.ts @@ -0,0 +1,56 @@ +/** + * Namespace Api + * + * All backend api type + */ +declare namespace Api { + namespace Competition { + /** common params of paginating */ + interface PaginatingCommonParams { + /** current page number */ + current: number + /** page size */ + size: number + /** total count */ + total: number + } + + /** common params of paginating query list data */ + interface PaginatingQueryRecord extends PaginatingCommonParams { + records: T[] + } + + /** common search params of table */ + type CommonSearchParams = Pick + + /** + * enable status + * + * - "1": enabled + * - "2": disabled + */ + type EnableStatus = '1' | '2' + + /** question score type */ + type QuestionScoreType = '1' | '2' /** 固定分数 | 答题个数 */ + + /** competition round type */ + type CompetitionRoundType = '1' | '2' /** 题包环节 | 加时环节 */ + + /** common record */ + type CommonRecord = { + /** record id */ + id: number + /** record creator */ + createBy: string + /** record create time */ + createTime: string + /** record updater */ + updateBy: string + /** record update time */ + updateTime: string + /** record status */ + status: EnableStatus | null + } & T + } +} diff --git a/apps/admin/src/typings/components.d.ts b/apps/admin/src/typings/components.d.ts index 1af4d1a..4a89675 100644 --- a/apps/admin/src/typings/components.d.ts +++ b/apps/admin/src/typings/components.d.ts @@ -47,10 +47,12 @@ declare module 'vue' { IconIcOutlineAccessTime: typeof import('~icons/ic/outline-access-time')['default'] IconIcOutlineAddToPhotos: typeof import('~icons/ic/outline-add-to-photos')['default'] IconIcOutlineArchive: typeof import('~icons/ic/outline-archive')['default'] + IconIcOutlineAttachMoney: typeof import('~icons/ic/outline-attach-money')['default'] IconIcOutlineDelete: typeof import('~icons/ic/outline-delete')['default'] IconIcOutlineFolderOff: typeof import('~icons/ic/outline-folder-off')['default'] IconIcOutlineFormatListNumbered: typeof import('~icons/ic/outline-format-list-numbered')['default'] IconIcOutlineTimer: typeof import('~icons/ic/outline-timer')['default'] + IconIcOutlineTitle: typeof import('~icons/ic/outline-title')['default'] IconIcRoundAccessTime: typeof import('~icons/ic/round-access-time')['default'] IconIcRoundArrowBack: typeof import('~icons/ic/round-arrow-back')['default'] IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default'] @@ -67,6 +69,7 @@ declare module 'vue' { IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default'] IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default'] IconMdiRefresh: typeof import('~icons/mdi/refresh')['default'] + 'IconStreamlineSharp:typeAreaRemix': typeof import('~icons/streamline-sharp/type-area-remix')['default'] IconTooltip: typeof import('./../components/common/icon-tooltip.vue')['default'] IconUilSearch: typeof import('~icons/uil/search')['default'] LangSwitch: typeof import('./../components/common/lang-switch.vue')['default'] @@ -180,10 +183,12 @@ declare global { const IconIcOutlineAccessTime: typeof import('~icons/ic/outline-access-time')['default'] const IconIcOutlineAddToPhotos: typeof import('~icons/ic/outline-add-to-photos')['default'] const IconIcOutlineArchive: typeof import('~icons/ic/outline-archive')['default'] + const IconIcOutlineAttachMoney: typeof import('~icons/ic/outline-attach-money')['default'] const IconIcOutlineDelete: typeof import('~icons/ic/outline-delete')['default'] const IconIcOutlineFolderOff: typeof import('~icons/ic/outline-folder-off')['default'] const IconIcOutlineFormatListNumbered: typeof import('~icons/ic/outline-format-list-numbered')['default'] const IconIcOutlineTimer: typeof import('~icons/ic/outline-timer')['default'] + const IconIcOutlineTitle: typeof import('~icons/ic/outline-title')['default'] const IconIcRoundAccessTime: typeof import('~icons/ic/round-access-time')['default'] const IconIcRoundArrowBack: typeof import('~icons/ic/round-arrow-back')['default'] const IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default'] @@ -200,6 +205,7 @@ declare global { const IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default'] const IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default'] const IconMdiRefresh: typeof import('~icons/mdi/refresh')['default'] + const 'IconStreamlineSharp:typeAreaRemix': typeof import('~icons/streamline-sharp/type-area-remix')['default'] const IconTooltip: typeof import('./../components/common/icon-tooltip.vue')['default'] const IconUilSearch: typeof import('~icons/uil/search')['default'] const LangSwitch: typeof import('./../components/common/lang-switch.vue')['default'] diff --git a/apps/admin/src/typings/elegant-router.d.ts b/apps/admin/src/typings/elegant-router.d.ts index 6c29769..6cb632b 100644 --- a/apps/admin/src/typings/elegant-router.d.ts +++ b/apps/admin/src/typings/elegant-router.d.ts @@ -33,6 +33,7 @@ declare module "@elegant-router/types" { "rank_rank-list": "/rank/rank-list"; "results": "/results"; "template": "/template"; + "user": "/user"; }; /** @@ -75,6 +76,7 @@ declare module "@elegant-router/types" { | "rank" | "results" | "template" + | "user" >; /** @@ -105,6 +107,7 @@ declare module "@elegant-router/types" { | "rank_rank-list" | "results" | "template" + | "user" >; /** diff --git a/apps/admin/src/views/competition/competition-add/index.vue b/apps/admin/src/views/competition/competition-add/index.vue index 2c3e022..7175836 100644 --- a/apps/admin/src/views/competition/competition-add/index.vue +++ b/apps/admin/src/views/competition/competition-add/index.vue @@ -1,9 +1,10 @@ @@ -71,16 +87,15 @@ defineExpose({ validate, reset })
您可以为比赛添加多个阶段的题包,并自定义题目、分值与限时。 -
+
总题数 {{ totalStats.count }}
-
- 总分 - {{ totalStats.score }} -
总时长 @@ -89,7 +104,10 @@ defineExpose({ validate, reset })
- + @@ -98,7 +116,10 @@ defineExpose({ validate, reset })
-
+
@@ -112,7 +133,10 @@ defineExpose({ validate, reset })
-
+
@@ -121,23 +145,28 @@ defineExpose({ validate, reset })
+ + {{ roundTypeOptions.find((item) => item.value === round.roundType)?.label || '未知类型' }} +
-
+
{{ round.questions.length }} 题
-
+ +
{{ getRoundTime(roundIndex) }} 秒
@@ -146,12 +175,18 @@ defineExpose({ validate, reset })
- + - + @@ -160,56 +195,73 @@ defineExpose({ validate, reset })
-
+
- {{ String(qIdx + 1).padStart(2, '0') }} +
+
+ +
+ {{ + String(qIdx + 1).padStart(2, '0') }} +
-
- - -
- PTS -
+ 答题时间: S
+ +
+ + 分数规则: + + S +
+ + +
+ + 标题: + +
+ - +
-
+
@@ -235,15 +287,30 @@ defineExpose({ validate, reset }) + + + - + 生成题包卡片
+ + diff --git a/apps/admin/src/views/competition/competition-add/modules/useBasicInfo.ts b/apps/admin/src/views/competition/competition-add/modules/useBasicInfo.ts index c234989..aa67237 100644 --- a/apps/admin/src/views/competition/competition-add/modules/useBasicInfo.ts +++ b/apps/admin/src/views/competition/competition-add/modules/useBasicInfo.ts @@ -9,6 +9,7 @@ export interface BasicInfoModel { groupCount: number teamCount: number poster: string + ap: string } export function useBasicInfo(props: any, emit: any) { @@ -94,6 +95,7 @@ export function useBasicInfo(props: any, emit: any) { groupCount: 10, teamCount: 4, poster: '', + ap: '', } } diff --git a/apps/admin/src/views/competition/competition-add/modules/useQuestionConfig.ts b/apps/admin/src/views/competition/competition-add/modules/useQuestionConfig.ts index 00723c8..5bae6ca 100644 --- a/apps/admin/src/views/competition/competition-add/modules/useQuestionConfig.ts +++ b/apps/admin/src/views/competition/competition-add/modules/useQuestionConfig.ts @@ -1,9 +1,13 @@ import { computed } from 'vue' +import { roundTypeOptions, scoreTypeOptions } from '@/constants/business' export interface QuestionItem { + id: string value: string | null score: number time: number + title: string + scoreType: Api.Competition.QuestionScoreType } export interface RoundModel { @@ -12,8 +16,8 @@ export interface RoundModel { questions: QuestionItem[] } -export interface QuestionConfigModel { - rounds: RoundModel[] +function generateId() { + return `q_${Date.now()}_${Math.random().toString(36).slice(2, 9)}` } export function useQuestionConfig(props: any) { @@ -59,14 +63,6 @@ export function useQuestionConfig(props: any) { { label: '极速成语接龙 - 每题20秒', value: 'speed20' }, ] - const scoreOptions = [ - { label: '1分', value: 1 }, - { label: '2分', value: 2 }, - { label: '3分', value: 3 }, - { label: '5分', value: 5 }, - { label: '10分', value: 10 }, - ] - const timeOptions = [ { label: '15s', value: 15 }, { label: '30s', value: 30 }, @@ -76,7 +72,7 @@ export function useQuestionConfig(props: any) { ] // 新增轮次 - function addRound(customName?: string, customCount?: number) { + function addRound(customName?: string, customCount?: number, roundType?: Api.Competition.CompetitionRoundType) { if (!props.modelValue.rounds) { props.modelValue.rounds = [] } @@ -87,10 +83,14 @@ export function useQuestionConfig(props: any) { props.modelValue.rounds.push({ id: `round_${Date.now()}`, name, + roundType: roundType || roundTypeOptions[0].value, questions: Array.from({ length: count }).map(() => ({ + id: generateId(), value: null, score: 5, time: 30, + title: '', + scoreType: scoreTypeOptions[0].value, })), }) } @@ -109,9 +109,12 @@ export function useQuestionConfig(props: any) { const round = props.modelValue.rounds[roundIndex] if (round) { round.questions.push({ + id: generateId(), value: null, score: 5, time: 30, + title: '', + scoreType: scoreTypeOptions[0].value, }) } } @@ -158,7 +161,6 @@ export function useQuestionConfig(props: any) { getRoundTime, totalStats, questionOptions, - scoreOptions, timeOptions, addRound, removeRound, diff --git a/apps/admin/src/views/question-store/modules/CategoryTree copy.vue b/apps/admin/src/views/question-store/modules/CategoryTree copy.vue new file mode 100644 index 0000000..30dc00c --- /dev/null +++ b/apps/admin/src/views/question-store/modules/CategoryTree copy.vue @@ -0,0 +1,385 @@ + + + + + diff --git a/apps/admin/src/views/question-store/modules/CategoryTree.vue b/apps/admin/src/views/question-store/modules/CategoryTree.vue index 30dc00c..e81d101 100644 --- a/apps/admin/src/views/question-store/modules/CategoryTree.vue +++ b/apps/admin/src/views/question-store/modules/CategoryTree.vue @@ -5,12 +5,10 @@ import { NFormItem, NInput, NModal, - NTree, - type TreeOption, useDialog, useMessage, } from 'naive-ui' -import { h, ref, watch } from 'vue' +import { ref, watch } from 'vue' import SvgIcon from '@/components/custom/svg-icon.vue' const emit = defineEmits<{ @@ -20,122 +18,54 @@ const emit = defineEmits<{ const message = useMessage() const dialog = useDialog() -// Mock Data - 模拟分类树数据 -const treeData = ref([ +interface CategoryItem { + key: string + label: string +} + +// Mock Data - 模拟分类列表数据 +const categoryList = ref([ { key: 'stage-1', - label: '汉字听写', - children: [ - { - key: 'q-type-1', - label: '请根据提示书写正确的汉字。', - isLeaf: true, - }, - { - key: 'q-type-2', - label: '请根据拼音书写同音字。', - isLeaf: true, - }, - ], + label: '请根据提示书写正确的汉字。', }, { key: 'stage-2', - label: '汉字加一加', - children: [ - { - key: 'q-type-3', - label: '请写出含有“”的汉字。', - isLeaf: true, - }, - ], + label: '请写出含有“车”的汉字。', }, { key: 'poem', - label: '词语大比拼', - children: [ - { - key: 'q-type-4', - label: '词语听写', - children: [ - { - key: 'q-type-4-1', - label: '请根据拼音书写正确的词语。', - isLeaf: true, - }, - ], - }, - { - key: 'q-type-5', - label: '成语写一写', - children: [ - { - key: 'q-type-5-1', - label: '请写出含有反义字的四字成语。', - isLeaf: true, - }, - { - key: 'q-type-5-2', - label: '请根据图片书写正确的成语', - isLeaf: true, - }, - ], - }, - ], + label: '请根据拼音书写正确的词语。', }, { key: 'stage-extra-1', - label: '换字组成语', - children: [ - { - key: 'q-type-extra-1', - label: '请换一个字,组成新的成语。', - isLeaf: true, - }, - ], + label: '请写出含有反义字的四字成语。', + }, + { + key: 'stage-extra-2', + label: '请根据图片书写正确的成语。', }, ]) -const selectedKeys = ref([]) -const expandedKeys = ref(['root', 'stage-1']) +const selectedKey = ref(null) // Modal State const showCategoryModal = ref(false) -const categoryModalType = ref<1 | 2>(1) // 1级或2级分类 const categoryForm = ref({ name: '' }) +const categoryOperation = ref<'add' | 'edit'>('add') +const currentOperationNode = ref(null) -// 记录当前操作类型:add-root, add-child, edit -const categoryOperation = ref<'add-root' | 'add-child' | 'edit'>('add-root') -// 记录当前操作的目标节点(编辑时为该节点,添加子节点时为父节点) -const currentOperationNode = ref(null) - -// 递归查找节点 -function findNodeByKey(key: string, nodes: TreeOption[]): TreeOption | null { - for (const node of nodes) { - if (node.key === key) - return node - if (node.children) { - const found = findNodeByKey(key, node.children) - if (found) - return found - } - } - return null -} - -watch(selectedKeys, (newKeys) => { - if (newKeys.length === 0) { +watch(selectedKey, (newKey) => { + if (!newKey) { emit('update:category', null) return } - const key = newKeys[0] - const node = findNodeByKey(key, treeData.value) + const node = categoryList.value.find(item => item.key === newKey) if (node) { emit('update:category', { - label: node.label, - level: node.isLeaf ? 3 : 1, - key: node.key, - isLeaf: node.isLeaf, - children: node.children, + ...node, + level: 1, // Treat all as level 1 + isLeaf: true, // Treat all as leaf (container for questions) }) } else { @@ -143,70 +73,39 @@ watch(selectedKeys, (newKeys) => { } }) -// 打开新增根节点弹窗 -function handleAddRootCategory() { - categoryOperation.value = 'add-root' - categoryModalType.value = 1 +function handleSelect(key: string) { + selectedKey.value = key +} + +function handleAddCategory() { + categoryOperation.value = 'add' categoryForm.value.name = '' currentOperationNode.value = null showCategoryModal.value = true } -// 打开新增子节点弹窗 -function handleAddChildCategory(parentNode: TreeOption) { - categoryOperation.value = 'add-child' - categoryModalType.value = 2 // 视为下一级 - categoryForm.value.name = '' - currentOperationNode.value = parentNode - showCategoryModal.value = true -} - -// 打开编辑节点弹窗 -function handleEditCategory(node: TreeOption) { +function handleEditCategory(item: CategoryItem) { categoryOperation.value = 'edit' - categoryForm.value.name = node.label as string - currentOperationNode.value = node + categoryForm.value.name = item.label + currentOperationNode.value = item showCategoryModal.value = true } -// 递归删除节点 如果节点有子节点,无法删除 -function deleteNode(nodes: TreeOption[], key: string | number): boolean { - const index = nodes.findIndex(n => n.key === key) - if (index !== -1) { - // 检查是否有子节点 - if (nodes[index].children && nodes[index].children.length > 0) { - throw new Error('该分类下有子分类,无法删除') - } - nodes.splice(index, 1) - return true - } - for (const node of nodes) { - if (node.children) { - if (deleteNode(node.children, key)) - return true - } - } - return false -} - -function handleDeleteCategory(node: TreeOption) { +function handleDeleteCategory(item: CategoryItem) { dialog.warning({ title: '警告', - content: `确定要删除分类 "${node.label}" 吗?此操作无法撤销。`, + content: `确定要删除分类 "${item.label}" 吗?此操作无法撤销。`, positiveText: '确定', negativeText: '取消', onPositiveClick: () => { - try { - deleteNode(treeData.value, node.key!) - // 如果删除的是当前选中的节点,清空选中 - if (selectedKeys.value.includes(node.key as string)) { - selectedKeys.value = [] + const index = categoryList.value.findIndex(n => n.key === item.key) + if (index !== -1) { + categoryList.value.splice(index, 1) + if (selectedKey.value === item.key) { + selectedKey.value = null } message.success('删除成功') } - catch (error: any) { - message.error(error.message || '删除失败') - } }, }) } @@ -217,137 +116,103 @@ function submitCategory() { return } - if (categoryOperation.value === 'add-root') { - // 新增根节点 - const newKey = `root-${Date.now()}` - treeData.value.push({ + if (categoryOperation.value === 'add') { + const newKey = `cate-${Date.now()}` + categoryList.value.push({ key: newKey, label: categoryForm.value.name, - children: [], }) message.success('分类添加成功') - } - else if (categoryOperation.value === 'add-child' && currentOperationNode.value) { - // 新增子节点 - if (!currentOperationNode.value.children) { - currentOperationNode.value.children = [] - } - // 确保父节点不再是叶子节点,否则无法展开显示子节点 - if (currentOperationNode.value.isLeaf) { - currentOperationNode.value.isLeaf = false - } - const newKey = `node-${Date.now()}` - // 如果是第三级(叶子),标记 isLeaf - currentOperationNode.value.children.push({ - key: newKey, - label: categoryForm.value.name, - isLeaf: true, - }) - // 展开父节点 - if (!expandedKeys.value.includes(currentOperationNode.value.key as string)) { - expandedKeys.value.push(currentOperationNode.value.key as string) - } - message.success('子分类添加成功') + // Automatically select the new category + selectedKey.value = newKey } else if (categoryOperation.value === 'edit' && currentOperationNode.value) { - // 编辑节点 currentOperationNode.value.label = categoryForm.value.name message.success('分类修改成功') + // Trigger update if currently selected + if (selectedKey.value === currentOperationNode.value.key) { + const node = currentOperationNode.value + emit('update:category', { + ...node, + level: 1, + isLeaf: true, + }) + } } showCategoryModal.value = false } - -// Tree Rendering -function renderPrefix({ option }: { option: TreeOption }) { - // 根据层级或类型显示不同图标 - if (option.children && option.children.length > 0) { - return h(SvgIcon, { icon: 'carbon:folder', class: 'text-gray-400 text-lg' }) - } - // 如果明确标记为叶子节点,或者没有 children - return h(SvgIcon, { icon: 'carbon:document', class: 'text-gray-400 text-lg' }) -} - -function renderSuffix({ option }: { option: TreeOption }) { - // 悬浮时显示操作按钮 - return h( - 'div', - { - class: 'flex items-center gap-2 opacity-0 group-hover:opacity-100 transition-opacity', - onClick: (e: Event) => e.stopPropagation(), - }, - [ - h('div', { - class: 'text-gray-400 hover:text-blue-500 cursor-pointer flex items-center', - title: '编辑', - onClick: (e: Event) => { - e.stopPropagation() - handleEditCategory(option) - }, - }, [h(SvgIcon, { icon: 'carbon:edit', class: 'text-lg' })]), - // 允许所有节点添加子节点,如果添加了子节点,它就变成文件夹 - h('div', { - class: 'text-gray-400 hover:text-green-500 cursor-pointer flex items-center', - title: '添加子分类', - onClick: (e: Event) => { - e.stopPropagation() - handleAddChildCategory(option) - }, - }, [h(SvgIcon, { icon: 'carbon:add', class: 'text-lg' })]), - h('div', { - class: 'text-gray-400 hover:text-red-500 cursor-pointer flex items-center', - title: '删除', - onClick: (e: Event) => { - e.stopPropagation() - handleDeleteCategory(option) - }, - }, [h(SvgIcon, { icon: 'carbon:trash-can', class: 'text-lg' })]), - ], - ) -} diff --git a/apps/admin/src/views/question-store/modules/QuestionList.vue b/apps/admin/src/views/question-store/modules/QuestionList.vue index b6de1df..fdfb346 100644 --- a/apps/admin/src/views/question-store/modules/QuestionList.vue +++ b/apps/admin/src/views/question-store/modules/QuestionList.vue @@ -25,7 +25,7 @@ const props = defineProps<{ const questionList = ref([ { id: 'Q-0325', - categoryKey: 'q-type-1', + categoryKey: 'stage-1', content: 'jiū 表示小鸟的叫声', answer: '碧', score: 10, @@ -33,7 +33,7 @@ const questionList = ref([ }, { id: 'Q-0326', - categoryKey: 'q-type-1', + categoryKey: 'stage-1', content: '“春色满园关不住,一枝红杏出墙来”。请书写“杏”字。', answer: '杏', score: 10, @@ -41,7 +41,7 @@ const questionList = ref([ }, { id: 'Q-0327', - categoryKey: 'q-type-1', + categoryKey: 'stage-1', content: '“春色满园关不住,一枝红杏出墙来”。请书写“㽱”字。', answer: '㽱', score: 10, @@ -49,7 +49,7 @@ const questionList = ref([ }, { id: 'Q-0328', - categoryKey: 'q-type-1', + categoryKey: 'stage-1', content: '“春色满园关不住,一枝红杏出墙来”。请书写“不”字。', answer: '不', score: 10, @@ -93,9 +93,7 @@ const questionForm = ref({ }) const isLeafSelected = computed(() => { - if (!props.currentCategory) - return false - return !!props.currentCategory.isLeaf || (props.currentCategory.children && props.currentCategory.children.length === 0 && props.currentCategory.level === 3) + return !!props.currentCategory }) const filteredQuestions = computed(() => { @@ -203,7 +201,7 @@ function submitQuestion() {
-
+