提交学生管理权限设置的代码

This commit is contained in:
zlwu committed 2025-07-25 14:51:19 +08:00
1 parent 0917c7f156
commit 517a0052bc
28 files changed
+2506 -161

No files matched your search

@@ -0,0 +1,95 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { StudentManagerVO, StudentManagerForm, StudentManagerQuery } from '@/api/xgStudentManager/studentManager/types';
// 临时定义一个接口来表示返回的教师数据
export interface TeacherData {
id: string | number;
managerName: string;
phone: string;
gender: string;
}
/**
* 获取可用的教职工信息列表
* @param managerType 管理员类型(1 全校管理员 2 自定义管理员 3 班主任)
*/
export const listAvailableTeachers = (managerType: string): AxiosPromise<TeacherData[]> => {
return request({
url: '/xgStudentManager/studentManager/listAvailableTeachers',
method: 'get',
params: { managerType }
});
};
/**
* 查询宿舍管理员信息列表
* @param query
* @returns {*}
*/
export const listStudentManager = (query?: StudentManagerQuery): AxiosPromise<StudentManagerVO[]> => {
return request({
url: '/xgStudentManager/studentManager/list',
method: 'get',
params: query
});
};
/**
* 查询宿舍管理员信息详细
* @param id
*/
export const getStudentManager = (id: string | number): AxiosPromise<StudentManagerVO> => {
return request({
url: '/xgStudentManager/studentManager/' + id,
method: 'get'
});
};
/**
* 新增宿舍管理员信息
* @param data
*/
export const addStudentManager = (data: StudentManagerForm) => {
return request({
url: '/xgStudentManager/studentManager',
method: 'post',
data: data
});
};
/**
* 修改宿舍管理员信息
* @param data
*/
export const updateStudentManager = (data: StudentManagerForm) => {
return request({
url: '/xgStudentManager/studentManager',
method: 'put',
data: data
});
};
/**
* 删除宿舍管理员信息
* @param id
*/
export const delStudentManager = (id: string | number | Array<string | number>) => {
return request({
url: '/xgStudentManager/studentManager/' + id,
method: 'delete'
});
};
/**
* 获取当前正在教学的班主任信息
* @param params 包含 phone 和 name 字段
*/
export const listActiveClassTeachers = (params: { phone?: string; name?: string }) => {
return request({
url: '/xgStudentManager/studentManager/listActiveClassTeachers',
method: 'get',
params
});
};
@@ -0,0 +1,156 @@
export interface StudentManagerVO {
/**
* 主键ID
*/
id: string | number;
/**
* 管理员姓名
*/
managerName: string;
/**
* 管理员类型(1 全校管理员 2 自定义管理员 3 班主任)
*/
managerType: string;
/**
* 管理级别(1-3,1为最高)
*/
managerLevel: number;
/**
* 关联用户ID
*/
userId: string | number;
/**
* 联系电话
*/
phone: string;
/**
* 性别(0男 1女 2未知)
*/
gender: string;
/**
* 状态(0正常 1停用)
*/
status: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted: string;
/**
* 备注
*/
remark: string;
}
export interface StudentManagerForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 管理员姓名
*/
managerName?: string;
/**
* 管理员类型(1 全校管理员 2 自定义管理员 3 班主任)
*/
managerType?: string;
/**
* 管理级别(1-3,1为最高)
*/
managerLevel?: number;
/**
* 关联用户ID
*/
userId?: string | number;
/**
* 联系电话
*/
phone?: string;
/**
* 性别(0男 1女 2未知)
*/
gender?: string;
/**
* 状态(0正常 1停用)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 备注
*/
remark?: string;
}
export interface StudentManagerQuery extends PageQuery {
/**
* 管理员姓名
*/
managerName?: string;
/**
* 管理员类型(1 全校管理员 2 自定义管理员 3 班主任)
*/
managerType?: string;
/**
* 管理级别(1-3,1为最高)
*/
managerLevel?: number;
/**
* 关联用户ID
*/
userId?: string | number;
/**
* 联系电话
*/
phone?: string;
/**
* 性别(0男 1女 2未知)
*/
gender?: string;
/**
* 状态(0正常 1停用)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 日期范围参数
*/
params?: any;
}
@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { StudentManagerSourceVO, StudentManagerSourceForm, StudentManagerSourceQuery } from '@/api/xgStudentManagerSource/studentManagerSource/types';
/**
* 查询学生管理员授权关系列表
* @param query
* @returns {*}
*/
export const listStudentManagerSource = (query?: StudentManagerSourceQuery): AxiosPromise<StudentManagerSourceVO[]> => {
return request({
url: '/xgStudentManagerSource/studentManagerSource/list',
method: 'get',
params: query
});
};
/**
* 查询学生管理员授权关系详细
* @param id
*/
export const getStudentManagerSource = (id: string | number): AxiosPromise<StudentManagerSourceVO> => {
return request({
url: '/xgStudentManagerSource/studentManagerSource/' + id,
method: 'get'
});
};
/**
* 新增学生管理员授权关系
* @param data
*/
export const addStudentManagerSource = (data: StudentManagerSourceForm) => {
return request({
url: '/xgStudentManagerSource/studentManagerSource',
method: 'post',
data: data
});
};
/**
* 修改学生管理员授权关系
* @param data
*/
export const updateStudentManagerSource = (data: StudentManagerSourceForm) => {
return request({
url: '/xgStudentManagerSource/studentManagerSource',
method: 'put',
data: data
});
};
/**
* 删除学生管理员授权关系
* @param id
*/
export const delStudentManagerSource = (id: string | number | Array<string | number>) => {
return request({
url: '/xgStudentManagerSource/studentManagerSource/' + id,
method: 'delete'
});
};
@@ -0,0 +1,126 @@
export interface StudentManagerSourceVO {
/**
* 主键ID
*/
id: string | number;
/**
* 管理员ID
*/
managerId: string | number;
/**
* 权限类型(1查看 2编辑 3完全管理)
*/
permissionType: string;
/**
* 授权类型(1全校级 2自定义 3班主任)
*/
authType: string;
/**
* 授权来源ID(对应班级id)
*/
authSource: number;
/**
* 状态(0有效 1已撤销)
*/
status: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted: string;
/**
* 备注
*/
remark: string;
}
export interface StudentManagerSourceForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 管理员ID
*/
managerId?: string | number;
/**
* 权限类型(1查看 2编辑 3完全管理)
*/
permissionType?: string;
/**
* 授权类型(1全校级 2自定义 3班主任)
*/
authType?: string;
/**
* 授权来源ID(对应班级id)
*/
authSource?: number;
/**
* 状态(0有效 1已撤销)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 备注
*/
remark?: string;
}
export interface StudentManagerSourceQuery extends PageQuery {
/**
* 管理员ID
*/
managerId?: string | number;
/**
* 权限类型(1查看 2编辑 3完全管理)
*/
permissionType?: string;
/**
* 授权类型(1全校级 2自定义 3班主任)
*/
authType?: string;
/**
* 授权来源ID(对应班级id)
*/
authSource?: number;
/**
* 状态(0有效 1已撤销)
*/
status?: string;
/**
* 删除标志(0代表存在 1代表删除)
*/
deleted?: string;
/**
* 日期范围参数
*/
params?: any;
}
@@ -8,7 +8,21 @@
>
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
<el-select
v-model="form.name"
filterable
placeholder="请选择教师姓名"
@change="handleTeacherChange"
:disabled="mode === 'edit'"
style="width: 100%"
>
<el-option v-for="item in teacherOptions" :key="item.id" :label="item.managerName" :value="item.managerName">
<div>
<span> {{ item.managerName }} </span>
<span style="color: #8492a6; font-size: 13px"> ({{ item.phone }}) ({{ item.userId }}) </span>
</div>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="手机号码" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号码" />
@@ -33,8 +47,68 @@
</template>
<script setup lang="ts">
import { ref, reactive, watchEffect, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { ref, reactive, watchEffect, computed, onMounted } from 'vue';
import { ElMessage, type FormInstance } from 'element-plus';
import request from '@/utils/request';
/**
* 教师信息数据结构
*/
interface TeacherData {
/** 教师ID */
userId: string | number;
/** 管理员姓名 */
managerName: string;
/** 手机号码 */
phone: string;
/** 性别(0男 1女) */
gender: string;
}
/**
* 获取可用的教职工信息列表
* @param managerType 管理员类型(1 全校管理员 2 自定义管理员 3 班主任)
*/
const listAvailableTeachers = (managerType: string) => {
return request({
url: '/xgStudentManager/studentManager/listAvailableTeachers',
method: 'get',
params: { managerType }
});
};
/**
* 新增宿舍管理员信息
*/
const addStudentManager = (data: any) => {
return request({
url: '/xgStudentManager/studentManager',
method: 'post',
data: data
});
};
/**
* 修改宿舍管理员信息
*/
const updateStudentManager = (data: any) => {
return request({
url: '/xgStudentManager/studentManager',
method: 'put',
data: data
});
};
// 在setup函数中引入这种方式提示弹窗
const message = (type: 'success' | 'error' | 'info', text: string) => {
if (type === 'success') {
ElMessage.success(text);
} else if (type === 'error') {
ElMessage.error(text);
} else {
ElMessage.info(text);
}
};
const props = defineProps({
modelValue: {
@@ -57,6 +131,9 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue', 'submit']);
// 教师选项列表
const teacherOptions = ref<TeacherData[]>([]);
// 计算属性:对话框可见性
const visible = computed({
get: () => props.modelValue,
@@ -64,9 +141,10 @@ const visible = computed({
});
// 表单和校验
const formRef = ref(null);
const formRef = ref<FormInstance>();
const form = reactive({
id: null,
userId: null,
name: '',
phone: '',
sex: 0,
@@ -74,27 +152,81 @@ const form = reactive({
});
// 表单校验规则
const rules = reactive({
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
const rules = {
name: [{ required: true, message: '请选择姓名', trigger: 'change' }],
phone: [
{ required: true, message: '请输入手机号码', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
]
});
};
// 获取管理员类型对应的值
const getManagerType = (type: string): string => {
switch (type) {
case 'school':
return '1'; // 全校管理员
case 'custom':
return '2'; // 自定义管理员
case 'teacher':
return '3'; // 班主任
default:
return '1';
}
};
// 加载可用教师列表
const loadTeachers = async () => {
try {
const managerType = getManagerType(props.type);
const res = await listAvailableTeachers(managerType);
if (res.data) {
teacherOptions.value = res.data;
}
} catch (error) {
console.error('获取可用教师列表失败', error);
}
};
// 选择教师后的处理
const handleTeacherChange = (value: string) => {
const selectedTeacher = teacherOptions.value.find((item) => item.managerName === value);
if (selectedTeacher) {
console.log(selectedTeacher.gender === '0');
// 自动填充手机号码和性别
form.phone = selectedTeacher.phone || '';
form.sex = selectedTeacher.gender === '0' ? 0 : 1; // 0男 1女
form.userId = selectedTeacher.userId;
}
};
// 监听传入的admin数据,更新表单
watchEffect(() => {
if (props.admin) {
form.id = props.admin.id;
form.name = props.admin.name;
form.userId = props.admin.userId;
form.name = props.admin.managerName;
form.phone = props.admin.phone;
form.sex = props.admin.sex;
form.sex = props.admin.gender === '0' ? 0 : 1;
form.remark = props.admin.remark;
}
});
// 监听对话框可见性变化,当打开时加载教师列表
watchEffect(() => {
if (visible.value && props.mode === 'add') {
loadTeachers();
}
});
// 组件挂载时加载教师列表
onMounted(() => {
if (props.mode === 'add') {
loadTeachers();
}
});
// 根据类型获取标签文本
function getTypeLabel(type) {
function getTypeLabel(type: string): string {
switch (type) {
case 'school':
return '全校管理员';
@@ -108,21 +240,43 @@ function getTypeLabel(type) {
}
// 提交表单
function submitForm() {
formRef.value?.validate((valid) => {
async function submitForm() {
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
// 这里模拟保存
emit('submit', {
id: form.id,
name: form.name,
phone: form.phone,
sex: form.sex,
remark: form.remark,
scope: props.admin?.scope || ''
});
try {
const formData = {
id: form.id,
managerName: form.name,
userId: form.userId,
phone: form.phone,
gender: form.sex,
remark: form.remark,
status: '0',
// scope: props.admin?.scope || '',
managerType: getManagerType(props.type),
managerLevel: getManagerType(props.type)
};
ElMessage.success('保存成功');
visible.value = false;
let result;
if (props.mode === 'add') {
// 调用添加接口
result = await addStudentManager(formData);
} else {
// 调用更新接口
result = await updateStudentManager(formData);
}
if (result.code === 200) {
message('success', props.mode === 'add' ? '添加成功' : '更新成功');
// 通知父组件处理成功
emit('submit', formData);
visible.value = false;
} else {
message('error', result.msg || '操作失败');
}
} catch (error: any) {
message('error', '操作失败: ' + (error.message || '未知错误'));
}
}
});
}
@@ -2,17 +2,35 @@
<el-dialog :title="getScopeDialogTitle(type)" v-model="visible" width="600px" append-to-body destroy-on-close>
<el-form :model="form" label-width="100px">
<el-form-item :label="getScopeName(type)">
<div v-if="type === 'custom'">
<el-checkbox-group v-model="form.selectedScopes">
<el-checkbox v-for="item in scopeOptions.custom" :key="item.id" :label="item.id">
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
<div v-if="loading" class="loading-container">
<el-icon class="is-loading"><Loading /></el-icon>
<span>加载中...</span>
</div>
<div v-else-if="type === 'custom'">
<el-tree
:data="scopeOptions.custom"
show-checkbox
node-key="id"
:default-checked-keys="form.selectedScopes"
:props="{ label: 'label', children: 'children' }"
@check="onTreeCheck"
default-expand-all
style="
width: 100%;
min-width: 100%;
overflow-x: auto;
overflow-y: auto;
/* border: 1px solid #ebeef5; */
border-radius: 4px;
padding: 10px;
box-sizing: border-box;
"
/>
</div>
<div v-else-if="type === 'teacher'">
<el-checkbox-group v-model="form.selectedScopes">
<el-checkbox v-for="item in scopeOptions.teacher" :key="item.id" :label="item.id">
{{ item.name }}
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</div>
@@ -21,15 +39,18 @@
<template #footer>
<div class="dialog-footer">
<el-button @click="cancel">取 消</el-button>
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button type="primary" @click="submitForm" :loading="loading">确 定</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, reactive, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { ref, reactive, computed, watch, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { Loading } from '@element-plus/icons-vue';
import axios from 'axios';
import request from '@/utils/request';
const props = defineProps({
modelValue: {
@@ -54,35 +75,107 @@ const visible = computed({
set: (value) => emit('update:modelValue', value)
});
// 范围选项(模拟数据)
const scopeOptions = {
custom: [
{ id: 1, name: '高一年级' },
{ id: 2, name: '高二年级' },
{ id: 3, name: '高三年级' },
{ id: 4, name: '初一年级' },
{ id: 5, name: '初二年级' },
{ id: 6, name: '初三年级' }
],
teacher: [
{ id: 101, name: '高一(1)班' },
{ id: 102, name: '高一(2)班' },
{ id: 103, name: '高一(3)班' },
{ id: 104, name: '高二(1)班' },
{ id: 105, name: '高二(2)班' },
{ id: 106, name: '高三(1)班' },
{ id: 107, name: '高三(2)班' }
]
};
// 范围选项(从API获取)
const scopeOptions = reactive({
custom: [] as any[],
teacher: [] as any[]
});
// 加载状态
const loading = ref(false);
// 表单数据
const form = reactive({
selectedScopes: [] as number[]
});
// 获取部门树数据
async function fetchDeptTree() {
try {
loading.value = true;
const response = await request({
url: '/system/user/deptTree',
method: 'get',
params: {
belongDeptId: 101
}
});
if (response && response.code === 200) {
// custom类型直接使用树形结构
if (props.type === 'custom') {
scopeOptions.custom = response.data || [];
} else if (props.type === 'teacher') {
// teacher类型仍可用扁平化
scopeOptions.teacher = flattenTreeData(response.data || []);
}
}
} catch (error) {
console.error('获取部门树数据失败:', error);
ElMessage.error('获取范围选项失败');
} finally {
loading.value = false;
}
}
// 将树形数据扁平化
function flattenTreeData(treeData: any[]): any[] {
const result: any[] = [];
function traverse(nodes: any[]) {
nodes.forEach((node) => {
result.push({
id: node.id,
label: node.label
});
if (node.children && node.children.length > 0) {
traverse(node.children);
}
});
}
traverse(treeData);
return result;
}
// 新增:获取历史范围数据
async function fetchSelectedScopes(managerId: number | string) {
if (!managerId) return;
try {
const res = await request({
url: '/xgStudentManagerSource/studentManagerSource/list',
method: 'get',
params: { managerId }
});
if (res && res.code === 200) {
// 提取rows中的authSource字段作为已选范围ID
form.selectedScopes = (res.rows || []).map((item: any) => item.authSource);
}
} catch (e) {
form.selectedScopes = [];
}
}
// 监听对话框显示状态,自动加载数据
watch(visible, async (newVal) => {
if (newVal) {
const managerId = props.admin?.managerId || props.admin?.id;
await fetchDeptTree();
await fetchSelectedScopes(managerId);
} else {
// 对话框关闭时清空选择
form.selectedScopes = [];
}
});
// el-tree勾选事件,确保能正确获取所有勾选节点的id
function onTreeCheck(checkedNodes: any, info: { checkedKeys: any[]; halfCheckedKeys: any[] }) {
form.selectedScopes = info.checkedKeys;
}
// 获取范围对话框标题
function getScopeDialogTitle(type: string) {
const name = props.admin?.name || '';
const name = props.admin?.managerName || '';
switch (type) {
case 'custom':
return `为【${name}】分配管理范围`;
@@ -106,32 +199,33 @@ function getScopeName(type: string) {
}
// 提交表单
function submitForm() {
async function submitForm() {
// 组装要提交的数据
const selectedIds = form.selectedScopes;
let scopeName = '';
// 根据类型获取选中的名称
if (type.value === 'custom') {
scopeName = scopeOptions.custom
.filter((item) => selectedIds.includes(item.id))
.map((item) => item.name)
.join(', ');
} else if (type.value === 'teacher') {
scopeName = scopeOptions.teacher
.filter((item) => selectedIds.includes(item.id))
.map((item) => item.name)
.join(', ');
console.log(selectedIds);
const managerId = props.admin?.managerId || props.admin?.id; // 兼容不同字段
if (!managerId) {
ElMessage.error('管理员ID缺失,无法提交');
return;
}
loading.value = true;
try {
await request({
url: '/xgStudentManagerSource/studentManagerSource/grantDeptAuth',
method: 'post',
params: { managerId },
data: selectedIds
});
ElMessage.success('分配成功');
visible.value = false;
emit('submit', {
sourceIds: selectedIds
});
} catch (error) {
ElMessage.error('分配失败,请重试');
} finally {
loading.value = false;
}
// 提交
emit('submit', {
sourceIds: selectedIds,
scopeName: scopeName
});
ElMessage.success('分配成功');
visible.value = false;
}
// 取消
@@ -145,7 +239,8 @@ const type = computed(() => props.type);
// 暴露组件以修复导出问题
defineExpose({
submitForm,
cancel
cancel,
fetchDeptTree
});
</script>
@@ -162,4 +257,15 @@ defineExpose({
margin-right: 15px;
margin-bottom: 10px;
}
.loading-container {
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
color: #909399;
}
.loading-container .el-icon {
margin-right: 8px;
font-size: 16px;
}
</style>
+83 -82
View File
@@ -8,7 +8,7 @@
<el-card shadow="hover">
<el-form :inline="true" :model="schoolSearchForm" class="search-form">
<el-form-item label="姓名">
<el-input v-model="schoolSearchForm.name" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('school')" />
<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')" />
@@ -30,11 +30,11 @@
</el-row>
</template>
<el-table :data="filteredAdmins('school')" border>
<el-table-column prop="name" label="姓名" align="center" />
<el-table-column prop="managerName" label="姓名" align="center" />
<el-table-column prop="phone" label="手机号码" align="center" />
<el-table-column prop="sex" label="性别" align="center">
<el-table-column prop="gender" label="性别" align="center">
<template #default="scope">
{{ scope.row.sex === 0 ? '男' : '女' }}
{{ scope.row.gender == 0 ? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" align="center" />
@@ -57,7 +57,7 @@
<el-card shadow="hover">
<el-form :inline="true" :model="customSearchForm" class="search-form">
<el-form-item label="姓名">
<el-input v-model="customSearchForm.name" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('custom')" />
<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')" />
@@ -78,11 +78,11 @@
</el-row>
</template>
<el-table :data="filteredAdmins('custom')" border>
<el-table-column prop="name" label="姓名" align="center" />
<el-table-column prop="managerName" label="姓名" align="center" />
<el-table-column prop="phone" label="手机号码" align="center" />
<el-table-column prop="sex" label="性别" align="center">
<el-table-column prop="gender" label="性别" align="center">
<template #default="scope">
{{ scope.row.sex === 0 ? '男' : '女' }}
{{ scope.row.gender == 0 ? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="scope" label="管理范围" align="center" />
@@ -109,7 +109,7 @@
<el-card shadow="hover">
<el-form :inline="true" :model="teacherSearchForm" class="search-form">
<el-form-item label="姓名">
<el-input v-model="teacherSearchForm.name" placeholder="请输入姓名" clearable @keyup.enter="handleSearch('teacher')" />
<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')" />
@@ -122,13 +122,13 @@
</el-card>
</div>
<el-card shadow="never">
<template #header>
<!-- <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>
</template> -->
<el-table :data="filteredAdmins('teacher')" border>
<el-table-column prop="name" label="姓名" align="center" />
<el-table-column prop="phone" label="手机号码" align="center" />
@@ -137,9 +137,9 @@
{{ scope.row.sex === 0 ? '男' : '女' }}
</template>
</el-table-column>
<el-table-column prop="scope" label="所管理班级" align="center" />
<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">
<!-- <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)" />
@@ -151,7 +151,7 @@
<el-button link type="danger" plain icon="Delete" @click="onDelete('teacher', scope.row)" />
</el-tooltip>
</template>
</el-table-column>
</el-table-column> -->
</el-table>
</el-card>
</el-tab-pane>
@@ -167,19 +167,30 @@ import { ref, reactive, onMounted } 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';
// 暴露组件以修复导出问题
defineExpose({});
// 导入改为使用模拟数据
// import { getAdminList, deleteAdmin, assignScope, getScopeNames } from '@/api/studentMsg/authmsg';
const activeTab = ref('school');
// 各tab独立检索表单
const schoolSearchForm = reactive({ name: '', phone: '' });
const customSearchForm = reactive({ name: '', phone: '' });
const teacherSearchForm = reactive({ name: '', phone: '' });
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([]);
@@ -192,46 +203,39 @@ const currentAdmin = ref<any>(null);
const scopeDialogVisible = ref(false);
const scopeType = ref('');
// 模拟数据
const mockData = {
school: [
{ id: 1, name: '张校长', phone: '13800138001', sex: 0, remark: '全校管理员' },
{ id: 2, name: '李主任', phone: '13800138002', sex: 1, remark: '教务处负责人' }
],
custom: [
{ id: 3, name: '王组长', phone: '13800138003', sex: 0, scope: '高一年级', remark: '年级组长' },
{ id: 4, name: '赵主管', phone: '13800138004', sex: 1, scope: '高二年级', remark: '年级负责人' }
],
teacher: [
{ id: 5, name: '刘老师', phone: '13800138005', sex: 0, scope: '高一(1)班', remark: '数学教师' },
{ id: 6, name: '陈老师', phone: '13800138006', sex: 1, scope: '高一(2)班', remark: '语文教师' }
]
};
// 班主任模拟数据 (预留,后续完善)
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) {
// 实际项目中这里会调用API
// 此处使用模拟数据
try {
// 模拟API检索过滤
const searchForm = getSearchForm(type);
const filteredData = mockData[type].filter((item) => {
const nameMatch = !searchForm.name || item.name.includes(searchForm.name);
const phoneMatch = !searchForm.phone || item.phone.includes(searchForm.phone);
return nameMatch && phoneMatch;
});
// 更新对应类型的管理员数据
switch (type) {
case 'school':
schoolAdmins.value = filteredData;
break;
case 'custom':
customAdmins.value = filteredData;
break;
case 'teacher':
teacherAdmins.value = filteredData;
break;
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);
@@ -274,17 +278,31 @@ function onEdit(type: string, admin: any) {
async function onDelete(type: string, admin: any) {
// 二次确认
ElMessageBox.confirm(`确定要删除管理员【${admin.name}】吗?`, '提示', {
ElMessageBox.confirm(`确定要删除管理员【${admin.name || admin.managerName}】吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
try {
// 模拟删除成功
mockData[type] = mockData[type].filter((item) => item.id !== admin.id);
ElMessage.success('删除成功');
fetchAdmins(type); // 删除后刷新
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('删除失败');
}
@@ -301,20 +319,7 @@ function onScope(type: string, admin: any) {
}
function onDialogSubmit(admin: any) {
// 模拟添加或编辑操作
if (dialogMode.value === 'add') {
// 生成新ID
const newId = Math.max(...mockData[activeTab.value].map((item) => item.id), 0) + 1;
admin.id = newId;
mockData[activeTab.value].push(admin);
} else {
// 编辑
const index = mockData[activeTab.value].findIndex((item) => item.id === admin.id);
if (index !== -1) {
mockData[activeTab.value][index] = admin;
}
}
// 表单已在对话框组件内处理API调用
// 刷新列表数据
fetchAdmins(activeTab.value);
dialogVisible.value = false;
@@ -322,12 +327,7 @@ function onDialogSubmit(admin: any) {
async function onScopeSubmit(scope: any) {
try {
// 模拟分配范围
const index = mockData[scopeType.value].findIndex((item) => item.id === currentAdmin.value.id);
if (index !== -1) {
mockData[scopeType.value][index].scope = scope.scopeName;
}
// 范围分配已在对话框组件内处理API调用
// 成功后刷新数据并提示
ElMessage.success('管理范围分配成功');
fetchAdmins(scopeType.value);
@@ -353,6 +353,7 @@ function getListByType(type: string) {
// 过滤
function filteredAdmins(type: string) {
console.log(getListByType(type).value);
return getListByType(type).value;
}
@@ -363,15 +364,15 @@ function handleSearch(type: string) {
function handleReset(type: string) {
switch (type) {
case 'school':
schoolSearchForm.name = '';
schoolSearchForm.managerName = '';
schoolSearchForm.phone = '';
break;
case 'custom':
customSearchForm.name = '';
customSearchForm.managerName = '';
customSearchForm.phone = '';
break;
case 'teacher':
teacherSearchForm.name = '';
teacherSearchForm.managerName = '';
teacherSearchForm.phone = '';
break;
}