和你<template>
|
<div class="activity-page">
|
<div class="page-card">
|
<h3 class="card-title">比赛管理</h3>
|
|
<!-- 搜索和操作栏 -->
|
<div class="toolbar">
|
<el-input
|
v-model="searchForm.name"
|
placeholder="请输入比赛名称"
|
style="width: 300px"
|
clearable
|
@keyup.enter="handleSearch"
|
>
|
<template #prefix>
|
<el-icon><Search /></el-icon>
|
</template>
|
</el-input>
|
<el-button type="primary" @click="handleSearch">
|
<el-icon><Search /></el-icon>
|
搜索
|
</el-button>
|
<el-button type="success" @click="handleAdd">
|
<el-icon><Plus /></el-icon>
|
新增比赛
|
</el-button>
|
</div>
|
|
<!-- 比赛列表 -->
|
<el-table :data="tableData" style="width: 100%" v-loading="loading">
|
<el-table-column prop="name" label="比赛名称" min-width="200" />
|
<el-table-column prop="playerCount" label="报名人数" width="120" align="center" />
|
<el-table-column prop="matchTime" label="比赛时间" width="180" />
|
<el-table-column prop="signupDeadline" label="报名截止时间" width="180" />
|
<el-table-column prop="stateName" label="状态" width="100" align="center">
|
<template #default="{ row }">
|
<el-tag :type="getStatusType(row.stateName)">{{ row.stateName }}</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" width="200" fixed="right">
|
<template #default="{ row }">
|
<div class="table-actions">
|
<el-button type="primary" size="small" @click="handleViewPlayers(row)">
|
查看选手
|
</el-button>
|
<el-button type="warning" size="small" @click="handleEdit(row)">
|
编辑
|
</el-button>
|
<el-button type="danger" size="small" @click="handleDelete(row)">
|
删除
|
</el-button>
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<!-- 分页 -->
|
<div class="pagination">
|
<el-pagination
|
v-model:current-page="pagination.page"
|
v-model:page-size="pagination.size"
|
:page-sizes="[10, 20, 50, 100]"
|
:total="pagination.total"
|
layout="total, sizes, prev, pager, next, jumper"
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
/>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { reactive, ref, onMounted } from 'vue'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { useRouter } from 'vue-router'
|
import { getActivities } from '@/api/activity'
|
|
const loading = ref(false)
|
const router = useRouter()
|
|
// 搜索表单
|
const searchForm = reactive({
|
name: ''
|
})
|
|
// 分页信息
|
const pagination = reactive({
|
page: 1,
|
size: 10,
|
total: 0
|
})
|
|
// 表格数据
|
const tableData = ref([])
|
|
// 获取状态标签类型
|
const getStatusType = (status: string) => {
|
const typeMap: Record<string, string> = {
|
'进行中': 'success',
|
'报名中': 'warning',
|
'待开始': 'info',
|
'已结束': 'info'
|
}
|
return typeMap[status] || 'info'
|
}
|
|
// 搜索
|
const handleSearch = () => {
|
pagination.page = 1
|
loadData()
|
}
|
|
// 新增比赛
|
const handleAdd = () => {
|
router.push('/activity/new')
|
}
|
|
// 编辑比赛
|
const handleEdit = (row: any) => {
|
router.push(`/activity/edit/${row.id}`)
|
}
|
|
// 查看选手(进入比赛详情页,进行阶段/评委/学员管理)
|
const handleViewPlayers = (row: any) => {
|
router.push(`/activity/${row.id}`)
|
}
|
|
// 删除比赛
|
const handleDelete = async (row: any) => {
|
try {
|
await ElMessageBox.confirm(`确定要删除比赛"${row.name}"吗?`, '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
|
ElMessage.success('删除成功')
|
loadData()
|
} catch {
|
// 用户取消
|
}
|
}
|
|
// 分页大小改变
|
const handleSizeChange = (size: number) => {
|
pagination.size = size
|
loadData()
|
}
|
|
// 当前页改变
|
const handleCurrentChange = (page: number) => {
|
pagination.page = page
|
loadData()
|
}
|
|
// 加载数据
|
const loadData = async () => {
|
loading.value = true
|
try {
|
const data = await getActivities(pagination.page - 1, pagination.size, searchForm.name || '')
|
tableData.value = (data && data.content) ? data.content : []
|
pagination.total = (data && data.totalElements) ? data.totalElements : 0
|
} catch (e) {
|
ElMessage.error((e && e.message) ? e.message : '加载比赛列表失败')
|
} finally {
|
loading.value = false
|
}
|
}
|
|
onMounted(() => {
|
loadData()
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.activity-page {
|
.card-title {
|
margin-bottom: 20px;
|
color: #303133;
|
font-size: 16px;
|
font-weight: 500;
|
}
|
|
.toolbar {
|
display: flex;
|
gap: 12px;
|
margin-bottom: 20px;
|
align-items: center;
|
}
|
|
.table-actions {
|
display: flex;
|
gap: 8px;
|
flex-wrap: wrap;
|
}
|
|
.pagination {
|
margin-top: 20px;
|
display: flex;
|
justify-content: flex-end;
|
}
|
}
|
</style>
|