<template>
|
<div class="activity-list">
|
<el-card>
|
<div class="header">
|
<el-input
|
v-model="searchName"
|
placeholder="搜索比赛名称"
|
style="width: 300px;"
|
@keyup.enter="handleSearch"
|
clearable
|
/>
|
<el-button type="primary" @click="handleAdd">新增比赛</el-button>
|
</div>
|
|
<el-table :data="tableData" style="width: 100%" v-loading="loading">
|
<el-table-column prop="name" label="比赛名称" min-width="200">
|
<template #default="{ row }">
|
<el-link type="primary" @click="handleView(row.id)">{{ row.name }}</el-link>
|
</template>
|
</el-table-column>
|
|
<el-table-column prop="playerCount" label="报名人数" width="100">
|
<template #default="{ row }">
|
{{ row.playerCount || 0 }}
|
</template>
|
</el-table-column>
|
|
<el-table-column prop="matchTime" label="比赛时间" width="180">
|
<template #default="{ row }">
|
{{ formatDateTime(row.matchTime) }}
|
</template>
|
</el-table-column>
|
|
<el-table-column prop="signupDeadline" label="报名截止时间" width="180">
|
<template #default="{ row }">
|
{{ formatDateTime(row.signupDeadline) }}
|
</template>
|
</el-table-column>
|
|
<el-table-column prop="stateName" label="状态" width="100">
|
<template #default="{ row }">
|
<el-tag :type="getStateType(row.state)">{{ row.stateName }}</el-tag>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="操作" width="200" fixed="right">
|
<template #default="{ row }">
|
<el-button size="small" @click="handleView(row.id)">查看选手</el-button>
|
<el-button size="small" type="primary" @click="handleEdit(row.id)">编辑</el-button>
|
<el-button size="small" type="danger" @click="handleDelete(row.id)">删除</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<div class="pagination">
|
<el-pagination
|
v-model:current-page="currentPage"
|
v-model:page-size="pageSize"
|
:page-sizes="[10, 20, 50, 100]"
|
:total="total"
|
layout="total, sizes, prev, pager, next, jumper"
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
/>
|
</div>
|
</el-card>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, onMounted, watch } from 'vue'
|
import { useRouter } from 'vue-router'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { getActivities, deleteActivity } from '@/api/activity'
|
import dayjs from 'dayjs'
|
|
const router = useRouter()
|
|
// 响应式数据
|
const loading = ref(false)
|
const tableData = ref([])
|
const searchName = ref('')
|
const currentPage = ref(1)
|
const pageSize = ref(10)
|
const total = ref(0)
|
|
// 搜索
|
const handleSearch = () => {
|
currentPage.value = 1
|
loadData()
|
}
|
|
// 监听搜索框变化
|
watch(searchName, () => {
|
if (!searchName.value) {
|
handleSearch()
|
}
|
})
|
|
// 加载数据
|
const loadData = async () => {
|
try {
|
loading.value = true
|
const result = await getActivities(
|
currentPage.value - 1,
|
pageSize.value,
|
searchName.value
|
)
|
|
tableData.value = result.content || []
|
total.value = result.totalElements || 0
|
} catch (error) {
|
console.error('加载比赛列表失败:', error)
|
ElMessage.error('加载比赛列表失败: ' + error.message)
|
} finally {
|
loading.value = false
|
}
|
}
|
|
// 分页处理
|
const handleSizeChange = (val) => {
|
pageSize.value = val
|
currentPage.value = 1
|
loadData()
|
}
|
|
const handleCurrentChange = (val) => {
|
currentPage.value = val
|
loadData()
|
}
|
|
// 操作处理
|
const handleAdd = () => {
|
router.push('/activity/form')
|
}
|
|
const handleEdit = (id) => {
|
router.push(`/activity/form/${id}`)
|
}
|
|
const handleView = (id) => {
|
router.push(`/activity/detail/${id}`)
|
}
|
|
const handleDelete = async (id) => {
|
try {
|
await ElMessageBox.confirm('确定要删除这个比赛吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
|
await deleteActivity(id)
|
ElMessage.success('删除成功')
|
loadData()
|
} catch (error) {
|
if (error !== 'cancel') {
|
console.error('删除比赛失败:', error)
|
ElMessage.error('删除失败: ' + error.message)
|
}
|
}
|
}
|
|
// 工具函数
|
const formatDateTime = (dateTime) => {
|
if (!dateTime) return '-'
|
return dayjs(dateTime).format('YYYY-MM-DD HH:mm')
|
}
|
|
const getStateType = (state) => {
|
switch (state) {
|
case 0: return 'info'
|
case 1: return 'success'
|
case 2: return 'danger'
|
default: return 'info'
|
}
|
}
|
|
// 生命周期
|
onMounted(() => {
|
loadData()
|
})
|
</script>
|
|
<style scoped>
|
.activity-list {
|
padding: 20px;
|
}
|
|
.header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
}
|
|
.pagination {
|
margin-top: 20px;
|
text-align: right;
|
}
|
</style>
|