445 lines
17 KiB
Vue
445 lines
17 KiB
Vue
<template>
|
||
<div class="p-2 page-container">
|
||
<el-card>
|
||
<el-tabs v-model="activeTab">
|
||
<el-tab-pane label="全校管理员" name="school">
|
||
<!-- 检索栏(全校管理员) -->
|
||
<div class="mb-[10px]">
|
||
<el-card shadow="hover">
|
||
<el-form :inline="true" :model="schoolSearchForm" class="search-form">
|
||
<el-form-item label="姓名">
|
||
<el-input v-model="schoolSearchForm.managerName" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('school')" />
|
||
</el-form-item>
|
||
<el-form-item label="手机号码">
|
||
<el-input v-model="schoolSearchForm.phone" placeholder="请输入手机号码" clearable @keyup.enter="handleSearch('school')" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="Search" @click="handleSearch('school')">搜索</el-button>
|
||
<el-button icon="Refresh" @click="handleReset('school')">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-card>
|
||
</div>
|
||
<!-- 按钮+列表区域 -->
|
||
<el-card shadow="never">
|
||
<template #header>
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button type="primary" plain icon="Plus" @click="onAdd('school')">新增管理员</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
</template>
|
||
<el-table :data="filteredAdmins('school')" border>
|
||
<el-table-column prop="managerName" label="姓名" align="center" />
|
||
<el-table-column prop="phone" label="手机号码" align="center" />
|
||
<el-table-column prop="gender" label="性别" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.gender == 0 ? '男' : '女' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="remark" label="备注" align="center" />
|
||
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
|
||
<template #default="scope">
|
||
<el-tooltip content="编辑" placement="top">
|
||
<el-button link type="primary" plain icon="Edit" @click="onEdit('school', scope.row)" />
|
||
</el-tooltip>
|
||
<el-tooltip content="删除" placement="top">
|
||
<el-button link type="danger" plain icon="Delete" @click="onDelete('school', scope.row)" />
|
||
</el-tooltip>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
</el-tab-pane>
|
||
<el-tab-pane label="自定义管理员" name="custom">
|
||
<!-- 检索栏(自定义管理员) -->
|
||
<div class="mb-[10px]">
|
||
<el-card shadow="hover">
|
||
<el-form :inline="true" :model="customSearchForm" class="search-form">
|
||
<el-form-item label="姓名">
|
||
<el-input v-model="customSearchForm.managerName" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('custom')" />
|
||
</el-form-item>
|
||
<el-form-item label="手机号码">
|
||
<el-input v-model="customSearchForm.phone" placeholder="请输入手机号码" clearable @keyup.enter="handleSearch('custom')" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="Search" @click="fetchCustomAdminsWithScope('custom')">搜索</el-button>
|
||
<el-button icon="Refresh" @click="handleReset('custom')">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-card>
|
||
</div>
|
||
<el-card shadow="never">
|
||
<template #header>
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button type="primary" plain icon="Plus" @click="onAdd('custom')">新增管理员</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
</template>
|
||
<el-table :data="filteredAdmins('custom')" border>
|
||
<el-table-column prop="managerName" label="姓名" align="center" />
|
||
<el-table-column prop="phone" label="手机号码" align="center" />
|
||
<el-table-column prop="gender" label="性别" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.gender == 0 ? '男' : '女' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="scope" label="管理范围" align="center">
|
||
<template #default="scope">
|
||
<el-tooltip
|
||
v-if="scope.row.authSourceNames && scope.row.authSourceNames.length > 2"
|
||
:content="scope.row.authSourceNames.join(',')"
|
||
placement="top"
|
||
>
|
||
<span>
|
||
{{ scope.row.authSourceNames.slice(0, 2).join(',')
|
||
}}{{ scope.row.authSourceNames.length > 2 ? ' 等' + scope.row.authSourceNames.length + '个' : '' }}
|
||
</span>
|
||
</el-tooltip>
|
||
<span v-else>
|
||
{{ scope.row.authSourceNames?.join(',') || '-' }}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="remark" label="备注" align="center" />
|
||
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
|
||
<template #default="scope">
|
||
<el-tooltip content="编辑" placement="top">
|
||
<el-button link type="primary" plain icon="Edit" @click="onEdit('custom', scope.row)" />
|
||
</el-tooltip>
|
||
<el-tooltip content="分配范围" placement="top">
|
||
<el-button link type="warning" plain icon="Setting" @click="onScope('custom', scope.row)" />
|
||
</el-tooltip>
|
||
<el-tooltip content="删除" placement="top">
|
||
<el-button link type="danger" plain icon="Delete" @click="onDelete('custom', scope.row)" />
|
||
</el-tooltip>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
</el-tab-pane>
|
||
<el-tab-pane label="班主任" name="teacher">
|
||
<!-- 检索栏(班主任) -->
|
||
<div class="mb-[10px]">
|
||
<el-card shadow="hover">
|
||
<el-form :inline="true" :model="teacherSearchForm" class="search-form">
|
||
<el-form-item label="姓名">
|
||
<el-input v-model="teacherSearchForm.managerName" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('teacher')" />
|
||
</el-form-item>
|
||
<el-form-item label="手机号码">
|
||
<el-input v-model="teacherSearchForm.phone" placeholder="请输入手机号码" clearable @keyup.enter="handleSearch('teacher')" />
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button type="primary" icon="Search" @click="handleSearch('teacher')">搜索</el-button>
|
||
<el-button icon="Refresh" @click="handleReset('teacher')">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</el-card>
|
||
</div>
|
||
<el-card shadow="never">
|
||
<!-- <template #header>
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button type="primary" plain icon="Plus" @click="onAdd('teacher')">新增班主任</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
</template> -->
|
||
<el-table :data="filteredAdmins('teacher')" border>
|
||
<el-table-column prop="name" label="姓名" align="center" />
|
||
<el-table-column prop="phone" label="手机号码" align="center" />
|
||
<el-table-column prop="sex" label="性别" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.sex === 0 ? '男' : '女' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="className" label="所管理班级" align="center" />
|
||
<el-table-column prop="remark" label="备注" align="center" />
|
||
<!-- <el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
|
||
<template #default="scope">
|
||
<el-tooltip content="编辑" placement="top">
|
||
<el-button link type="primary" plain icon="Edit" @click="onEdit('teacher', scope.row)" />
|
||
</el-tooltip>
|
||
<el-tooltip content="分配班级" placement="top">
|
||
<el-button link type="warning" plain icon="Setting" @click="onScope('teacher', scope.row)" />
|
||
</el-tooltip>
|
||
<el-tooltip content="删除" placement="top">
|
||
<el-button link type="danger" plain icon="Delete" @click="onDelete('teacher', scope.row)" />
|
||
</el-tooltip>
|
||
</template>
|
||
</el-table-column> -->
|
||
</el-table>
|
||
</el-card>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
<admin-dialog v-model="dialogVisible" :mode="dialogMode" :admin="currentAdmin" :type="activeTab" @submit="onDialogSubmit" />
|
||
<scope-dialog v-model="scopeDialogVisible" :admin="currentAdmin" :type="scopeType" @submit="onScopeSubmit" />
|
||
</el-card>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, reactive, onMounted, watch } from 'vue';
|
||
import AdminDialog from './components/AdminDialog.vue';
|
||
import ScopeDialog from './components/ScopeDialog.vue';
|
||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||
import { listStudentManager, delStudentManager, listActiveClassTeachers } from '@/api/xgStudentManager/studentManager';
|
||
import type { StudentManagerQuery } from '@/api/xgStudentManager/studentManager/types';
|
||
import service from '@/utils/request';
|
||
|
||
// 暴露组件以修复导出问题
|
||
defineExpose({});
|
||
|
||
const activeTab = ref('school');
|
||
|
||
// 各tab独立检索表单
|
||
const schoolSearchForm = reactive<StudentManagerQuery>({
|
||
managerName: '',
|
||
phone: '',
|
||
managerType: '1',
|
||
pageNum: 1,
|
||
pageSize: 1000
|
||
});
|
||
const customSearchForm = reactive<StudentManagerQuery>({
|
||
managerName: '',
|
||
phone: '',
|
||
managerType: '2',
|
||
pageNum: 1,
|
||
pageSize: 1000
|
||
});
|
||
const teacherSearchForm = reactive({ managerName: '', phone: '' });
|
||
|
||
// 管理员数据
|
||
const schoolAdmins = ref([]);
|
||
const customAdmins = ref([]);
|
||
const teacherAdmins = ref([]);
|
||
|
||
const dialogVisible = ref(false);
|
||
const dialogMode = ref<'add' | 'edit'>('add');
|
||
const currentAdmin = ref<any>(null);
|
||
const scopeDialogVisible = ref(false);
|
||
const scopeType = ref('');
|
||
|
||
// 班主任模拟数据 (预留,后续完善)
|
||
const mockTeacherData = [
|
||
{ id: 5, name: '刘老师', phone: '13800138005', sex: 0, scope: '高一(1)班', remark: '数学教师' },
|
||
{ id: 6, name: '陈老师', phone: '13800138006', sex: 1, scope: '高一(2)班', remark: '语文教师' }
|
||
];
|
||
|
||
// 获取管理员列表
|
||
async function fetchAdmins(type: string) {
|
||
try {
|
||
const searchForm = getSearchForm(type);
|
||
|
||
if (type === 'school' || type === 'custom') {
|
||
// 调用API获取全校管理员或自定义管理员数据
|
||
const managerType = type === 'school' ? '1' : '2';
|
||
const res = await listStudentManager({
|
||
...searchForm,
|
||
managerType
|
||
});
|
||
// 更新对应类型的管理员数据
|
||
if (type === 'school') {
|
||
schoolAdmins.value = res.rows || [];
|
||
} else {
|
||
customAdmins.value = res.rows || [];
|
||
}
|
||
} else if (type === 'teacher') {
|
||
// 通过API获取班主任数据
|
||
const params = {
|
||
phone: searchForm.phone,
|
||
name: searchForm.managerName // teacherSearchForm 实际只有 managerName 字段
|
||
};
|
||
const res = await listActiveClassTeachers(params);
|
||
teacherAdmins.value = res.data || [];
|
||
}
|
||
} catch (error) {
|
||
console.error('获取管理员列表失败:', error);
|
||
ElMessage.error('获取管理员列表失败');
|
||
}
|
||
}
|
||
|
||
function getSearchForm(type: string) {
|
||
switch (type) {
|
||
case 'school':
|
||
return schoolSearchForm;
|
||
case 'custom':
|
||
return customSearchForm;
|
||
case 'teacher':
|
||
return teacherSearchForm;
|
||
default:
|
||
return schoolSearchForm;
|
||
}
|
||
}
|
||
|
||
// 获取自定义管理员及其管理范围
|
||
async function fetchCustomAdminsWithScope() {
|
||
await fetchAdmins('custom');
|
||
// 遍历 customAdmins,异步获取每个管理员的authSource
|
||
for (const admin of customAdmins.value) {
|
||
try {
|
||
const res = await service({
|
||
url: '/xgStudentManagerSource/studentManagerSource//authSourceNames',
|
||
method: 'get',
|
||
params: { managerId: admin.id }
|
||
});
|
||
admin.authSourceNames = res?.data || [];
|
||
} catch (e) {
|
||
admin.authSourceNames = [];
|
||
}
|
||
}
|
||
}
|
||
|
||
// 监听tab切换,切到custom时自动加载管理范围
|
||
watch(activeTab, (val) => {
|
||
if (val === 'custom') {
|
||
fetchCustomAdminsWithScope();
|
||
}
|
||
});
|
||
|
||
onMounted(() => {
|
||
fetchAdmins('school');
|
||
fetchCustomAdminsWithScope();
|
||
fetchAdmins('teacher');
|
||
});
|
||
|
||
function onAdd(type: string) {
|
||
dialogMode.value = 'add';
|
||
currentAdmin.value = { id: null, name: '', phone: '', sex: 0, remark: '', scope: '' };
|
||
activeTab.value = type; // 确保当前标签页与点击的按钮一致
|
||
dialogVisible.value = true;
|
||
}
|
||
|
||
function onEdit(type: string, admin: any) {
|
||
dialogMode.value = 'edit';
|
||
currentAdmin.value = { ...admin };
|
||
activeTab.value = type; // 确保当前标签页与编辑的管理员类型一致
|
||
dialogVisible.value = true;
|
||
}
|
||
|
||
async function onDelete(type: string, admin: any) {
|
||
// 二次确认
|
||
ElMessageBox.confirm(`确定要删除管理员【${admin.name || admin.managerName}】吗?`, '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
.then(async () => {
|
||
try {
|
||
if (type === 'school' || type === 'custom') {
|
||
// 调用删除API
|
||
const res = await delStudentManager(admin.id);
|
||
if (res.code === 200) {
|
||
ElMessage.success('删除成功');
|
||
fetchAdmins(type);
|
||
} else {
|
||
ElMessage.error(res.msg || '删除失败');
|
||
}
|
||
} else {
|
||
// 班主任暂时使用模拟数据
|
||
ElMessage.success('删除成功');
|
||
mockTeacherData.splice(
|
||
mockTeacherData.findIndex((item) => item.id === admin.id),
|
||
1
|
||
);
|
||
fetchAdmins(type);
|
||
}
|
||
} catch (e) {
|
||
ElMessage.error('删除失败');
|
||
}
|
||
})
|
||
.catch(() => {
|
||
// 用户取消
|
||
});
|
||
}
|
||
|
||
function onScope(type: string, admin: any) {
|
||
currentAdmin.value = { ...admin };
|
||
scopeType.value = type;
|
||
scopeDialogVisible.value = true;
|
||
}
|
||
|
||
function onDialogSubmit(admin: any) {
|
||
// 表单已在对话框组件内处理API调用
|
||
// 刷新列表数据
|
||
if (activeTab.value === 'custom') {
|
||
fetchCustomAdminsWithScope();
|
||
} else {
|
||
fetchAdmins(activeTab.value);
|
||
}
|
||
dialogVisible.value = false;
|
||
}
|
||
|
||
async function onScopeSubmit(scope: any) {
|
||
try {
|
||
// 范围分配已在对话框组件内处理API调用
|
||
// 成功后刷新数据并提示
|
||
ElMessage.success('管理范围分配成功');
|
||
fetchAdmins(scopeType.value);
|
||
fetchCustomAdminsWithScope();
|
||
scopeDialogVisible.value = false;
|
||
} catch (error) {
|
||
ElMessage.error('管理范围分配失败');
|
||
console.error(error);
|
||
}
|
||
}
|
||
|
||
function getListByType(type: string) {
|
||
switch (type) {
|
||
case 'school':
|
||
return schoolAdmins;
|
||
case 'custom':
|
||
return customAdmins;
|
||
case 'teacher':
|
||
return teacherAdmins;
|
||
default:
|
||
return schoolAdmins;
|
||
}
|
||
}
|
||
|
||
// 过滤
|
||
function filteredAdmins(type: string) {
|
||
if (type === 'custom') {
|
||
return customAdmins.value;
|
||
}
|
||
return getListByType(type).value;
|
||
}
|
||
|
||
function handleSearch(type: string) {
|
||
fetchAdmins(type);
|
||
}
|
||
|
||
function handleReset(type: string) {
|
||
switch (type) {
|
||
case 'school':
|
||
schoolSearchForm.managerName = '';
|
||
schoolSearchForm.phone = '';
|
||
break;
|
||
case 'custom':
|
||
customSearchForm.managerName = '';
|
||
customSearchForm.phone = '';
|
||
break;
|
||
case 'teacher':
|
||
teacherSearchForm.managerName = '';
|
||
teacherSearchForm.phone = '';
|
||
break;
|
||
}
|
||
if (type === 'custom') {
|
||
fetchCustomAdminsWithScope();
|
||
} else {
|
||
fetchAdmins(type);
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.el-card {
|
||
padding: 8px !important;
|
||
}
|
||
.search-form {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
}
|
||
</style>
|