laobinghu 30f2115877 feat: dark mode adaptation for main pages
Add dark mode CSS variable overrides to index, events, teams, results, and scoreboard pages for consistent theme switching
2026-03-22 16:03:39 +08:00

221 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="teams-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.grade" placeholder="全部" clearable @change="onFilterChange">
<el-option v-for="g in config.grades" :key="g" :label="g" :value="g" />
</el-select>
</el-form-item>
<!-- 班级类型筛选 -->
<el-form-item label="班级类型">
<el-select v-model="filters.classType" placeholder="全部" clearable :disabled="!filters.grade" @change="onFilterChange">
<el-option v-for="c in config.classTypes" :key="c" :label="c" :value="c" />
</el-select>
</el-form-item>
<!-- 性别筛选 -->
<el-form-item label="性别">
<el-select v-model="filters.gender" placeholder="全部" clearable :disabled="!filters.grade" @change="onFilterChange">
<el-option v-for="g in config.genders" :key="g" :label="g" :value="g" />
</el-select>
</el-form-item>
</el-form>
<el-table :data="teams" border stripe class="teams-table">
<el-table-column prop="id" label="ID" width="80"></el-table-column>
<el-table-column prop="name" label="队伍名称"></el-table-column>
<el-table-column prop="team_group" label="组别" width="200" class-name="col-group"></el-table-column>
<el-table-column prop="created_at" label="创建时间" width="200" class-name="col-time">
<template #default="{ row }">
{{ new Date(row.created_at).toLocaleString('zh-CN') }}
</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-input v-model="form.name" placeholder="请输入队伍名称" />
</el-form-item>
<el-form-item label="组别">
<el-select v-model="form.team_group" placeholder="请选择组别">
<el-option v-for="g in allGroupOptions" :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="addTeam">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { computed } from 'vue'
const teams = ref([])
const showAddDialog = ref(false)
const config = ref({
grades: [] as string[],
classTypes: [] as string[],
genders: [] as string[],
all: [] as string[]
})
const filters = ref({
grade: '',
classType: '',
gender: ''
})
const form = ref({
name: '',
team_group: ''
})
// 为添加队伍对话框生成所有可用的组别选项从config API获取
const allGroupOptions = computed(() => {
return (config.value.all || []).map(g => ({ value: g, label: g }))
})
const loadConfig = async () => {
try {
const res = await $fetch('/api/config')
config.value = res.data.groups
} catch (error) {
ElMessage.error('加载配置失败')
}
}
const loadTeams = async () => {
try {
const params = new URLSearchParams()
if (filters.value.grade) params.append('grade', filters.value.grade)
if (filters.value.classType) params.append('classType', filters.value.classType)
if (filters.value.gender) params.append('gender', filters.value.gender)
const res = await $fetch(`/api/teams?${params}`)
teams.value = res.data
} catch (error) {
ElMessage.error('加载队伍失败')
}
}
const onFilterChange = () => {
loadTeams()
}
const addTeam = async () => {
if (!form.value.name || !form.value.team_group) {
ElMessage.error('请填写完整信息')
return
}
try {
await $fetch('/api/teams', {
method: 'POST',
body: form.value
})
ElMessage.success('添加成功')
showAddDialog.value = false
form.value = { name: '', team_group: '' }
loadTeams()
} catch (error) {
ElMessage.error('添加失败')
}
}
onMounted(() => {
loadConfig()
loadTeams()
})
</script>
<style scoped>
.teams-container {
max-width: 1200px;
margin: 0 auto;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.card-header span {
color: var(--header-text);
font-size: 18px;
font-weight: 600;
}
.filter-form {
margin-bottom: 20px;
}
/* 确保表格和表单在暗色模式下文字清晰 */
:deep(.el-card) {
background-color: var(--header-bg);
color: var(--header-text);
}
:deep(.el-card .el-card__header) {
border-bottom-color: var(--header-border);
}
:deep(.el-form-item__label) {
color: var(--header-text) !important;
}
:deep(.el-table) {
color: var(--header-text);
}
:deep(.el-table th) {
background-color: var(--header-bg);
color: var(--header-text);
}
:deep(.el-table tr) {
background-color: var(--header-bg);
}
:deep(.el-table td) {
color: var(--header-text);
}
@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%;
}
.teams-table :deep(.col-time) {
display: none;
}
}
</style>