This commit is contained in:
zlwu committed 2025-07-26 17:54:01 +08:00
1 parent 3b3d2bb157
commit 94f07a059b
69 files changed
+2787 -643

No files matched your search

+2
View File
@@ -152,6 +152,8 @@ export interface ClassMsgVO {
lastCountUpdate?: string;
/** 备注 */
remark?: string;
/** 学制 */
schoolSystem?: string;
}
/** 班级表单数据 */
+5 -5
View File
@@ -227,7 +227,7 @@ const mockStudentData: StudentVO[] = [
classId: 101,
className: '计算机2001班',
address: '北京市海淀区',
status: '0',
studentStatus: '1',
createTime: '2023-01-01 10:00:00',
remark: ''
},
@@ -248,7 +248,7 @@ const mockStudentData: StudentVO[] = [
classId: 101,
className: '计算机2001班',
address: '上海市浦东新区',
status: '0',
studentStatus: '2',
createTime: '2023-01-01 10:10:00',
remark: ''
},
@@ -269,7 +269,7 @@ const mockStudentData: StudentVO[] = [
classId: 201,
className: '软工2001班',
address: '广州市天河区',
status: '0',
studentStatus: '5',
createTime: '2023-01-02 09:00:00',
remark: ''
},
@@ -290,7 +290,7 @@ const mockStudentData: StudentVO[] = [
classId: 201,
className: '软工2001班',
address: '深圳市南山区',
status: '0',
studentStatus: '3',
createTime: '2023-01-02 10:30:00',
remark: ''
},
@@ -311,7 +311,7 @@ const mockStudentData: StudentVO[] = [
classId: 301,
className: '人工智能2001班',
address: '杭州市西湖区',
status: '1', // 停用状态
studentStatus: '4',
createTime: '2023-01-03 11:20:00',
remark: '休学中'
}
+4 -4
View File
@@ -35,7 +35,7 @@ export interface StudentMsgVO {
formerName: string;
/**
* 性别:M-男,F-女
* 性别:0-男,1-女
*/
gender: string;
@@ -558,7 +558,7 @@ export interface StudentMsgForm extends BaseEntity {
formerName?: string;
/**
* 性别:M-男,F-女
* 性别:0-男,1-女
*/
gender?: string;
@@ -940,7 +940,7 @@ export interface StudentMsgForm extends BaseEntity {
/**
* 学历层次 - 预留,数据从班级表关联
*/
academicLevel?: string;
academicLevel?: string | number;
/**
* 培养方式:全日制、在职、函授、夜大等 - 预留,数据从班级表关联
@@ -1077,7 +1077,7 @@ export interface StudentMsgQuery extends PageQuery {
formerName?: string;
/**
* 性别:M-男,F-女
* 性别:0-男,1-女
*/
gender?: string;
+13 -12
View File
@@ -14,32 +14,32 @@ export interface XgDeptTreeVO extends BaseEntity {
export interface StudentQuery {
pageNum: number;
pageSize: number;
studentName?: string;
name?: string;
studentNo?: string;
phonenumber?: string;
status?: string;
phone?: string;
studentStatus?: string;
deptId?: number;
}
// 学生视图对象
export interface StudentVO {
studentId: number | string;
id: number | string;
studentNo: string;
studentName: string;
name: string;
nickName?: string;
sex?: string;
gender?: string;
age?: number;
phonenumber?: string;
phone?: string;
email?: string;
idCard?: string;
deptId?: number;
deptName?: string;
collegeId?: number;
colegeName?: string;
majorId?: number;
majorName?: string;
classId?: number;
className?: string;
address?: string;
status?: string;
studentStatus?: string;
createBy?: number;
createTime?: string;
updateBy?: number;
@@ -49,6 +49,7 @@ export interface StudentVO {
// 学生表单对象
export interface StudentForm {
id?: number | string;
// 原有字段
studentId?: number | string;
deptId?: number;
@@ -129,8 +130,8 @@ export interface StudentForm {
family_members?: string;
// 健康信息字段
height?: string;
weight?: string;
height?: number | string;
weight?: number | string;
blood_type?: string;
health_status?: string;
special_condition?: string;
+63
View File
@@ -0,0 +1,63 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { SysRegionVO, SysRegionForm, SysRegionQuery } from '@/api/system/SysRegion/types';
/**
* 查询行政区划列表
* @param query
* @returns {*}
*/
export const listSysRegion = (query?: SysRegionQuery): AxiosPromise<SysRegionVO[]> => {
return request({
url: '/system/SysRegion/list',
method: 'get',
params: query
});
};
/**
* 查询行政区划详细
* @param id
*/
export const getSysRegion = (id: string | number): AxiosPromise<SysRegionVO> => {
return request({
url: '/system/SysRegion/' + id,
method: 'get'
});
};
/**
* 新增行政区划
* @param data
*/
export const addSysRegion = (data: SysRegionForm) => {
return request({
url: '/system/SysRegion',
method: 'post',
data: data
});
};
/**
* 修改行政区划
* @param data
*/
export const updateSysRegion = (data: SysRegionForm) => {
return request({
url: '/system/SysRegion',
method: 'put',
data: data
});
};
/**
* 删除行政区划
* @param id
*/
export const delSysRegion = (id: string | number | Array<string | number>) => {
return request({
url: '/system/SysRegion/' + id,
method: 'delete'
});
};
+186
View File
@@ -0,0 +1,186 @@
export interface SysRegionVO {
/**
* 主键ID
*/
id: string | number;
/**
* 行政区划编码
*/
code: string;
/**
* 行政区划名称
*/
name: string;
/**
* 行政区划简称
*/
shortName: string;
/**
* 父级行政区划编码,顶级为0
*/
parentCode: number;
/**
* 层级(1:省,2:市,3:区/县,4:街道/镇)
*/
level: number;
/**
* 排序
*/
sort: number;
/**
* 状态(0正常 1停用)
*/
status: string;
/**
* 备注
*/
remark: string;
/**
* 经度
*/
longitude: number;
/**
* 纬度
*/
latitude: number;
/**
* 逻辑删除标识(0未删除 1已删除)
*/
deleted: number;
}
export interface SysRegionForm extends BaseEntity {
/**
* 主键ID
*/
id?: string | number;
/**
* 行政区划编码
*/
code?: string;
/**
* 行政区划名称
*/
name?: string;
/**
* 行政区划简称
*/
shortName?: string;
/**
* 父级行政区划编码,顶级为0
*/
parentCode?: number;
/**
* 层级(1:省,2:市,3:区/县,4:街道/镇)
*/
level?: number;
/**
* 排序
*/
sort?: number;
/**
* 状态(0正常 1停用)
*/
status?: string;
/**
* 备注
*/
remark?: string;
/**
* 经度
*/
longitude?: number;
/**
* 纬度
*/
latitude?: number;
/**
* 逻辑删除标识(0未删除 1已删除)
*/
deleted?: number;
}
export interface SysRegionQuery extends PageQuery {
/**
* 行政区划编码
*/
code?: string;
/**
* 行政区划名称
*/
name?: string;
/**
* 行政区划简称
*/
shortName?: string;
/**
* 父级行政区划编码,顶级为0
*/
parentCode?: number;
/**
* 层级(1:省,2:市,3:区/县,4:街道/镇)
*/
level?: number;
/**
* 排序
*/
sort?: number;
/**
* 状态(0正常 1停用)
*/
status?: string;
/**
* 经度
*/
longitude?: number;
/**
* 纬度
*/
latitude?: number;
/**
* 逻辑删除标识(0未删除 1已删除)
*/
deleted?: number;
/**
* 日期范围参数
*/
params?: any;
}
+1
View File
@@ -48,6 +48,7 @@ export interface UserVO extends BaseEntity {
postIds: any;
roleId: any;
admin: boolean;
accountType: string;
}
/**
+3 -3
View File
@@ -236,7 +236,7 @@ export interface XljkEvaluationDetailVO {
studentName: string;
/**
* 性别(M-男,F-女)
* 性别(0-男,1-女)
*/
gender: string;
@@ -328,7 +328,7 @@ export interface XljkEvaluationDetailForm extends BaseEntity {
studentName?: string;
/**
* 性别(M-男,F-女)
* 性别(0-男,1-女)
*/
gender?: string;
@@ -407,7 +407,7 @@ export interface StudentInfo {
studentName: string;
/**
* 性别(M-男,F-女)
* 性别(0-男,1-女)
*/
gender: string;
+3 -3
View File
@@ -15,7 +15,7 @@ export interface EnrollmentInfoVO {
idCard: string;
/**
* 性别(M-男 F-女)
* 性别(0-男 1-女)
*/
gender: string;
@@ -197,7 +197,7 @@ export interface EnrollmentInfoForm extends BaseEntity {
idCard?: string;
/**
* 性别(M-男 F-女)
* 性别(0-男 1-女)
*/
gender?: string;
@@ -354,7 +354,7 @@ export interface EnrollmentInfoQuery extends PageQuery {
idCard?: string;
/**
* 性别(M-男 F-女)
* 性别(0-男 1-女)
*/
gender?: string;
+1 -1
View File
@@ -153,7 +153,7 @@ export interface EnrollmentProcessVO {
updateTime: string
/**
* 性别(M-男 F-女)
* 性别(0-男 1-女)
*/
gender?: string
+13 -3
View File
@@ -83,6 +83,7 @@
<el-table-column label="辅导员" align="center" prop="counselorName" />
<el-table-column label="年级" align="center" prop="grade" />
<el-table-column label="入学年份" align="center" prop="enrollmentYear" />
<el-table-column label="学制(年)" align="center" prop="schoolSystem" />
<el-table-column label="毕业年份" align="center" prop="graduationYear" />
<el-table-column label="班级状态" align="center" prop="classStatus">
<template #default="scope">
@@ -156,8 +157,8 @@
<el-form-item label="班级名称" prop="className">
<el-input v-model="form.className" placeholder="请输入班级名称" />
</el-form-item>
<el-form-item label="班级类型" prop="classType">
<el-select v-model="form.classType" placeholder="请选择班级类型" style="width: 100%">
<el-form-item label="学历层级" prop="classType">
<el-select v-model="form.classType" placeholder="请选择学历层级" style="width: 100%">
<el-option label="中级工" :value="1" />
<el-option label="高级工" :value="2" />
<el-option label="预备技师" :value="3" />
@@ -171,6 +172,9 @@
<el-form-item label="入学年份" prop="enrollmentYear">
<el-input v-model="form.enrollmentYear" placeholder="请输入入学年份" />
</el-form-item>
<el-form-item label="学制(年)" prop="schoolSystem">
<el-input v-model="form.schoolSystem" placeholder="请输入学制(年)" />
</el-form-item>
<el-form-item label="毕业年份" prop="graduationYear">
<el-input v-model="form.graduationYear" placeholder="请输入毕业年份" />
</el-form-item>
@@ -457,6 +461,7 @@ const initFormData: ClassMsgForm = {
classType: undefined,
grade: undefined,
enrollmentYear: undefined,
schoolSystem: undefined,
graduationYear: undefined,
trainingType: undefined,
degreeType: undefined,
@@ -514,7 +519,12 @@ const data = reactive<PageData<ClassMsgForm, ClassMsgQuery>>({
classCode: [{ required: true, message: '班级代码不能为空', trigger: 'blur' }],
className: [{ required: true, message: '班级名称不能为空', trigger: 'blur' }],
grade: [{ required: true, message: '年级不能为空', trigger: 'blur' }],
enrollmentYear: [{ required: true, message: '入学年份不能为空', trigger: 'blur' }]
enrollmentYear: [{ required: true, message: '入学年份不能为空', trigger: 'blur' }],
majorId: [{ required: true, message: '专业不能为空', trigger: 'blur' }],
classType: [{ required: true, message: '学历层级不能为空', trigger: 'blur' }],
schoolSystem: [{ required: true, message: '学制(年)不能为空', trigger: 'blur' }],
graduationYear: [{ required: true, message: '毕业年份不能为空', trigger: 'blur' }],
collegeId: [{ required: true, message: '学院不能为空', trigger: 'blur' }]
}
});
+1 -1
View File
@@ -279,7 +279,7 @@ async function fetchCustomAdminsWithScope() {
for (const admin of customAdmins.value) {
try {
const res = await service({
url: '/xgStudentManagerSource/studentManagerSource//authSourceNames',
url: '/xgStudentManagerSource/studentManagerSource/authSourceNames',
method: 'get',
params: { managerId: admin.id }
});
File diff suppressed because it is too large. Load diff
+98 -17
View File
@@ -2,7 +2,7 @@
<div class="p-2">
<div style="display: flex; gap: 16px">
<!-- 部门树 -->
<div style="width: 300px">
<div style="width: 360px">
<el-card shadow="hover">
<el-input v-model="deptName" placeholder="请输入部门名称" prefix-icon="Search" clearable />
<el-tree
@@ -10,7 +10,7 @@
class="mt-2 dept-tree"
node-key="id"
:data="deptOptions"
:props="{ label: 'label', children: 'children' } as any"
:props="{ label: 'label', children: 'children' }"
:expand-on-click-node="false"
:filter-node-method="filterNode"
highlight-current
@@ -66,10 +66,14 @@
<el-button v-has-permi="['system:user:add']" type="primary" plain icon="Plus" @click="handleAdd()">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button v-has-permi="['system:user:edit']" :disabled="single" icon="Edit" @click="handleUpdate()"> 修改 </el-button>
<el-button v-has-permi="['system:user:edit']" :disabled="single || isSelectedStudentUser" icon="Edit" @click="handleUpdate()">
修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button v-has-permi="['system:user:remove']" :disabled="multiple" icon="Delete" @click="handleDelete()"> 删除 </el-button>
<el-button v-has-permi="['system:user:remove']" :disabled="multiple || hasSelectedStudentUser" icon="Delete" @click="handleDelete()">
删除
</el-button>
</el-col>
<el-col :span="1.5">
<el-dropdown class="mt-[1px]">
@@ -100,7 +104,13 @@
<el-table-column v-if="columns[4].visible" key="phonenumber" label="手机号码" align="center" prop="phonenumber" width="120" />
<el-table-column v-if="columns[5].visible" key="status" label="状态" align="center">
<template #default="scope">
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
:disabled="scope.row.accountType === '2'"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
@@ -112,10 +122,10 @@
<el-table-column label="操作" fixed="right" width="280" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip v-if="scope.row.userId !== 1" content="修改" placement="top">
<el-tooltip v-if="scope.row.userId !== 1 && scope.row.accountType !== '2'" content="修改" placement="top">
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)"></el-button>
</el-tooltip>
<el-tooltip v-if="scope.row.userId !== 1" content="删除" placement="top">
<el-tooltip v-if="scope.row.userId !== 1 && scope.row.accountType !== '2'" content="删除" placement="top">
<el-button v-hasPermi="['system:user:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)"></el-button>
</el-tooltip>
@@ -126,6 +136,11 @@
<el-tooltip v-if="scope.row.userId !== 1" content="分配角色" placement="top">
<el-button v-hasPermi="['system:user:edit']" link type="primary" icon="CircleCheck" @click="handleAuthRole(scope.row)"></el-button>
</el-tooltip>
<!-- 学生用户显示提示信息 -->
<el-tooltip v-if="scope.row.accountType === '2'" content="学生用户不允许操作" placement="top">
<span class="text-gray-400">学生用户</span>
</el-tooltip>
</template>
</el-table-column>
</el-table>
@@ -155,7 +170,7 @@
<el-tree-select
v-model="form.deptId"
:data="enabledDeptOptions"
:props="{ value: 'id', label: 'label', children: 'children' } as any"
:props="{ value: 'id', label: 'label', children: 'children' }"
value-key="id"
placeholder="请选择归属部门"
check-strictly
@@ -316,6 +331,20 @@ const enabledDeptOptions = ref<DeptTreeVO[]>([]);
const initPassword = ref<string>('');
const postOptions = ref<PostVO[]>([]);
const roleOptions = ref<RoleVO[]>([]);
// 选中的用户相关计算属性
const selectedUsers = ref<UserVO[]>([]);
// 计算属性:是否选中了学生用户
const isSelectedStudentUser = computed(() => {
return selectedUsers.value.length === 1 && selectedUsers.value[0].accountType === '2';
});
// 计算属性:选中的用户中是否包含学生用户
const hasSelectedStudentUser = computed(() => {
return selectedUsers.value.some((user) => user.accountType === '2');
});
/*** 用户导入参数 */
const upload = reactive<ImportOption>({
// 是否显示弹出层(用户导入)
@@ -489,6 +518,19 @@ const resetQuery = () => {
/** 删除按钮操作 */
const handleDelete = async (row?: UserVO) => {
const userIds = row?.userId || ids.value;
// 检查是否是学生用户
if (row && row.accountType === '2') {
proxy?.$modal.msgError('学生用户不允许删除操作');
return;
}
// 检查批量删除时是否包含学生用户
if (!row && hasSelectedStudentUser.value) {
proxy?.$modal.msgError('选中的用户中包含学生用户,不允许删除操作');
return;
}
const [err] = await to(proxy?.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?') as any);
if (!err) {
await api.delUser(userIds);
@@ -499,6 +541,14 @@ const handleDelete = async (row?: UserVO) => {
/** 用户状态修改 */
const handleStatusChange = async (row: UserVO) => {
// 检查是否是学生用户
if (row.accountType === '2') {
// 恢复原状态
row.status = row.status === '0' ? '1' : '0';
proxy?.$modal.msgError('学生用户不允许修改状态');
return;
}
const text = row.status === '0' ? '启用' : '停用';
try {
await proxy?.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?');
@@ -510,12 +560,24 @@ const handleStatusChange = async (row: UserVO) => {
};
/** 跳转角色分配 */
const handleAuthRole = (row: UserVO) => {
// 检查是否是学生用户
// if (row.accountType === '2') {
// proxy?.$modal.msgError('学生用户不允许分配角色操作');
// return;
// }
const userId = row.userId;
router.push('/system/user-auth/role/' + userId);
};
/** 重置密码按钮操作 */
const handleResetPwd = async (row: UserVO) => {
// 检查是否是学生用户
// if (row.accountType === '2') {
// proxy?.$modal.msgError('学生用户不允许重置密码操作');
// return;
// }
const [err, res] = await to(
ElMessageBox.prompt('请输入"' + row.userName + '"的新密码', '提示', {
confirmButtonText: '确定',
@@ -538,6 +600,7 @@ const handleResetPwd = async (row: UserVO) => {
/** 选择条数 */
const handleSelectionChange = (selection: UserVO[]) => {
selectedUsers.value = selection;
ids.value = selection.map((item) => item.userId);
single.value = selection.length != 1;
multiple.value = !selection.length;
@@ -607,6 +670,18 @@ const handleAdd = async () => {
/** 修改按钮操作 */
const handleUpdate = async (row?: UserForm) => {
// 检查是否是学生用户
if (row && (row as UserVO).accountType === '2') {
proxy?.$modal.msgError('学生用户不允许修改操作');
return;
}
// 检查选中的用户是否是学生用户
if (!row && isSelectedStudentUser.value) {
proxy?.$modal.msgError('学生用户不允许修改操作');
return;
}
reset();
const userId = row?.userId || ids.value[0];
const { data } = await api.getUser(userId);
@@ -671,24 +746,30 @@ async function handleDeptChange(value: number | string) {
height: 600px;
overflow-y: auto;
overflow-x: auto;
width: 270px; /* 固定宽度,超出时显示滚动条 */
min-width: 270px;
width: 330px; /* 固定宽度,超出时显示滚动条 */
min-width: 330px;
}
/* 强制覆盖el-tree的默认样式 */
.dept-tree :deep(.el-tree-node) {
white-space: nowrap !important;
width: max-content !important;
min-width: max-content !important;
width: 100% !important;
min-width: 300px !important;
}
.dept-tree :deep(.el-tree-node__content) {
white-space: nowrap !important;
min-width: max-content !important;
width: max-content !important;
width: 100% !important;
min-width: 300px !important;
overflow: visible !important;
text-overflow: unset !important; /* 移除省略号 */
max-width: none !important;
padding-right: 20px !important; /* 增加右侧内边距,确保hover效果完整显示 */
}
/* 树节点hover效果优化 */
.dept-tree :deep(.el-tree-node__content:hover) {
background-color: var(--el-tree-node-hover-bg-color, #f5f7fa) !important;
}
.dept-tree :deep(.el-tree-node__label) {
@@ -698,7 +779,7 @@ async function handleDeptChange(value: number | string) {
max-width: none !important;
overflow: visible !important;
text-overflow: unset !important; /* 移除省略号效果 */
width: max-content !important;
width: auto !important;
}
.dept-tree :deep(.el-tree-node__expand-icon) {
@@ -707,10 +788,10 @@ async function handleDeptChange(value: number | string) {
/* 确保树容器内部元素都不被截断 */
.dept-tree :deep(.el-tree-node__children) {
width: max-content !important;
width: 100% !important;
}
.dept-tree :deep(.el-tree-node > .el-tree-node__children) {
width: max-content !important;
width: 100% !important;
}
</style>