|
|
<template>
|
|
|
<div class="page-container fade-in-up">
|
|
|
<div class="page-header">
|
|
|
<h2 class="page-title">人员管理</h2>
|
|
|
<p class="page-subtitle">管理学生信息,支持批量导入与编辑</p>
|
|
|
</div>
|
|
|
|
|
|
<div class="filter-bar">
|
|
|
<el-input v-model="searchKey" placeholder="搜索姓名/学号..." :prefix-icon="Search" clearable size="default" style="width: 220px" />
|
|
|
<el-select v-model="classFilter" placeholder="班级筛选" clearable size="default" style="width: 180px">
|
|
|
<el-option label="计算机2021-1班" value="cs1" />
|
|
|
<el-option label="软件工程2022-2班" value="se2" />
|
|
|
<el-option label="人工智能2023-1班" value="ai1" />
|
|
|
</el-select>
|
|
|
<el-upload action="#" :show-file-list="false" accept=".xlsx,.xls">
|
|
|
<el-button :icon="Upload">导入Excel</el-button>
|
|
|
</el-upload>
|
|
|
<el-button type="primary" :icon="Plus" @click="showAddDialog">添加学生</el-button>
|
|
|
<el-button :icon="Delete" :disabled="!hasSelected" @click="batchDelete">批量删除</el-button>
|
|
|
</div>
|
|
|
|
|
|
<div class="data-table-card">
|
|
|
<el-table :data="students" stripe @selection-change="handleSelectionChange">
|
|
|
<el-table-column type="selection" width="45" />
|
|
|
<el-table-column prop="id" label="学号" width="120" />
|
|
|
<el-table-column prop="name" label="姓名" width="100" />
|
|
|
<el-table-column prop="gender" label="性别" width="70" align="center" />
|
|
|
<el-table-column prop="className" label="班级" min-width="160" />
|
|
|
<el-table-column prop="phone" label="手机号" width="140" />
|
|
|
<el-table-column prop="status" label="状态" width="80" align="center">
|
|
|
<template #default="{ row }">
|
|
|
<el-tag :type="row.status === '正常' ? 'success' : 'info'" size="small">
|
|
|
{{ row.status }}
|
|
|
</el-tag>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="160" align="center" fixed="right">
|
|
|
<template #default="{ row }">
|
|
|
<el-button link type="primary" size="small" :icon="Edit" @click="editStudent(row)">编辑</el-button>
|
|
|
<el-button link type="danger" size="small" :icon="Delete" @click="deleteStudent(row)">删除</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
|
|
|
<el-pagination
|
|
|
v-model:current-page="pageCurrent"
|
|
|
:total="students.length"
|
|
|
:page-size="10"
|
|
|
small
|
|
|
background
|
|
|
layout="total, prev, pager, next"
|
|
|
style="justify-content: flex-end; margin-top: 16px"
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
<!-- 添加/编辑弹窗 -->
|
|
|
<el-dialog v-model="dialogVisible" :title="editing ? '编辑学生信息' : '添加学生'" width="520px" destroy-on-close>
|
|
|
<el-form :model="form" label-width="80px" label-position="left">
|
|
|
<el-form-item label="学号" required>
|
|
|
<el-input v-model="form.id" placeholder="请输入学号" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="姓名" required>
|
|
|
<el-input v-model="form.name" placeholder="请输入姓名" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="性别">
|
|
|
<el-radio-group v-model="form.gender">
|
|
|
<el-radio value="男">男</el-radio>
|
|
|
<el-radio value="女">女</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="班级" required>
|
|
|
<el-select v-model="form.className" placeholder="请选择班级" style="width: 100%">
|
|
|
<el-option label="计算机2021-1班" value="计算机2021-1班" />
|
|
|
<el-option label="软件工程2022-2班" value="软件工程2022-2班" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="手机号">
|
|
|
<el-input v-model="form.phone" placeholder="请输入手机号" />
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
<template #footer>
|
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
|
<el-button type="primary" @click="saveStudent">保存</el-button>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { ref } from 'vue'
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
|
|
const searchKey = ref('')
|
|
|
const classFilter = ref('')
|
|
|
const pageCurrent = ref(1)
|
|
|
const dialogVisible = ref(false)
|
|
|
const editing = ref(false)
|
|
|
const selectedRows = ref([])
|
|
|
const hasSelected = ref(false)
|
|
|
|
|
|
const form = ref({
|
|
|
id: '',
|
|
|
name: '',
|
|
|
gender: '男',
|
|
|
className: '',
|
|
|
phone: ''
|
|
|
})
|
|
|
|
|
|
const students = ref([
|
|
|
{ id: '2021001', name: '张三', gender: '男', className: '计算机2021-1班', phone: '138****6789', status: '正常' },
|
|
|
{ id: '2021002', name: '李四', gender: '女', className: '计算机2021-1班', phone: '139****7890', status: '正常' },
|
|
|
{ id: '2021003', name: '王五', gender: '男', className: '计算机2021-1班', phone: '137****8901', status: '正常' },
|
|
|
{ id: '2022001', name: '赵六', gender: '男', className: '软件工程2022-2班', phone: '136****9012', status: '正常' },
|
|
|
{ id: '2022002', name: '钱七', gender: '女', className: '软件工程2022-2班', phone: '135****0123', status: '休学' }
|
|
|
])
|
|
|
|
|
|
const handleSelectionChange = (rows) => {
|
|
|
selectedRows.value = rows
|
|
|
hasSelected.value = rows.length > 0
|
|
|
}
|
|
|
|
|
|
const showAddDialog = () => {
|
|
|
editing.value = false
|
|
|
form.value = { id: '', name: '', gender: '男', className: '', phone: '' }
|
|
|
dialogVisible.value = true
|
|
|
}
|
|
|
|
|
|
const editStudent = (row) => {
|
|
|
editing.value = true
|
|
|
form.value = { ...row }
|
|
|
dialogVisible.value = true
|
|
|
}
|
|
|
|
|
|
const saveStudent = () => {
|
|
|
ElMessage.success(editing.value ? '编辑成功' : '添加成功')
|
|
|
dialogVisible.value = false
|
|
|
}
|
|
|
|
|
|
const deleteStudent = (row) => {
|
|
|
ElMessageBox.confirm(`确认删除学生 ${row.name}?`, '提示', { type: 'warning' })
|
|
|
.then(() => ElMessage.success('删除成功'))
|
|
|
.catch(() => {})
|
|
|
}
|
|
|
|
|
|
const batchDelete = () => {
|
|
|
ElMessageBox.confirm(`确认删除选中的 ${selectedRows.value.length} 名学生?`, '批量删除', { type: 'warning' })
|
|
|
.then(() => ElMessage.success('批量删除成功'))
|
|
|
.catch(() => {})
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.data-table-card {
|
|
|
background: #ffffff;
|
|
|
border-radius: 8px;
|
|
|
padding: 20px;
|
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
|
|
}
|
|
|
</style>
|