2026-01-19 18:03:45 +08:00
|
|
|
<script setup lang="ts">
|
2026-01-21 08:41:36 +08:00
|
|
|
import { NButton, NCard, NForm, NFormItem, NGrid, NGridItem, NInputNumber, NModal, NSelect } from 'naive-ui'
|
|
|
|
|
import { computed, ref } from 'vue'
|
2026-01-19 18:03:45 +08:00
|
|
|
|
|
|
|
|
defineProps<{ isEdit: boolean }>()
|
|
|
|
|
|
|
|
|
|
const scoreOptions = [
|
|
|
|
|
{ label: '1分', value: '1' },
|
|
|
|
|
{ label: '2分', value: '2' },
|
|
|
|
|
{ label: '3分', value: '3' },
|
|
|
|
|
{ label: '5分', value: '5' },
|
|
|
|
|
{ label: '10分', value: '10' },
|
|
|
|
|
]
|
2026-01-21 08:41:36 +08:00
|
|
|
|
|
|
|
|
interface Question {
|
|
|
|
|
id: string
|
|
|
|
|
label: string
|
|
|
|
|
type: string
|
|
|
|
|
score: string
|
|
|
|
|
time: number | null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化常规赛题目数据
|
|
|
|
|
const regularQuestions = ref<Question[]>(Array.from({ length: 10 }, (_, i) => ({
|
|
|
|
|
id: `reg-${i}`,
|
|
|
|
|
label: `第${i + 1}题`,
|
|
|
|
|
type: 'hanzi',
|
|
|
|
|
score: '1',
|
|
|
|
|
time: 30,
|
|
|
|
|
})))
|
|
|
|
|
|
|
|
|
|
// 初始化PK赛题目数据
|
|
|
|
|
const pkQuestions = ref<Question[]>(Array.from({ length: 5 }, (_, i) => ({
|
|
|
|
|
id: `pk-${i}`,
|
|
|
|
|
label: `PK${i + 1}`,
|
|
|
|
|
type: 'hanzi',
|
|
|
|
|
score: '1',
|
|
|
|
|
time: 30,
|
|
|
|
|
})))
|
|
|
|
|
|
|
|
|
|
const regularTotalScore = computed(() => regularQuestions.value.reduce((acc, cur) => acc + Number(cur.score || 0), 0))
|
|
|
|
|
const pkTotalScore = computed(() => pkQuestions.value.reduce((acc, cur) => acc + Number(cur.score || 0), 0))
|
|
|
|
|
|
|
|
|
|
// 快速配置相关逻辑
|
|
|
|
|
const showQuickConfigModal = ref(false)
|
|
|
|
|
const quickConfigForm = ref({
|
|
|
|
|
score: '1',
|
|
|
|
|
time: 30,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
function handleBatchReset() {
|
|
|
|
|
regularQuestions.value.forEach((q) => {
|
|
|
|
|
q.score = '1'
|
|
|
|
|
q.time = 30
|
|
|
|
|
})
|
|
|
|
|
pkQuestions.value.forEach((q) => {
|
|
|
|
|
q.score = '1'
|
|
|
|
|
q.time = 30
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handleQuickConfig() {
|
|
|
|
|
showQuickConfigModal.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function applyQuickConfig() {
|
|
|
|
|
const { score, time } = quickConfigForm.value
|
|
|
|
|
regularQuestions.value.forEach((q) => {
|
|
|
|
|
q.score = score
|
|
|
|
|
q.time = time
|
|
|
|
|
})
|
|
|
|
|
pkQuestions.value.forEach((q) => {
|
|
|
|
|
q.score = score
|
|
|
|
|
q.time = time
|
|
|
|
|
})
|
|
|
|
|
showQuickConfigModal.value = false
|
|
|
|
|
}
|
2026-01-19 18:03:45 +08:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
<NCard :bordered="false" class="rounded-xl shadow-sm">
|
|
|
|
|
<div class="mb-6 flex items-center justify-between">
|
|
|
|
|
<div class="flex items-center gap-3 border-l-4 border-purple-500 pl-3">
|
|
|
|
|
<span class="text-lg text-gray-800 font-bold">题包配置</span>
|
|
|
|
|
</div>
|
|
|
|
|
<!-- 编辑模式下显示批量操作按钮 -->
|
|
|
|
|
<div v-if="isEdit" class="flex gap-3">
|
2026-01-21 08:41:36 +08:00
|
|
|
<NButton size="small" secondary @click="handleBatchReset">
|
2026-01-19 18:03:45 +08:00
|
|
|
批量重置
|
|
|
|
|
</NButton>
|
2026-01-21 08:41:36 +08:00
|
|
|
<NButton size="small" type="primary" secondary @click="handleQuickConfig">
|
2026-01-19 18:03:45 +08:00
|
|
|
快速配置
|
|
|
|
|
</NButton>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<NGrid :x-gap="24" :cols="2">
|
2026-01-21 08:41:36 +08:00
|
|
|
<!-- 常规赛 -->
|
|
|
|
|
<NGridItem>
|
|
|
|
|
<div class="flex items-center justify-between border-b border-blue-100 rounded-t-lg bg-blue-50/50 px-4 py-3">
|
|
|
|
|
<div class="flex items-center gap-2 text-gray-800 font-bold">
|
|
|
|
|
<div class="i-carbon-document-tasks text-blue-500" />
|
|
|
|
|
常规赛题包
|
2026-01-19 18:03:45 +08:00
|
|
|
</div>
|
2026-01-21 08:41:36 +08:00
|
|
|
<div class="text-xs text-[#8DA5C3] font-medium">
|
|
|
|
|
共 {{ regularQuestions.length }} 题 / 总计 {{ regularTotalScore }} 分
|
2026-01-19 18:03:45 +08:00
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-01-21 08:41:36 +08:00
|
|
|
<div class="flex flex-col gap-3 border border-t-0 border-blue-100 rounded-b-lg bg-[#F5F9FF] p-4">
|
|
|
|
|
<div v-for="item in regularQuestions" :key="item.id" class="flex items-center gap-2">
|
|
|
|
|
<div class="w-16 flex-shrink-0 text-xs text-[#8DA5C3] font-bold">
|
|
|
|
|
{{ item.label }}:
|
2026-01-19 18:03:45 +08:00
|
|
|
</div>
|
|
|
|
|
<NSelect
|
2026-01-21 08:41:36 +08:00
|
|
|
v-model:value="item.type"
|
2026-01-19 18:03:45 +08:00
|
|
|
size="small"
|
|
|
|
|
placeholder="题型"
|
|
|
|
|
:options="[{ label: '汉字书写', value: 'hanzi' }]"
|
|
|
|
|
:disabled="!isEdit"
|
|
|
|
|
class="min-w-[120px] flex-1"
|
|
|
|
|
/>
|
|
|
|
|
<div class="w-20 flex-shrink-0">
|
|
|
|
|
<NSelect
|
2026-01-21 08:41:36 +08:00
|
|
|
v-model:value="item.score"
|
2026-01-19 18:03:45 +08:00
|
|
|
size="small"
|
|
|
|
|
:options="scoreOptions"
|
|
|
|
|
:disabled="!isEdit"
|
|
|
|
|
placeholder="分值"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2026-01-21 08:41:36 +08:00
|
|
|
<div class="w-20 flex-shrink-0">
|
|
|
|
|
<NInputNumber
|
|
|
|
|
v-model:value="item.time"
|
|
|
|
|
size="small"
|
|
|
|
|
placeholder="秒"
|
|
|
|
|
:show-button="false"
|
|
|
|
|
:disabled="!isEdit"
|
|
|
|
|
>
|
|
|
|
|
<template #suffix>
|
|
|
|
|
s
|
|
|
|
|
</template>
|
|
|
|
|
</NInputNumber>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</NGridItem>
|
2026-01-19 18:03:45 +08:00
|
|
|
|
2026-01-21 08:41:36 +08:00
|
|
|
<!-- PK赛 -->
|
|
|
|
|
<NGridItem>
|
|
|
|
|
<div class="flex items-center justify-between border-b border-orange-100 rounded-t-lg bg-orange-50/50 px-4 py-3">
|
|
|
|
|
<div class="flex items-center gap-2 text-[#5E3218] font-bold">
|
|
|
|
|
<div class="i-carbon-timer text-[#D96B23]" />
|
|
|
|
|
加时赛题包
|
|
|
|
|
</div>
|
|
|
|
|
<div class="text-xs text-[#D96B23]/60 font-medium">
|
|
|
|
|
共 {{ pkQuestions.length }} 题 / 总计 {{ pkTotalScore }} 分
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex flex-col gap-3 border border-t-0 border-orange-100 rounded-b-lg bg-[#FFF9F5] p-4">
|
|
|
|
|
<div v-for="item in pkQuestions" :key="item.id" class="flex items-center gap-2">
|
|
|
|
|
<div class="w-16 flex-shrink-0 text-xs text-[#FF8C38] font-bold">
|
|
|
|
|
{{ item.label }}:
|
|
|
|
|
</div>
|
|
|
|
|
<NSelect
|
|
|
|
|
v-model:value="item.type"
|
|
|
|
|
size="small"
|
|
|
|
|
placeholder="题型"
|
|
|
|
|
:options="[{ label: '汉字书写', value: 'hanzi' }]"
|
|
|
|
|
:disabled="!isEdit"
|
|
|
|
|
class="min-w-[120px] flex-1"
|
|
|
|
|
/>
|
|
|
|
|
<div class="w-20 flex-shrink-0">
|
|
|
|
|
<NSelect
|
|
|
|
|
v-model:value="item.score"
|
|
|
|
|
size="small"
|
|
|
|
|
:options="scoreOptions"
|
|
|
|
|
:disabled="!isEdit"
|
|
|
|
|
placeholder="分值"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
2026-01-19 18:03:45 +08:00
|
|
|
<div class="w-20 flex-shrink-0">
|
|
|
|
|
<NInputNumber
|
2026-01-21 08:41:36 +08:00
|
|
|
v-model:value="item.time"
|
2026-01-19 18:03:45 +08:00
|
|
|
size="small"
|
|
|
|
|
placeholder="秒"
|
|
|
|
|
:show-button="false"
|
|
|
|
|
:disabled="!isEdit"
|
|
|
|
|
>
|
|
|
|
|
<template #suffix>
|
|
|
|
|
s
|
|
|
|
|
</template>
|
|
|
|
|
</NInputNumber>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</NGridItem>
|
|
|
|
|
</NGrid>
|
2026-01-21 08:41:36 +08:00
|
|
|
|
|
|
|
|
<!-- 快速配置弹窗 -->
|
|
|
|
|
<NModal
|
|
|
|
|
v-model:show="showQuickConfigModal"
|
|
|
|
|
preset="card"
|
|
|
|
|
title="快速配置"
|
|
|
|
|
class="w-[400px]"
|
|
|
|
|
>
|
|
|
|
|
<NForm :model="quickConfigForm" label-placement="left" label-width="80">
|
|
|
|
|
<NFormItem label="统一分值">
|
|
|
|
|
<NSelect v-model:value="quickConfigForm.score" :options="scoreOptions" />
|
|
|
|
|
</NFormItem>
|
|
|
|
|
<NFormItem label="统一时间">
|
|
|
|
|
<NInputNumber v-model:value="quickConfigForm.time" :show-button="false">
|
|
|
|
|
<template #suffix>
|
|
|
|
|
秒
|
|
|
|
|
</template>
|
|
|
|
|
</NInputNumber>
|
|
|
|
|
</NFormItem>
|
|
|
|
|
</NForm>
|
|
|
|
|
<template #footer>
|
|
|
|
|
<div class="flex justify-end gap-3">
|
|
|
|
|
<NButton @click="showQuickConfigModal = false">
|
|
|
|
|
取消
|
|
|
|
|
</NButton>
|
|
|
|
|
<NButton type="primary" @click="applyQuickConfig">
|
|
|
|
|
应用
|
|
|
|
|
</NButton>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</NModal>
|
2026-01-19 18:03:45 +08:00
|
|
|
</NCard>
|
|
|
|
|
</template>
|