feat(admin): 添加比赛管理页面功能优化

refactor(utils): 为工具函数添加注释并导出新模块
feat(utils): 新增防抖和节流工具函数
docs(utils): 为现有工具类添加中文注释

style(admin): 优化比赛配置页面UI样式
feat(admin): 实现比赛基础信息表单双向绑定
feat(admin): 新增页面头部公共组件
feat(admin): 完善分组管理自动生成逻辑
feat(admin): 增强题目配置功能与交互

fix(admin): 修复表单数据更新死循环问题
This commit is contained in:
2026-01-20 10:58:42 +08:00
parent 1e8e2d1495
commit 2639aef69b
13 changed files with 443 additions and 128 deletions

View File

@ -1,16 +1,39 @@
<script setup lang="ts">
import { debounce } from '@sa/utils'
import { NCard, NDatePicker, NForm, NFormItemGi, NGrid, NInput, NInputNumber } from 'naive-ui'
import { reactive, useTemplateRef } from 'vue'
import { ref, useTemplateRef, watch } from 'vue'
const props = defineProps<{
modelValue: {
name: string
startTime: number | null
endTime: number | null
groupCount: number
teamCount: number
}
}>()
const emit = defineEmits(['update:modelValue'])
const formRef = useTemplateRef('formRef')
const formData = reactive({
name: '阅读之星年度总决赛',
startTime: null,
endTime: null,
groupCount: 40,
teamCount: 4,
})
const formData = ref({ ...props.modelValue })
// 修复死循环:添加值对比逻辑
watch(() => props.modelValue, (val) => {
if (JSON.stringify(val) !== JSON.stringify(formData.value)) {
formData.value = { ...val }
}
}, { deep: true })
// 添加防抖300ms 延迟,避免频繁触发父组件更新
const handleUpdate = debounce((val: typeof formData.value) => {
emit('update:modelValue', { ...val })
}, 300)
watch(formData, (val) => {
handleUpdate(val)
}, { deep: true })
defineExpose({
formRef,
@ -44,12 +67,26 @@ defineExpose({
/>
</NFormItemGi>
<NFormItemGi label="小组总数">
<NInputNumber v-model:value="formData.groupCount" class="w-full" />
<NFormItemGi label="参赛队伍总数">
<NInputNumber
v-model:value="formData.groupCount"
class="w-full"
:min="1"
:max="999"
:precision="0"
/>
<span class="text-xs text-gray-400"></span>
</NFormItemGi>
<NFormItemGi label="单组队伍">
<NInputNumber v-model:value="formData.teamCount" class="w-full" />
<NInputNumber
v-model:value="formData.teamCount"
class="w-full"
:min="1"
:max="formData.groupCount"
:precision="0"
/>
<span class="text-xs text-gray-400"></span>
</NFormItemGi>
</NGrid>
</NForm>