<template>
|
<div class="judge-page">
|
<div class="search-bar">
|
<el-input
|
v-model="searchQuery"
|
placeholder="搜索评委..."
|
style="width: 300px; margin-right: 10px"
|
clearable
|
@input="handleSearch"
|
/>
|
<el-button type="primary" @click="openAddDialog">
|
<el-icon><Plus /></el-icon>
|
新增评委
|
</el-button>
|
</div>
|
|
<el-table :data="judges" style="width: 100%; margin-top: 20px">
|
<!-- 头像列 - 第一列 -->
|
<el-table-column label="头像" width="80" align="center">
|
<template #default="scope">
|
<el-avatar
|
v-if="scope.row.avatarUrl"
|
:src="scope.row.avatarUrl"
|
:size="40"
|
/>
|
<el-avatar
|
v-else
|
:size="40"
|
:style="{ backgroundColor: getAvatarColor(scope.row.name) }"
|
>
|
{{ scope.row.name?.charAt(0) || '?' }}
|
</el-avatar>
|
</template>
|
</el-table-column>
|
|
<!-- 姓名列 -->
|
<el-table-column prop="name" label="姓名" width="120" />
|
|
<!-- 电话列 -->
|
<el-table-column prop="phone" label="电话" width="150" />
|
|
<!-- 简介列 -->
|
<el-table-column prop="description" label="简介" min-width="200" show-overflow-tooltip />
|
|
<!-- 操作列 -->
|
<el-table-column label="操作" width="150" align="center">
|
<template #default="scope">
|
<el-button
|
type="primary"
|
size="small"
|
@click="editJudge(scope.row)"
|
>
|
编辑
|
</el-button>
|
<el-button
|
type="danger"
|
size="small"
|
@click="deleteJudge(scope.row.id)"
|
>
|
删除
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
|
<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"
|
style="margin-top: 20px; justify-content: center"
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
/>
|
|
<!-- 新增/编辑对话框 -->
|
<JudgeFormSimple
|
v-model="dialogVisible"
|
:judge-data="currentJudge"
|
@success="handleFormSuccess"
|
/>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, onMounted } from 'vue'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { Plus } from '@element-plus/icons-vue'
|
import JudgeFormSimple from '@/components/JudgeFormSimple.vue'
|
import { JudgeApi } from '@/api/judge'
|
|
interface Judge {
|
id: string
|
name: string
|
phone: string
|
email: string
|
organization: string
|
title: string
|
avatar?: string
|
}
|
|
const judges = ref<Judge[]>([])
|
const searchQuery = ref('')
|
const currentPage = ref(1)
|
const pageSize = ref(10)
|
const total = ref(0)
|
const dialogVisible = ref(false)
|
const currentJudge = ref<Judge | null>(null)
|
|
const loadJudges = async () => {
|
try {
|
let judgeList = []
|
if (searchQuery.value) {
|
judgeList = await JudgeApi.searchJudges(searchQuery.value)
|
} else {
|
judgeList = await JudgeApi.getJudges()
|
}
|
|
// 简单的分页处理(实际项目中应该在后端实现)
|
const startIndex = (currentPage.value - 1) * pageSize.value
|
const endIndex = startIndex + pageSize.value
|
judges.value = judgeList.slice(startIndex, endIndex)
|
total.value = judgeList.length
|
} catch (error) {
|
ElMessage.error('加载评委列表失败')
|
console.error(error)
|
}
|
}
|
|
const handleSearch = () => {
|
currentPage.value = 1
|
loadJudges()
|
}
|
|
const handleSizeChange = (val: number) => {
|
pageSize.value = val
|
loadJudges()
|
}
|
|
const handleCurrentChange = (val: number) => {
|
currentPage.value = val
|
loadJudges()
|
}
|
|
const openAddDialog = () => {
|
currentJudge.value = null
|
dialogVisible.value = true
|
}
|
|
const editJudge = (judge: Judge) => {
|
currentJudge.value = { ...judge }
|
dialogVisible.value = true
|
}
|
|
const deleteJudge = async (id: string) => {
|
try {
|
await ElMessageBox.confirm('确定要删除这个评委吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
})
|
|
await JudgeApi.deleteJudge(id)
|
ElMessage.success('删除成功')
|
loadJudges()
|
} catch (error) {
|
if (error !== 'cancel') {
|
ElMessage.error('删除失败')
|
console.error(error)
|
}
|
}
|
}
|
|
const handleFormSuccess = () => {
|
dialogVisible.value = false
|
loadJudges()
|
}
|
|
// 根据名称生成头像背景色
|
const getAvatarColor = (name: string): string => {
|
if (!name) return '#909399'
|
|
// 预定义的美观颜色数组
|
const colors = [
|
'#409EFF', // 蓝色
|
'#67C23A', // 绿色
|
'#E6A23C', // 橙色
|
'#F56C6C', // 红色
|
'#909399', // 灰色
|
'#9C27B0', // 紫色
|
'#FF9800', // 深橙色
|
'#4CAF50', // 深绿色
|
'#2196F3', // 深蓝色
|
'#FF5722', // 深红色
|
'#795548', // 棕色
|
'#607D8B' // 蓝灰色
|
]
|
|
// 根据名称字符串生成固定的索引
|
let hash = 0
|
for (let i = 0; i < name.length; i++) {
|
hash = name.charCodeAt(i) + ((hash << 5) - hash)
|
}
|
|
// 确保索引在颜色数组范围内
|
const index = Math.abs(hash) % colors.length
|
return colors[index]
|
}
|
|
onMounted(() => {
|
loadJudges()
|
})
|
</script>
|
|
<style lang="scss" scoped>
|
.judge-page {
|
padding: 20px;
|
}
|
|
.search-bar {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 20px;
|
}
|
|
.el-pagination {
|
display: flex;
|
justify-content: center;
|
}
|
</style>
|