Administrator 22f073d8e7 feat: 运动会记分板系统核心功能
- 前后端分离架构 (Nuxt 3 + Element Plus)
- SQLite 数据库 (better-sqlite3)
- 比赛项目管理 (田赛/径赛/团体赛)
- 队伍管理 (5 个组别)
- 成绩录入与积分统计
- 记分板展示 (排名/奖牌榜)
- 移动端响应式适配
- 侧边栏布局 + 抽屉菜单
- 自动生成初始化数据接口
2026-03-17 22:29:18 +08:00

197 lines
5.6 KiB
Vue

<template>
<div class="events-container">
<el-card>
<template #header>
<div class="card-header">
<span>比赛项目管理</span>
<el-button type="primary" @click="showAddDialog = true">添加项目</el-button>
</div>
</template>
<el-form :inline="true" class="filter-form">
<el-form-item label="类别">
<el-select v-model="filters.category" placeholder="全部" clearable @change="loadEvents">
<el-option label="田赛" value="田赛" />
<el-option label="径赛" value="径赛" />
<el-option label="团体赛" value="团体赛" />
</el-select>
</el-form-item>
<el-form-item label="组别">
<el-select v-model="filters.group" placeholder="全部" clearable @change="loadEvents">
<el-option v-for="g in groups" :key="g.value" :label="g.label" :value="g.value" />
</el-select>
</el-form-item>
</el-form>
<el-table :data="events" border stripe class="events-table">
<el-table-column prop="id" label="ID" width="80" class-name="col-id" />
<el-table-column prop="name" label="项目名称" />
<el-table-column prop="category" label="类别" width="120" class-name="col-category" />
<el-table-column prop="event_group" label="组别" width="150" class-name="col-group" />
<el-table-column prop="unit" label="单位" width="100" class-name="col-unit" />
<el-table-column prop="status" label="状态" width="100" class-name="col-status">
<template #default="{ row }">
<el-tag :type="row.status === 'completed' ? 'success' : 'info'">
{{ row.status === 'completed' ? '已完成' : '进行中' }}
</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog v-model="showAddDialog" title="添加比赛项目" width="500px">
<el-form :model="form" label-width="100px">
<el-form-item label="类别">
<el-select v-model="form.category" placeholder="请选择" @change="onCategoryChange">
<el-option label="田赛" value="田赛" />
<el-option label="径赛" value="径赛" />
<el-option label="团体赛" value="团体赛" />
</el-select>
</el-form-item>
<el-form-item label="项目名称">
<el-select v-model="form.name" placeholder="请选择">
<el-option
v-for="event in availableEvents"
:key="event.name"
:label="event.name"
:value="event.name"
/>
</el-select>
</el-form-item>
<el-form-item label="组别">
<el-select v-model="form.event_group" placeholder="请选择">
<el-option v-for="g in groups" :key="g.value" :label="g.label" :value="g.value" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showAddDialog = false">取消</el-button>
<el-button type="primary" @click="addEvent">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ElMessage } from 'element-plus'
const events = ref([])
const showAddDialog = ref(false)
const filters = ref({ category: '', group: '' })
const groups = ref([])
const eventTypes = ref({})
const form = ref({
name: '',
category: '',
event_group: '',
unit: ''
})
const availableEvents = computed(() => {
if (!form.value.category) return []
return eventTypes.value[form.value.category] || []
})
const onCategoryChange = () => {
form.value.name = ''
form.value.unit = ''
}
const loadConfig = async () => {
try {
const res = await $fetch('/api/config')
groups.value = res.data.groups
eventTypes.value = res.data.eventTypes
} catch (error) {
ElMessage.error('加载配置失败')
}
}
const loadEvents = async () => {
try {
const params = new URLSearchParams()
if (filters.value.category) params.append('category', filters.value.category)
if (filters.value.group) params.append('group', filters.value.group)
const res = await $fetch(`/api/events?${params}`)
events.value = res.data
} catch (error) {
ElMessage.error('加载项目失败')
}
}
const addEvent = async () => {
try {
const selectedEvent = availableEvents.value.find(e => e.name === form.value.name)
if (!selectedEvent) {
ElMessage.error('请选择项目')
return
}
await $fetch('/api/events', {
method: 'POST',
body: {
name: form.value.name,
category: form.value.category,
event_group: form.value.event_group,
unit: selectedEvent.unit
}
})
ElMessage.success('添加成功')
showAddDialog.value = false
form.value = { name: '', category: '', event_group: '', unit: '' }
loadEvents()
} catch (error) {
ElMessage.error('添加失败')
}
}
onMounted(() => {
loadConfig()
loadEvents()
})
</script>
<style scoped>
.events-container {
max-width: 1200px;
margin: 0 auto;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.filter-form {
margin-bottom: 20px;
}
@media (max-width: 900px) {
.card-header {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.filter-form :deep(.el-form-item) {
margin-right: 0;
width: 100%;
}
.filter-form :deep(.el-select) {
width: 100%;
}
.events-table :deep(.col-id),
.events-table :deep(.col-category),
.events-table :deep(.col-unit),
.events-table :deep(.col-status) {
display: none;
}
}
</style>