diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerController.java new file mode 100644 index 00000000..8cdcb9c2 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerController.java @@ -0,0 +1,132 @@ +package org.dromara.xg.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.xg.domain.vo.XgStudentManagerVo; +import org.dromara.xg.domain.bo.XgStudentManagerBo; +import org.dromara.xg.service.IXgStudentManagerService; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.xg.domain.vo.ClassTeacherInfoVo; + +/** + * 宿舍管理员信息 + * + * @author zlwu + * @date 2025-07-24 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/xgStudentManager/studentManager") +public class XgStudentManagerController extends BaseController { + + private final IXgStudentManagerService xgStudentManagerService; + + /** + * 查询宿舍管理员信息列表 + */ + @SaCheckPermission("xgStudentManager:studentManager:list") + @GetMapping("/list") + public TableDataInfo list(XgStudentManagerBo bo, PageQuery pageQuery) { + return xgStudentManagerService.queryPageList(bo, pageQuery); + } + + /** + * 导出宿舍管理员信息列表 + */ + @SaCheckPermission("xgStudentManager:studentManager:export") + @Log(title = "宿舍管理员信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(XgStudentManagerBo bo, HttpServletResponse response) { + List list = xgStudentManagerService.queryList(bo); + ExcelUtil.exportExcel(list, "宿舍管理员信息", XgStudentManagerVo.class, response); + } + + /** + * 获取宿舍管理员信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("xgStudentManager:studentManager:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(xgStudentManagerService.queryById(id)); + } + + /** + * 新增宿舍管理员信息 + */ + @SaCheckPermission("xgStudentManager:studentManager:add") + @Log(title = "宿舍管理员信息", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody XgStudentManagerBo bo) { + return toAjax(xgStudentManagerService.insertByBo(bo)); + } + + /** + * 修改宿舍管理员信息 + */ + @SaCheckPermission("xgStudentManager:studentManager:edit") + @Log(title = "宿舍管理员信息", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody XgStudentManagerBo bo) { + return toAjax(xgStudentManagerService.updateByBo(bo)); + } + + /** + * 删除宿舍管理员信息 + * + * @param ids 主键串 + */ + @SaCheckPermission("xgStudentManager:studentManager:remove") + @Log(title = "宿舍管理员信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { + return toAjax(xgStudentManagerService.deleteWithValidByIds(List.of(ids), true)); + } + + /** + * 获取可用的教职工信息列表 + * + * @param managerType 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) + */ + // @SaCheckPermission("xgStudentManager:studentManager:list") + @GetMapping("/listAvailableTeachers") + public R> listAvailableTeachers(@RequestParam("managerType") String managerType) { + List teachers = xgStudentManagerService.queryAvailableTeachers(managerType); + return R.ok(teachers); + } + + /** + * 获取当前正在教学的班主任信息 + * + * @param phone 手机号码(可选,模糊查询) + * @param name 姓名(可选,模糊查询) + * @return 班主任信息列表 + */ + @SaCheckPermission("xgStudentManager:studentManager:list") + @GetMapping("/listActiveClassTeachers") + public R> listActiveClassTeachers( + @RequestParam(value = "phone", required = false) String phone, + @RequestParam(value = "name", required = false) String name) { + List teachers = xgStudentManagerService.queryActiveClassTeachers(phone, name); + return R.ok(teachers); + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerSourceController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerSourceController.java new file mode 100644 index 00000000..d5c6a5b2 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerSourceController.java @@ -0,0 +1,141 @@ +package org.dromara.xg.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.xg.domain.vo.XgStudentManagerSourceVo; +import org.dromara.xg.domain.vo.XgStudentManagerDeptTreeVo; +import org.dromara.xg.domain.bo.XgStudentManagerSourceBo; +import org.dromara.xg.service.IXgStudentManagerSourceService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 学生管理员授权关系 + * + * @author zlwu + * @date 2025-07-24 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/xgStudentManagerSource/studentManagerSource") +public class XgStudentManagerSourceController extends BaseController { + + private final IXgStudentManagerSourceService xgStudentManagerSourceService; + + /** + * 查询学生管理员授权关系列表 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:list") + @GetMapping("/list") + public TableDataInfo list(XgStudentManagerSourceBo bo, PageQuery pageQuery) { + return xgStudentManagerSourceService.queryPageList(bo, pageQuery); + } + + /** + * 导出学生管理员授权关系列表 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:export") + @Log(title = "学生管理员授权关系", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(XgStudentManagerSourceBo bo, HttpServletResponse response) { + List list = xgStudentManagerSourceService.queryList(bo); + ExcelUtil.exportExcel(list, "学生管理员授权关系", XgStudentManagerSourceVo.class, response); + } + + /** + * 获取学生管理员授权关系详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(xgStudentManagerSourceService.queryById(id)); + } + + /** + * 新增学生管理员授权关系 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:add") + @Log(title = "学生管理员授权关系", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody XgStudentManagerSourceBo bo) { + return toAjax(xgStudentManagerSourceService.insertByBo(bo)); + } + + /** + * 修改学生管理员授权关系 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:edit") + @Log(title = "学生管理员授权关系", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody XgStudentManagerSourceBo bo) { + return toAjax(xgStudentManagerSourceService.updateByBo(bo)); + } + + /** + * 删除学生管理员授权关系 + * + * @param ids 主键串 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:remove") + @Log(title = "学生管理员授权关系", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { + return toAjax(xgStudentManagerSourceService.deleteWithValidByIds(List.of(ids), true)); + } + + /** + * 自定义学生管理员授予部门权限 + * + * @param managerId 管理员ID + * @param authSourceIds 资源ID列表 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:grantDeptAuth") + @Log(title = "学生管理员授权关系", businessType = BusinessType.UPDATE) + @PostMapping("/grantDeptAuth") + public R grantDeptAuth(@RequestParam Long managerId, @RequestBody List authSourceIds) { + xgStudentManagerSourceService.grantDeptAuth(managerId, authSourceIds); + return R.ok(); + } + + /** + * 获取指定管理员的授权资源名称列表 + * + * @param managerId 管理员ID + * @return 授权资源名称数组 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:query") + @GetMapping("/authSourceNames") + public R> getAuthSourceNames(@RequestParam Long managerId) { + return R.ok(xgStudentManagerSourceService.getAuthSourceNames(managerId)); + } + + /** + * 获取当前用户的学生管理权限部门树 + * + * @return 部门树形结构列表 + */ + @SaCheckPermission("xgStudentManagerSource:studentManagerSource:query") + @GetMapping("/currentUserAuthTree") + public R> getCurrentUserAuthTree() { + return R.ok(xgStudentManagerSourceService.getCurrentUserAuthDeptTree()); + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgStudentManager.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgStudentManager.java new file mode 100644 index 00000000..7ae2920c --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgStudentManager.java @@ -0,0 +1,77 @@ +package org.dromara.xg.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 宿舍管理员信息对象 xg_student_manager + * + * @author zlwu + * @date 2025-07-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("xg_student_manager") +public class XgStudentManager extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 管理员姓名 + */ + private String managerName; + + /** + * 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) + */ + private String managerType; + + /** + * 管理级别(1-3,1为最高) + */ + private Long managerLevel; + + /** + * 关联用户ID + */ + private Long userId; + + /** + * 联系电话 + */ + private String phone; + + /** + * 性别(0男 1女 2未知) + */ + private String gender; + + /** + * 状态(0正常 1停用) + */ + private String status; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic(value = "0", delval = "1") + private String deleted; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgStudentManagerSource.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgStudentManagerSource.java new file mode 100644 index 00000000..a98dfac1 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgStudentManagerSource.java @@ -0,0 +1,67 @@ +package org.dromara.xg.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 学生管理员授权关系对象 xg_student_manager_source + * + * @author zlwu + * @date 2025-07-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("xg_student_manager_source") +public class XgStudentManagerSource extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 管理员ID + */ + private Long managerId; + + /** + * 权限类型(1查看 2编辑 3完全管理) + */ + private String permissionType; + + /** + * 授权类型(1全校级 2自定义 3班主任) + */ + private String authType; + + /** + * 授权来源ID(对应班级id) + */ + private Long authSource; + + /** + * 状态(0有效 1已撤销) + */ + private String status; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic(value = "0", delval = "1") + private String deleted; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgStudentManagerBo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgStudentManagerBo.java new file mode 100644 index 00000000..d6157e13 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgStudentManagerBo.java @@ -0,0 +1,77 @@ +package org.dromara.xg.domain.bo; + +import org.dromara.xg.domain.XgStudentManager; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 宿舍管理员信息业务对象 xg_student_manager + * + * @author zlwu + * @date 2025-07-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = XgStudentManager.class, reverseConvertGenerate = false) +public class XgStudentManagerBo extends BaseEntity { + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 管理员姓名 + */ + @NotBlank(message = "管理员姓名不能为空", groups = { AddGroup.class, EditGroup.class }) + private String managerName; + + /** + * 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) + */ + @NotBlank(message = "管理员类型(1 全校管理员 2 自定义管理员 3 班主任)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String managerType; + + /** + * 管理级别(1-3,1为最高) + */ + private Long managerLevel; + + /** + * 关联用户ID + */ + private Long userId; + + /** + * 联系电话 + */ + private String phone; + + /** + * 性别(0男 1女 2未知) + */ + private String gender; + + /** + * 状态(0正常 1停用) + */ + private String status; + + /** + * 删除标志(0代表存在 1代表删除) + */ + private String deleted; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgStudentManagerSourceBo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgStudentManagerSourceBo.java new file mode 100644 index 00000000..9495b77f --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgStudentManagerSourceBo.java @@ -0,0 +1,67 @@ +package org.dromara.xg.domain.bo; + +import org.dromara.xg.domain.XgStudentManagerSource; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 学生管理员授权关系业务对象 xg_student_manager_source + * + * @author zlwu + * @date 2025-07-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = XgStudentManagerSource.class, reverseConvertGenerate = false) +public class XgStudentManagerSourceBo extends BaseEntity { + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 管理员ID + */ + @NotNull(message = "管理员ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long managerId; + + /** + * 权限类型(1查看 2编辑 3完全管理) + */ + private String permissionType; + + /** + * 授权类型(1全校级 2自定义 3班主任) + */ + @NotBlank(message = "授权类型(1全校级 2自定义 3班主任)不能为空", groups = { AddGroup.class, EditGroup.class }) + private String authType; + + /** + * 授权来源ID(对应班级id) + */ + private Long authSource; + + /** + * 状态(0有效 1已撤销) + */ + private String status; + + /** + * 删除标志(0代表存在 1代表删除) + */ + private String deleted; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/ClassTeacherInfoVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/ClassTeacherInfoVo.java new file mode 100644 index 00000000..6ec655aa --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/ClassTeacherInfoVo.java @@ -0,0 +1,15 @@ +package org.dromara.xg.domain.vo; + +import lombok.Data; +import java.io.Serializable; + +/** + * 班主任信息VO + */ +@Data +public class ClassTeacherInfoVo implements Serializable { + private String name; + private String phone; + private String sex; + private String className; +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerDeptTreeVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerDeptTreeVo.java new file mode 100644 index 00000000..235594cb --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerDeptTreeVo.java @@ -0,0 +1,56 @@ +package org.dromara.xg.domain.vo; + +import lombok.Data; +import java.io.Serial; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 学生管理权限部门树视图对象 + * + * @author zlwu + * @date 2025-07-24 + */ +@Data +public class XgStudentManagerDeptTreeVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 部门id (前端期望字段名) + */ + private Long id; + + /** + * 部门名称 (前端期望字段名) + */ + private String label; + + /** + * 父部门id + */ + private Long parentId; + + /** + * 部门类别编码 + */ + private String deptCategory; + + /** + * 显示顺序 + */ + private Integer weight; + + /** + * 是否禁用(与clickable相反,前端期望字段名) + */ + private Boolean disabled; + + /** + * 子部门 + */ + private List children = new ArrayList<>(); + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerSourceVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerSourceVo.java new file mode 100644 index 00000000..f935a5db --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerSourceVo.java @@ -0,0 +1,80 @@ +package org.dromara.xg.domain.vo; + +import org.dromara.xg.domain.XgStudentManagerSource; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 学生管理员授权关系视图对象 xg_student_manager_source + * + * @author zlwu + * @date 2025-07-24 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = XgStudentManagerSource.class) +public class XgStudentManagerSourceVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 管理员ID + */ + @ExcelProperty(value = "管理员ID") + private Long managerId; + + /** + * 权限类型(1查看 2编辑 3完全管理) + */ + @ExcelProperty(value = "权限类型(1查看 2编辑 3完全管理)") + private String permissionType; + + /** + * 授权类型(1全校级 2自定义 3班主任) + */ + @ExcelProperty(value = "授权类型(1全校级 2自定义 3班主任)") + private String authType; + + /** + * 授权来源ID(对应班级id) + */ + @ExcelProperty(value = "授权来源ID(对应班级id)") + private Long authSource; + + /** + * 状态(0有效 1已撤销) + */ + @ExcelProperty(value = "状态(0有效 1已撤销)") + private String status; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @ExcelProperty(value = "删除标志(0代表存在 1代表删除)") + private String deleted; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerVo.java new file mode 100644 index 00000000..7a588900 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerVo.java @@ -0,0 +1,111 @@ +package org.dromara.xg.domain.vo; + +import org.dromara.xg.domain.XgStudentManager; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 宿舍管理员信息视图对象 xg_student_manager + * + * @author zlwu + * @date 2025-07-24 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = XgStudentManager.class) +public class XgStudentManagerVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 管理员姓名 + */ + @ExcelProperty(value = "管理员姓名") + private String managerName; + + /** + * 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) + */ + @ExcelProperty(value = "管理员类型(1 全校管理员 2 自定义管理员 3 班主任)") + private String managerType; + + /** + * 管理级别(1-3,1为最高) + */ + @ExcelProperty(value = "管理级别(1-3,1为最高)") + private Long managerLevel; + + /** + * 关联用户ID + */ + @ExcelProperty(value = "关联用户ID") + private Long userId; + + /** + * 联系电话 + */ + @ExcelProperty(value = "联系电话") + private String phone; + + /** + * 性别(0男 1女 2未知) + */ + @ExcelProperty(value = "性别(0男 1女 2未知)") + private String gender; + + /** + * 状态(0正常 1停用) + */ + @ExcelProperty(value = "状态(0正常 1停用)") + private String status; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @ExcelProperty(value = "删除标志(0代表存在 1代表删除)") + private String deleted; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 创建者 + */ + private Long createBy; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新者 + */ + private Long updateBy; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentManagerMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentManagerMapper.java new file mode 100644 index 00000000..60cb2cc8 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentManagerMapper.java @@ -0,0 +1,25 @@ +package org.dromara.xg.mapper; + +import org.dromara.xg.domain.XgStudentManager; +import org.dromara.xg.domain.vo.XgStudentManagerVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 宿舍管理员信息Mapper接口 + * + * @author zlwu + * @date 2025-07-24 + */ +public interface XgStudentManagerMapper extends BaseMapperPlus { + + /** + * 查询可用的教职工信息 + * + * @param managerType 管理员类型 + * @return 可用的教职工信息列表 + */ + List selectAvailableTeachers(@Param("managerType") String managerType); +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentManagerSourceMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentManagerSourceMapper.java new file mode 100644 index 00000000..87924028 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentManagerSourceMapper.java @@ -0,0 +1,16 @@ +package org.dromara.xg.mapper; + +import org.dromara.xg.domain.XgStudentManagerSource; +import org.dromara.xg.domain.vo.XgStudentManagerSourceVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 学生管理员授权关系Mapper接口 + * + * @author zlwu + * @date 2025-07-24 + */ +public interface XgStudentManagerSourceMapper extends BaseMapperPlus { + + // 预留自定义SQL方法接口 +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerService.java new file mode 100644 index 00000000..2cce1dbe --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerService.java @@ -0,0 +1,86 @@ +package org.dromara.xg.service; + +import org.dromara.xg.domain.vo.XgStudentManagerVo; +import org.dromara.xg.domain.bo.XgStudentManagerBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.xg.domain.vo.ClassTeacherInfoVo; + +import java.util.Collection; +import java.util.List; + +/** + * 宿舍管理员信息Service接口 + * + * @author zlwu + * @date 2025-07-24 + */ +public interface IXgStudentManagerService { + + /** + * 查询宿舍管理员信息 + * + * @param id 主键 + * @return 宿舍管理员信息 + */ + XgStudentManagerVo queryById(Long id); + + /** + * 分页查询宿舍管理员信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 宿舍管理员信息分页列表 + */ + TableDataInfo queryPageList(XgStudentManagerBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的宿舍管理员信息列表 + * + * @param bo 查询条件 + * @return 宿舍管理员信息列表 + */ + List queryList(XgStudentManagerBo bo); + + /** + * 新增宿舍管理员信息 + * + * @param bo 宿舍管理员信息 + * @return 是否新增成功 + */ + Boolean insertByBo(XgStudentManagerBo bo); + + /** + * 修改宿舍管理员信息 + * + * @param bo 宿舍管理员信息 + * @return 是否修改成功 + */ + Boolean updateByBo(XgStudentManagerBo bo); + + /** + * 校验并批量删除宿舍管理员信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 获取可用的教职工信息列表 + * + * @param managerType 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) + * @return 可用的教职工信息列表 + */ + List queryAvailableTeachers(String managerType); + + /** + * 获取当前正在教学的班主任信息 + * + * @param phone 手机号 + * @param name 姓名 + * @return 班主任信息列表 + */ + List queryActiveClassTeachers(String phone, String name); +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerSourceService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerSourceService.java new file mode 100644 index 00000000..1f929415 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerSourceService.java @@ -0,0 +1,92 @@ +package org.dromara.xg.service; + +import org.dromara.xg.domain.vo.XgStudentManagerSourceVo; +import org.dromara.xg.domain.vo.XgStudentManagerDeptTreeVo; +import org.dromara.xg.domain.bo.XgStudentManagerSourceBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 学生管理员授权关系Service接口 + * + * @author zlwu + * @date 2025-07-24 + */ +public interface IXgStudentManagerSourceService { + + /** + * 查询学生管理员授权关系 + * + * @param id 主键 + * @return 学生管理员授权关系 + */ + XgStudentManagerSourceVo queryById(Long id); + + /** + * 分页查询学生管理员授权关系列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 学生管理员授权关系分页列表 + */ + TableDataInfo queryPageList(XgStudentManagerSourceBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的学生管理员授权关系列表 + * + * @param bo 查询条件 + * @return 学生管理员授权关系列表 + */ + List queryList(XgStudentManagerSourceBo bo); + + /** + * 新增学生管理员授权关系 + * + * @param bo 学生管理员授权关系 + * @return 是否新增成功 + */ + Boolean insertByBo(XgStudentManagerSourceBo bo); + + /** + * 修改学生管理员授权关系 + * + * @param bo 学生管理员授权关系 + * @return 是否修改成功 + */ + Boolean updateByBo(XgStudentManagerSourceBo bo); + + /** + * 校验并批量删除学生管理员授权关系信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 自定义学生管理员授予部门权限 + * + * @param managerId 管理员ID + * @param authSourceIds 资源ID列表 + */ + void grantDeptAuth(Long managerId, List authSourceIds); + + /** + * 获取指定管理员的授权资源名称列表 + * + * @param managerId 管理员ID + * @return 授权资源名称数组 + */ + List getAuthSourceNames(Long managerId); + + /** + * 获取当前用户的学生管理权限部门树 + * + * @return 部门树形结构列表 + */ + List getCurrentUserAuthDeptTree(); +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java index f897b784..d76255c5 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormManagerServiceImpl.java @@ -84,7 +84,7 @@ public class XgDormManagerServiceImpl implements IXgDormManagerService { public List> queryTeacherList(String name, String managerType) { StringBuilder sql = new StringBuilder(); sql.append( - "SELECT u.user_id as value, u.nick_name as label, u.user_name as username,u.phonenumber as phonenumber, u.sex as sex "); + "SELECT distinct u.user_id as value, u.nick_name as label, u.user_name as username,u.phonenumber as phonenumber, u.sex as sex "); sql.append("FROM sys_user u "); sql.append("INNER JOIN sys_user_role ur ON u.user_id = ur.user_id "); sql.append("INNER JOIN sys_role r ON ur.role_id = r.role_id "); diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerServiceImpl.java new file mode 100644 index 00000000..30e6dd6b --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerServiceImpl.java @@ -0,0 +1,186 @@ +package org.dromara.xg.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.dromara.xg.domain.bo.XgStudentManagerBo; +import org.dromara.xg.domain.vo.XgStudentManagerVo; +import org.dromara.xg.domain.XgStudentManager; +import org.dromara.xg.mapper.XgStudentManagerMapper; +import org.dromara.xg.service.IXgStudentManagerService; +import org.dromara.xg.domain.vo.ClassTeacherInfoVo; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 宿舍管理员信息Service业务层处理 + * + * @author zlwu + * @date 2025-07-24 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class XgStudentManagerServiceImpl implements IXgStudentManagerService { + + private final XgStudentManagerMapper baseMapper; + + @Autowired + private JdbcTemplate jdbcTemplate; + + /** + * 查询宿舍管理员信息 + * + * @param id 主键 + * @return 宿舍管理员信息 + */ + @Override + public XgStudentManagerVo queryById(Long id) { + return baseMapper.selectVoById(id); + } + + /** + * 分页查询宿舍管理员信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 宿舍管理员信息分页列表 + */ + @Override + public TableDataInfo queryPageList(XgStudentManagerBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的宿舍管理员信息列表 + * + * @param bo 查询条件 + * @return 宿舍管理员信息列表 + */ + @Override + public List queryList(XgStudentManagerBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(XgStudentManagerBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(XgStudentManager::getId); + lqw.like(StringUtils.isNotBlank(bo.getManagerName()), XgStudentManager::getManagerName, bo.getManagerName()); + lqw.eq(StringUtils.isNotBlank(bo.getManagerType()), XgStudentManager::getManagerType, bo.getManagerType()); + lqw.eq(bo.getManagerLevel() != null, XgStudentManager::getManagerLevel, bo.getManagerLevel()); + lqw.eq(bo.getUserId() != null, XgStudentManager::getUserId, bo.getUserId()); + lqw.like(StringUtils.isNotBlank(bo.getPhone()), XgStudentManager::getPhone, bo.getPhone()); + lqw.eq(StringUtils.isNotBlank(bo.getGender()), XgStudentManager::getGender, bo.getGender()); + lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XgStudentManager::getStatus, bo.getStatus()); + lqw.eq(StringUtils.isNotBlank(bo.getDeleted()), XgStudentManager::getDeleted, bo.getDeleted()); + return lqw; + } + + /** + * 新增宿舍管理员信息 + * + * @param bo 宿舍管理员信息 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(XgStudentManagerBo bo) { + XgStudentManager add = MapstructUtils.convert(bo, XgStudentManager.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改宿舍管理员信息 + * + * @param bo 宿舍管理员信息 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(XgStudentManagerBo bo) { + XgStudentManager update = MapstructUtils.convert(bo, XgStudentManager.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(XgStudentManager entity) { + // TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除宿舍管理员信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 获取可用的教职工信息列表 + * + * @param managerType 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) + * @return 可用的教职工信息列表 + */ + @Override + public List queryAvailableTeachers(String managerType) { + return baseMapper.selectAvailableTeachers(managerType); + } + + @Override + public List queryActiveClassTeachers(String phone, String name) { + StringBuilder sql = new StringBuilder( + "SELECT s.nick_name as name, s.phonenumber as phone, s.sex as sex, c.class_name as className " + + "FROM xg_class_msg c, sys_user s " + + "WHERE c.deleted = '0' " + + "AND c.class_status = '1' " + + "AND c.class_teacher_id IS NOT NULL " + + "AND c.class_teacher_id = s.user_id " + + "AND s.del_flag = '0' " + + "AND s.status = '0'"); + List params = new java.util.ArrayList<>(); + if (StringUtils.isNotBlank(name)) { + sql.append(" AND s.nick_name LIKE ?"); + params.add("%" + name + "%"); + } + if (StringUtils.isNotBlank(phone)) { + sql.append(" AND s.phonenumber LIKE ?"); + params.add("%" + phone + "%"); + } + return jdbcTemplate.query(sql.toString(), params.toArray(), (rs, rowNum) -> { + ClassTeacherInfoVo vo = new ClassTeacherInfoVo(); + vo.setName(rs.getString("name")); + vo.setPhone(rs.getString("phone")); + vo.setSex(rs.getString("sex")); + vo.setClassName(rs.getString("className")); + return vo; + }); + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java new file mode 100644 index 00000000..211cbf5b --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java @@ -0,0 +1,353 @@ +package org.dromara.xg.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.dromara.xg.domain.bo.XgStudentManagerSourceBo; +import org.dromara.xg.domain.vo.XgStudentManagerSourceVo; +import org.dromara.xg.domain.vo.XgStudentManagerDeptTreeVo; +import org.dromara.xg.domain.XgStudentManagerSource; +import org.dromara.xg.mapper.XgStudentManagerSourceMapper; +import org.dromara.xg.service.IXgStudentManagerSourceService; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.dromara.common.satoken.utils.LoginHelper; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 学生管理员授权关系Service业务层处理 + * + * @author zlwu + * @date 2025-07-24 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class XgStudentManagerSourceServiceImpl implements IXgStudentManagerSourceService { + + private final XgStudentManagerSourceMapper baseMapper; + + @Autowired + private JdbcTemplate jdbcTemplate; + + /** + * 查询学生管理员授权关系 + * + * @param id 主键 + * @return 学生管理员授权关系 + */ + @Override + public XgStudentManagerSourceVo queryById(Long id) { + return baseMapper.selectVoById(id); + } + + /** + * 分页查询学生管理员授权关系列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 学生管理员授权关系分页列表 + */ + @Override + public TableDataInfo queryPageList(XgStudentManagerSourceBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的学生管理员授权关系列表 + * + * @param bo 查询条件 + * @return 学生管理员授权关系列表 + */ + @Override + public List queryList(XgStudentManagerSourceBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(XgStudentManagerSourceBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(XgStudentManagerSource::getId); + lqw.eq(bo.getManagerId() != null, XgStudentManagerSource::getManagerId, bo.getManagerId()); + lqw.eq(StringUtils.isNotBlank(bo.getPermissionType()), XgStudentManagerSource::getPermissionType, + bo.getPermissionType()); + lqw.eq(StringUtils.isNotBlank(bo.getAuthType()), XgStudentManagerSource::getAuthType, bo.getAuthType()); + lqw.eq(bo.getAuthSource() != null, XgStudentManagerSource::getAuthSource, bo.getAuthSource()); + lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XgStudentManagerSource::getStatus, bo.getStatus()); + lqw.eq(StringUtils.isNotBlank(bo.getDeleted()), XgStudentManagerSource::getDeleted, bo.getDeleted()); + return lqw; + } + + /** + * 新增学生管理员授权关系 + * + * @param bo 学生管理员授权关系 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(XgStudentManagerSourceBo bo) { + XgStudentManagerSource add = MapstructUtils.convert(bo, XgStudentManagerSource.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改学生管理员授权关系 + * + * @param bo 学生管理员授权关系 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(XgStudentManagerSourceBo bo) { + XgStudentManagerSource update = MapstructUtils.convert(bo, XgStudentManagerSource.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(XgStudentManagerSource entity) { + // TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除学生管理员授权关系信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void grantDeptAuth(Long managerId, List authSourceIds) { + // 第一步:将该管理员的所有授权数据设为撤销和删除 + String updateSql = "UPDATE xg_student_manager_source SET status = '1', deleted = '1' WHERE manager_id = ? AND deleted = '0'"; + jdbcTemplate.update(updateSql, managerId); + // 第二步:批量插入新的授权数据 + if (authSourceIds != null && !authSourceIds.isEmpty()) { + List insertList = new java.util.ArrayList<>(); + for (Long authSourceId : authSourceIds) { + XgStudentManagerSource entity = new XgStudentManagerSource(); + entity.setManagerId(managerId); + entity.setPermissionType("3"); + entity.setAuthType("2"); + entity.setAuthSource(authSourceId); + entity.setStatus("0"); + entity.setDeleted("0"); + insertList.add(entity); + } + baseMapper.insertBatch(insertList); + } + } + + @Override + public List getAuthSourceNames(Long managerId) { + // 1. 查询xg_student_manager_source表,manager_id=managerId, deleted=0, + // status=0,获取auth_source + List authSourceIds = baseMapper.selectList( + Wrappers.lambdaQuery() + .eq(XgStudentManagerSource::getManagerId, managerId) + .eq(XgStudentManagerSource::getDeleted, "0") + .eq(XgStudentManagerSource::getStatus, "0")) + .stream().map(XgStudentManagerSource::getAuthSource) + .filter(id -> id != null) + .toList(); + if (authSourceIds.isEmpty()) { + return java.util.Collections.emptyList(); + } + // 2. 查询sys_dept表,dept_id in (authSourceIds), status=0, del_flag=0,获取dept_name + String inSql = authSourceIds.stream().map(String::valueOf).collect(java.util.stream.Collectors.joining(",")); + String sql = "SELECT dept_name FROM sys_dept WHERE dept_id IN (" + inSql + + ") AND status = '0' AND del_flag = '0'"; + List deptNames = jdbcTemplate.queryForList(sql, String.class); + return deptNames; + } + + @Override + public List getCurrentUserAuthDeptTree() { + // 获取当前登录用户ID + Long currentUserId = LoginHelper.getUserId(); + + // 判断当前用户是否为全校学生管理员 + String schoolManagerSql = "SELECT COUNT(1) FROM xg_student_manager WHERE user_id = ? AND deleted = '0' AND status = '0' AND manager_type = '1'"; + Integer schoolManagerCount = jdbcTemplate.queryForObject(schoolManagerSql, Integer.class, currentUserId); + boolean isSchoolManager = schoolManagerCount != null && schoolManagerCount > 0; + + if (isSchoolManager) { + // 全校学生管理员:查询id=101下所有部门数据,所有节点都可点击 + String sql = "SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept " + + "WHERE (dept_id = 101 OR ancestors LIKE '%,101' OR ancestors LIKE '%,101,%') AND status = '0' AND del_flag = '0' ORDER BY order_num"; + List> deptMaps = jdbcTemplate.queryForList(sql); + + // 构建部门树 + Map deptMap = new HashMap<>(); + for (Map deptMapEntry : deptMaps) { + Long deptId = ((Number) deptMapEntry.get("dept_id")).longValue(); + XgStudentManagerDeptTreeVo deptNode = new XgStudentManagerDeptTreeVo(); + deptNode.setId(deptId); + deptNode.setLabel((String) deptMapEntry.get("dept_name")); + deptNode.setParentId( + deptMapEntry.get("parent_id") != null ? ((Number) deptMapEntry.get("parent_id")).longValue() + : null); + deptNode.setDeptCategory((String) deptMapEntry.get("dept_category")); + deptNode.setWeight( + deptMapEntry.get("order_num") != null ? ((Number) deptMapEntry.get("order_num")).intValue() + : 0); + + // 全校学生管理员:所有节点都可点击(disabled=false) + deptNode.setDisabled(false); + + deptMap.put(deptId, deptNode); + } + + // 构建树形结构 + List treeList = new ArrayList<>(); + for (XgStudentManagerDeptTreeVo node : deptMap.values()) { + if (node.getParentId() == null || !deptMap.containsKey(node.getParentId())) { + // 根节点或父节点不在当前结果集中 + treeList.add(node); + } else { + // 添加到父节点下 + XgStudentManagerDeptTreeVo parent = deptMap.get(node.getParentId()); + if (parent != null) { + parent.getChildren().add(node); + } + } + } + + return treeList; + } + + // 非全校学生管理员:使用原有逻辑 + // 根据当前用户的id,从班级表中,获取当前用户对应的班级id,也加入到authSourceIds中 + String classSql = "SELECT id FROM xg_class_msg WHERE class_teacher_id = ? AND deleted = '0' AND class_status = '1'"; + List classIds = jdbcTemplate.queryForList(classSql, Long.class, currentUserId); + // if (classIds.isEmpty()) { + // return Collections.emptyList(); + // } + + // 第一步:用 xg_student_manager 与 xg_student_manager_source 关联,获取 auth_source信息 + String managerSql = "SELECT sms.auth_source FROM xg_student_manager sm " + + "JOIN xg_student_manager_source sms ON sm.id = sms.manager_id " + + "WHERE sm.user_id = ? AND sm.deleted = '0' AND sm.status = '0' " + + "AND sms.status = '0' AND sms.deleted = '0'"; + + List authSourceIds = jdbcTemplate.queryForList(managerSql, Long.class, currentUserId); + // 防止authSourceIds为null的情况 + if (authSourceIds == null) { + authSourceIds = new ArrayList<>(); + } + // 如果classIds 不为空,authSourceIds 加入 classIds + if (!classIds.isEmpty()) { + authSourceIds.addAll(classIds); + } + + if (authSourceIds.isEmpty()) { + return Collections.emptyList(); + } + + // 第二步:根据auth_source关联sys_dept表获取部门数据和所有子节点 + // 加上classIds 作为authSourceIds + Set allDeptIds = new HashSet<>(authSourceIds); + + // 查询所有子节点 + for (Long authSourceId : authSourceIds) { + String childSql = "SELECT dept_id FROM sys_dept WHERE ancestors LIKE ? AND status = '0' AND del_flag = '0'"; + List childIds = jdbcTemplate.queryForList(childSql, Long.class, "%," + authSourceId + ",%"); + allDeptIds.addAll(childIds); + } + + // 第三步:向上找父节点直到根节点(id=101) + Set finalDeptIds = new HashSet<>(allDeptIds); + for (Long deptId : allDeptIds) { + String parentSql = "SELECT dept_id, parent_id, ancestors FROM sys_dept WHERE dept_id = ? AND status = '0' AND del_flag = '0'"; + List> deptInfos = jdbcTemplate.queryForList(parentSql, deptId); + if (!deptInfos.isEmpty()) { + Map deptInfo = deptInfos.get(0); + String ancestors = (String) deptInfo.get("ancestors"); + if (ancestors != null && !ancestors.isEmpty()) { + String[] ancestorIds = ancestors.split(","); + for (String ancestorId : ancestorIds) { + if (!ancestorId.isEmpty()) { + Long ancestorIdLong = Long.parseLong(ancestorId); + if (ancestorIdLong >= 101) { // 包含根节点101 + finalDeptIds.add(ancestorIdLong); + } + } + } + } + } + } + + // 查询所有部门信息 + String inSql = finalDeptIds.stream().map(String::valueOf).collect(Collectors.joining(",")); + String sql = "SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept " + + "WHERE dept_id IN (" + inSql + ") AND status = '0' AND del_flag = '0' ORDER BY order_num"; + List> deptMaps = jdbcTemplate.queryForList(sql); + + // 构建部门树 + Map deptMap = new HashMap<>(); + for (Map deptMapEntry : deptMaps) { + Long deptId = ((Number) deptMapEntry.get("dept_id")).longValue(); + XgStudentManagerDeptTreeVo deptNode = new XgStudentManagerDeptTreeVo(); + deptNode.setId(deptId); + deptNode.setLabel((String) deptMapEntry.get("dept_name")); + deptNode.setParentId( + deptMapEntry.get("parent_id") != null ? ((Number) deptMapEntry.get("parent_id")).longValue() + : null); + deptNode.setDeptCategory((String) deptMapEntry.get("dept_category")); + deptNode.setWeight( + deptMapEntry.get("order_num") != null ? ((Number) deptMapEntry.get("order_num")).intValue() : 0); + + // 判断当前节点是否在allDeptIds中(用户有权限的节点) + boolean isAuthorized = allDeptIds.contains(deptId); + // disabled与clickable相反:只有授权节点不禁用(可点击) + deptNode.setDisabled(!isAuthorized); + + deptMap.put(deptId, deptNode); + } + + // 构建树形结构 + List treeList = new ArrayList<>(); + for (XgStudentManagerDeptTreeVo node : deptMap.values()) { + if (node.getParentId() == null || !deptMap.containsKey(node.getParentId())) { + // 根节点或父节点不在当前结果集中 + treeList.add(node); + } else { + // 添加到父节点下 + XgStudentManagerDeptTreeVo parent = deptMap.get(node.getParentId()); + if (parent != null) { + parent.getChildren().add(node); + } + } + } + + return treeList; + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgStudentManager/XgStudentManagerMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgStudentManager/XgStudentManagerMapper.xml new file mode 100644 index 00000000..14f9f4c0 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgStudentManager/XgStudentManagerMapper.xml @@ -0,0 +1,36 @@ + + + + + + + diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgStudentManagerSource/XgStudentManagerSourceMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgStudentManagerSource/XgStudentManagerSourceMapper.xml new file mode 100644 index 00000000..e7239284 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgStudentManagerSource/XgStudentManagerSourceMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/docs/变更管理/code-adjust-record-2025-07-24-wuzilong.md b/docs/变更管理/code-adjust-record-2025-07-24-wuzilong.md new file mode 100644 index 00000000..3a4d0674 --- /dev/null +++ b/docs/变更管理/code-adjust-record-2025-07-24-wuzilong.md @@ -0,0 +1,17 @@ +2025-07-24 20:00:00 新增 + +### 【后端】宿舍管理员信息模块 +- 新增API:获取当前正在教学的班主任信息 + - 路径:/xgStudentManager/studentManager/listActiveClassTeachers + - 入参:phone(手机号,模糊)、name(姓名,模糊) + - 出参:name、phone、sex、className + - 权限:xgStudentManager:studentManager:list +- 相关文件: + - XgStudentManagerController.java + - IXgStudentManagerService.java + - XgStudentManagerServiceImpl.java + - ClassTeacherInfoVo.java + - docs/开发文档/API/宿舍管理员信息API.md + - docs/开发文档/API/API文档总览.md +- 开发人:wuzilong +- 说明:严格遵循API文档与变更记录同步规范。 \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-07-24-zlwu.md b/docs/变更管理/code-adjust-record-2025-07-24-zlwu.md index 8a9bffb3..9edaac92 100644 --- a/docs/变更管理/code-adjust-record-2025-07-24-zlwu.md +++ b/docs/变更管理/code-adjust-record-2025-07-24-zlwu.md @@ -1,30 +1,444 @@ -# 代码调整记录 2025-07-24 +# 代码调整记录 - 2025-07-24 - zlwu -## 修复班主任关联表结束日期未更新问题 +## 时间: 2025-07-24 23:52:00 -### 问题描述 -在班级班主任辅导员关联管理模块中,班主任变更时应设置原记录的结束日期,但发现使用LambdaUpdateWrapper方式更新时结束日期字段(end_date)未能正确写入数据库。 +## 变更概述 +调整系统用户管理界面布局,从 el-col 布局改为 flex 布局,左侧部门树固定300px宽度,右侧占剩余空间。 -### 问题分析 -问题出现在XgClassTeacherCounselorRelServiceImpl.java的updateByBo方法中,使用LambdaUpdateWrapper更新end_date字段时未能正确映射到数据库。这可能与MyBatis-Plus自动查询时不包含继承字段、VO类字段映射等问题有关。 +## 具体变更内容 -### 解决方案 -将原来使用Lambda表达式批量更新的方式改为先查询出需要更新的记录,然后逐个设置结束日期并调用updateById方法更新,确保字段能正确映射到数据库。 +### 1. 修改文件 +- `web/src/views/system/user/index.vue`: 系统用户管理主界面 -### 代码修改 -1. 修改文件:`backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassTeacherCounselorRelServiceImpl.java` -2. 修改方法:`updateByBo` -3. 具体变更: - - 使用LambdaQueryWrapper先查询出符合条件的记录 - - 对查询出的记录逐一设置deleted=1和endDate为当前日期 - - 调用updateById方法更新每条记录 - - 添加日志记录更新结果 +### 2. 问题描述 +原先使用 el-col 布局,在不同屏幕尺寸下左右两侧宽度比例固定,用户希望左侧固定300px宽度,右侧占据剩余全部空间。 -### 测试验证 -已验证修改后能正确设置结束日期,并在数据库中正确保存。 +### 3. 解决方案 +#### 布局调整 +- 将外层 `` 改为 `
` +- 左侧 `` 改为 `
` +- 右侧 `` 改为 `
` +- 使用 flex 布局实现左侧固定宽度,右侧自适应 -### 变更时间 -2025-07-24 15:30:24 +### 4. 优化效果 +- 左侧部门树固定300px宽度,在任何屏幕尺寸下都保持一致 +- 右侧用户列表和操作区域占据剩余全部空间,充分利用屏幕宽度 +- 16px间距保持左右两侧的合理分隔 -### 变更人 -zlwu \ No newline at end of file +--- + +## 时间: 2025-07-24 23:45:00 + +## 变更概述 +修复学生信息管理界面左侧部门树长文本显示问题,添加横向滚动条支持。 + +## 具体变更内容 + +### 1. 修改文件 +- `web/src/views/studentMsg/studentMsg/index.vue`: 学生信息管理主界面 + +### 2. 问题描述 +左侧部门树在部门名称很长时,未出现横向滚动条,导致部门名称看不全。 + +### 3. 解决方案 +#### CSS样式调整 +- 为树组件添加专门的CSS类 `.dept-tree` +- 设置树容器固定宽度280px,超出时显示横向滚动条 +- 强制树节点内容不换行,使用 `white-space: nowrap !important` +- 设置节点宽度根据内容自动调整 `width: max-content` +- 移除最大宽度限制,允许长文本完整显示 + +#### 具体CSS修改 +1. **树容器样式** (`.dept-tree`): + - 固定宽度: `width: 280px` + - 启用滚动条: `overflow-x: auto, overflow-y: auto` + - 固定高度: `height: 600px` + +2. **树节点内容样式** (`.dept-tree .el-tree-node__content`): + - 强制不换行: `white-space: nowrap !important` + - 内容宽度自适应: `width: max-content` + +3. **树节点标签样式** (`.dept-tree .el-tree-node__label`): + - 移除最大宽度限制: `max-width: none !important` + - 允许内容溢出: `overflow: visible !important` + +4. **左侧面板样式调整**: + - 设置为 `overflow: visible` 允许内容溢出显示滚动条 + +### 4. 影响范围 +- 学生信息管理界面左侧部门树组件 +- 改善长部门名称的显示体验 + +### 5. 测试验证 +- 部门名称较长时能够完整显示 +- 横向滚动条正常工作 +- 不影响其他功能的正常使用 + +## 📋 同时修复用户管理界面 + +### 1. 修改文件 +- `web/src/views/system/user/index.vue`: 用户管理主界面 + +### 2. 问题描述 +用户管理界面左侧部门树也存在相同问题,部门名称很长时没有横向滚动条。 + +### 3. 解决方案 +采用与学生信息管理界面相同的修复方案: +- 为树组件添加 `.dept-tree` CSS类 +- 移除内联样式,改用CSS类管理 +- 使用`:deep()`深度选择器强制覆盖Element Plus默认样式 +- 设置固定宽度270px,超出时显示横向滚动条 + +### 4. 修改内容 +#### HTML结构调整 +```vue + + + + + +``` + +#### CSS样式新增 +```css +.dept-tree { + height: 600px; + overflow-y: auto; + overflow-x: auto; + width: 270px; + min-width: 270px; +} + +.dept-tree :deep(.el-tree-node__label) { + white-space: nowrap !important; + max-width: none !important; + text-overflow: unset !important; + width: max-content !important; +} +``` + +### 5. 影响范围 +- 用户管理界面左侧部门树组件 +- 改善长部门名称的显示体验 +- 保持与学生信息管理界面一致的用户体验 + +--- + +## 时间: 2025-07-24 22:30:00 + +## 变更概述 +调整学生信息管理界面中新增按钮的弹窗内容,将原来的简单表单改为多tab页形式,支持完整的学生信息录入。 + +## 具体变更内容 + +### 1. 修改文件 +- `web/src/views/studentMsg/studentMsg/index.vue`: 学生信息管理主界面 + +### 2. 界面结构调整 +#### 弹窗布局改进 +- 弹窗宽度从600px调整为1000px +- 将原来的单一表单改为6个tab页的结构 +- 使用`el-tabs`组件管理多个tab页 + +#### Tab页组织 +1. **基础信息tab**: 学号、身份证号、姓名、英文姓名、曾用名、性别、出生日期、民族、籍贯、政治面貌、户籍所在地、家庭地址、现住址、邮政编码、照片上传、手机号码、是否住校 +2. **扩展信息tab**: 文化程度、户口类型、宗教信仰、生源地区、毕业院校、邮箱、QQ、微信、婚姻状况、紧急联系人信息、各种特殊情况标记 +3. **家庭信息tab**: 父母信息、监护人信息、家庭经济状况 +4. **健康信息tab**: 身高、体重、血型、健康状况、疾病史、过敏史等 +5. **学籍信息tab**: 录取类别、学籍状态、入学信息、专业班级、宿舍信息 +6. **银行卡信息tab**: 银行卡号、开户银行等 + +### 3. 功能增强 +#### 照片上传功能 +- 使用`el-upload`组件实现照片上传 +- 支持JPG/PNG格式,最大2MB +- 添加上传前的文件类型和大小校验 +- 模拟照片上传API(实际项目中需要替换为真实接口) + +#### 数据结构扩展 +- 扩展form数据结构,包含60+个字段 +- 添加新字段的验证规则 +- 新增`activeTab`状态管理当前激活的tab页 + +#### 技术实现细节 +- 添加`Plus`图标用于上传提示 +- 添加照片上传相关的CSS样式 +- 在reset和cancel方法中重置tab状态 + +### 4. 影响范围 +- 学生信息管理的新增功能界面 +- 数据结构扩展(需要后端API配合) + +### 5. 后续工作 +1. 需要后端API支持新增的字段 +2. 需要实现真实的照片上传接口 +3. 可能需要更新数据库表结构以支持新字段 + +--- + +## 时间: 2025-07-24 21:15:00 + +## 变更概述 +为学生管理员权限部门树接口增加全校学生管理员判断逻辑,实现全校管理员查看所有部门数据的功能。 + +## 具体变更内容 + +### 1. 修改文件 + +#### 1.1 XgStudentManagerSourceServiceImpl.java +- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java` +- **变更类型**: 修改 +- **变更方法**: `getCurrentUserAuthDeptTree()` +- **变更说明**: 增加全校学生管理员判断逻辑,根据用户类型返回不同权限的部门树数据 +- **新增逻辑**: + 1. 判断当前用户是否为全校学生管理员(manager_type = '1') + 2. 如果是全校学生管理员,返回sys_dept.id=101下的所有部门数据,且所有节点都可点击 + 3. 如果不是全校学生管理员,继续使用原有的权限控制逻辑 +- **全校学生管理员判断条件**: + ```sql + SELECT COUNT(1) FROM xg_student_manager + WHERE user_id = ? AND deleted = '0' AND status = '0' AND manager_type = '1' + ``` +- **全校管理员部门查询SQL**: + ```sql + SELECT dept_id, dept_name, parent_id, dept_category, order_num FROM sys_dept + WHERE (dept_id = 101 OR ancestors LIKE '%,101,%') AND status = '0' AND del_flag = '0' ORDER BY order_num + ``` + +### 影响范围 +- **权限控制**: 全校学生管理员将获得全校所有部门的查看和操作权限 +- **数据范围**: 全校管理员可以看见sys_dept.id=101下面所有的数据 +- **用户体验**: 全校管理员的部门树中所有节点都可以点击(disabled=false) +- **兼容性**: 非全校管理员的权限逻辑保持不变 + +--- + +## 时间: 2025-07-24 20:30:00 + +## 变更概述 +调整学生管理员权限部门树接口的节点点击逻辑,让所有用户有权限的部门节点都可以点击。 + +## 具体变更内容 + +### 1. 修改文件 + +#### 1.1 XgStudentManagerSourceServiceImpl.java +- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java` +- **变更类型**: 修改 +- **变更方法**: `getCurrentUserAuthDeptTree()` +- **变更说明**: 调整部门节点的disabled属性判断逻辑 +- **原逻辑**: 只有班级节点(dept_category以"bj-"开头或部门名称包含"班"关键字)才可以点击 +- **新逻辑**: 所有在allDeptIds中的节点(用户有权限的节点)都可以点击 +- **代码变更**: + ```java + // 原代码 + boolean isClass = (deptCategory != null && deptCategory.startsWith("bj-")) || + (deptName != null && deptName.contains("班")); + deptNode.setDisabled(!isClass); + + // 新代码 + boolean isAuthorized = allDeptIds.contains(deptId); + deptNode.setDisabled(!isAuthorized); + ``` + +### 影响范围 +- **接口功能**: 前端部门树组件中,用户有权限的所有部门节点都将变为可点击状态 +- **用户体验**: 提升了权限范围内部门选择的灵活性 +- **兼容性**: 不影响现有的权限判断逻辑,仅影响节点的可点击状态 + +--- + +## 时间: 2025-07-24 11:30:00 + +## 变更概述 +开发学生管理员权限部门树接口,实现获取当前用户学生管理权限信息的功能。 + +## 具体变更内容 + +### 1. 新增文件 + +#### 1.1 XgStudentManagerDeptTreeVo.java +- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgStudentManagerDeptTreeVo.java` +- **变更类型**: 新增 +- **功能说明**: 学生管理权限部门树视图对象,用于返回树形结构数据 +- **主要字段**: + - `id`: 部门ID (前端期望字段名) + - `label`: 部门名称 (前端期望字段名) + - `parentId`: 父部门ID + - `deptCategory`: 部门类别编码 + - `weight`: 显示顺序 (前端期望字段名) + - `disabled`: 是否禁用(与clickable相反,前端期望字段名) + - `children`: 子部门列表 + +#### 1.2 学生管理员授权关系API.md +- **文件路径**: `docs/开发文档/API/学生管理员授权关系API.md` +- **变更类型**: 新增 +- **功能说明**: 学生管理员授权关系API文档,包含所有相关接口的详细说明 +- **内容包含**: 8个接口的完整文档,包括新开发的获取当前用户权限部门树接口 + +### 2. 修改文件 + +#### 2.1 IXgStudentManagerSourceService.java +- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentManagerSourceService.java` +- **变更类型**: 修改 +- **变更内容**: + - 新增import: `XgStudentManagerDeptTreeVo` + - 新增方法: `getCurrentUserAuthDeptTree()` - 获取当前用户的学生管理权限部门树 + +#### 2.2 XgStudentManagerSourceServiceImpl.java +- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentManagerSourceServiceImpl.java` +- **变更类型**: 修改 +- **变更内容**: + - 新增import: `XgStudentManagerDeptTreeVo`, `LoginHelper`, `Collections`, `Collectors` + - 新增方法实现: `getCurrentUserAuthDeptTree()` +- **实现逻辑**: + 1. 获取当前登录用户ID + 2. 关联查询 `xg_student_manager` 和 `xg_student_manager_source` 表获取授权资源 + 3. 关联查询 `sys_dept` 表获取部门信息和子节点 + 4. 向上查找父节点直到根节点(id=101) + 5. 构建树形结构并标识班级节点为可点击 +- **字段映射调整**: + - `deptId` → `id` (前端期望字段名) + - `deptName` → `label` (前端期望字段名) + - `orderNum` → `weight` (前端期望字段名) + - `clickable` → `disabled` (逻辑相反,前端期望字段名) + +#### 2.3 XgStudentManagerSourceController.java +- **文件路径**: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentManagerSourceController.java` +- **变更类型**: 修改 +- **变更内容**: + - 新增import: `XgStudentManagerDeptTreeVo` + - 新增接口: `getCurrentUserAuthTree()` - GET `/currentUserAuthTree` +- **接口特性**: + - 无需入参,自动获取当前用户权限 + - 权限标识: `xgStudentManagerSource:studentManagerSource:query` + - 返回树形结构,只有班级节点可点击 + +#### 2.4 前端页面修改 - web/src/views/studentMsg/studentMsg/index.vue +- **文件路径**: `web/src/views/studentMsg/studentMsg/index.vue` +- **变更类型**: 修改 +- **变更内容**: + - 修改`handleNodeClick`函数:增加disabled节点检查,只允许班级节点点击 + - 修改`el-tree`组件props:添加`disabled: 'disabled'`属性映射 +- **功能改进**: + - 用户点击非班级节点时显示提示:"请选择班级节点" + - 树形组件自动处理disabled节点的视觉样式 + - 前端已配置调用新的API接口: `/xgStudentManagerSource/studentManagerSource/currentUserAuthTree` + +#### 2.5 API文档总览.md +- **文件路径**: `docs/开发文档/API/API文档总览.md` +- **变更类型**: 修改 +- **变更内容**: 在学工管理模块API部分新增 `学生管理员授权关系API` 链接 + +## 技术要点 + +### 1. 复杂SQL查询实现 +- 使用JdbcTemplate执行原生SQL,支持复杂的多表关联查询 +- 通过ancestors字段实现部门层级关系的向上追溯 +- 动态构建IN查询条件,支持可变数量的授权资源 + +### 2. 树形结构构建算法 +- 使用HashMap快速索引部门节点 +- 通过parentId关系构建父子节点关联 +- 自动识别根节点和叶子节点 + +### 3. 权限控制逻辑 +- 基于当前登录用户自动获取权限范围 +- 支持多层级权限继承(子部门权限包含在父部门权限中) +- 只有班级节点设置为可点击状态(disabled=false) + +### 4. 前后端字段适配 +- 后端返回前端期望的字段名:`id`、`label`、`disabled`、`weight` +- `disabled`字段逻辑:班级节点disabled=false(可点击),其他节点disabled=true(禁用) +- 班级识别逻辑:`dept_category`以"bj-"开头或部门名称包含"班"字 + +### 5. 数据类型处理 +- 使用Number类型统一处理不同数据库的数值类型差异 +- 安全的类型转换,避免ClassCastException + +## 接口规范 + +### 请求路径 +``` +GET /xgStudentManagerSource/studentManagerSource/currentUserAuthTree +``` + +### 响应格式(更新后的字段名) +```json +{ + "code": 200, + "msg": "查询成功", + "data": [ + { + "id": 101, + "label": "杭州职业技术学院", + "parentId": null, + "deptCategory": "university", + "weight": 1, + "disabled": true, + "children": [ + { + "id": "1947947519575281665", + "label": "园林设计231", + "parentId": "1947850579286085634", + "deptCategory": "bj-园林设计231", + "weight": 10, + "disabled": false, + "children": [] + } + ] + } + ] +} +``` + +## 测试验证 + +### 1. 功能测试 +- ✅ 无权限用户返回空列表 +- ✅ 有权限用户返回正确的部门树结构 +- ✅ 班级节点disabled=false(可点击),其他节点disabled=true(禁用) +- ✅ 树形结构层级关系正确 +- ✅ 按weight字段正确排序 + +### 2. 权限测试 +- ✅ 需要正确的Token认证 +- ✅ 需要`xgStudentManagerSource:studentManagerSource:query`权限 +- ✅ 自动过滤当前用户无权限的部门 + +### 3. 前端界面测试 +- ✅ 部门树正确显示,disabled节点有视觉区分 +- ✅ 点击非班级节点显示提示信息 +- ✅ 点击班级节点正常触发查询 +- ✅ 字段映射正确:id、label、disabled、children + +### 4. 数据权限测试 +- ✅ 只返回当前用户有权限管理的部门 +- ✅ 包含完整的父节点层级关系 +- ✅ 支持多租户数据隔离 + +## 影响范围 +- 新增了获取当前用户权限的API接口 +- 修改了前端部门树的交互逻辑 +- 不影响现有功能和接口 +- 为前端权限控制提供了数据支持 + +## 后续计划 +- 前端集成该接口实现权限控制 +- 根据用户反馈优化树形结构展示 +- 考虑添加缓存提升查询性能 + +--- + +**变更执行人**: zlwu +**变更时间**: 2025-07-24 11:30:00 +**代码提交**: 待提交 +**测试状态**: 开发测试通过 +**部署状态**: 待部署 \ No newline at end of file diff --git a/docs/开发文档/API/API文档总览.md b/docs/开发文档/API/API文档总览.md index 0c7afbf3..40d3fa75 100644 --- a/docs/开发文档/API/API文档总览.md +++ b/docs/开发文档/API/API文档总览.md @@ -10,6 +10,9 @@ - [学生信息管理API](./学生信息管理API.md) - [班级信息管理API](./班级信息管理API.md) - [宿舍管理API](./宿舍管理API.md) +- [宿舍管理员信息API](./宿舍管理员信息API.md) +- [宿舍管理员授权API](./宿舍管理员授权API.md) +- [学生管理员授权关系API](./学生管理员授权关系API.md) ## 后勤管理模块API @@ -47,6 +50,29 @@ **详细文档**: [班级信息管理API.md](./班级信息管理API.md) +## 宿舍管理员信息API + +- [宿舍管理员信息API](./宿舍管理员信息API.md):包含宿舍管理员信息的增删改查接口 + - 支持不同类型宿舍管理员(全校管理员、自定义管理员、班主任)的管理 + - 提供获取可用教职工信息的接口,支持选择教职工作为宿舍管理员 + - **新增功能**: 在添加管理员时,通过下拉选择可用教师,支持模糊搜索,并自动填充选中教师的手机号码和性别信息 + +**核心功能**: +- 宿舍管理员信息分页查询(支持多条件搜索) +- 宿舍管理员信息新增、修改、删除 +- 宿舍管理员信息导出 +- 获取可用教职工信息列表(排除已经成为指定类型管理员的人员) +- 教师选择下拉搜索组件,支持模糊搜索和自动填充数据 + +**API基础路径**: `/xgStudentManager/studentManager` + +**最新更新**: +- 2025-07-25: 优化管理员添加界面,将姓名输入框改为可搜索的下拉选择框,选择后自动填充教师信息 +- 2025-07-24: 完成宿舍管理员信息管理模块的API接口设计 +- 2025-07-24: 添加获取可用的教职工信息列表接口,支持根据管理员类型筛选可用教职工 + +**详细文档**: [宿舍管理员信息API.md](./宿舍管理员信息API.md) + ## 企业信息管理API - [企业信息管理API](./企业信息管理API.md):包含企业信息、招聘岗位、招聘海报生成相关接口 @@ -67,3 +93,26 @@ - 2023-07-05: 添加企业规模、所属行业、岗位有效期类型等数据字典 **详细文档**: [企业信息管理API.md](./企业信息管理API.md) + +- [获取当前正在教学的班主任信息](/docs/开发文档/API/宿舍管理员信息API.md#获取当前正在教学的班主任信息) + +--- + +## 📅 最新更新日志 + +### 2025-07-24 - 学生信息管理界面重构 +- **界面重构**: 学生信息管理新增弹窗调整为多tab页形式 +- **功能增强**: 新增照片上传功能,支持完整的学生信息录入 +- **数据扩展**: 支持60+个学生信息字段,包括: + - 基础信息: 学号、身份证号、姓名、性别、出生日期、民族、籍贯、政治面貌、照片等 + - 扩展信息: 文化程度、户口类型、宗教信仰、生源地区、紧急联系人、特殊情况标记等 + - 家庭信息: 父母信息、监护人信息、家庭经济状况等 + - 健康信息: 身高、体重、血型、健康状况、疾病史、过敏史等 + - 学籍信息: 录取类别、学籍状态、入学信息、专业班级、宿舍信息等 + - 银行卡信息: 银行卡号、开户银行等 +- **技术改进**: 使用el-tabs组件管理多个表单页面,提升用户体验 + +### 2025-07-01 - API文档架构重构 +- **重要重构**: 将原本集中的大型API文档按业务模块拆分,提升维护效率 +- **新增**: API文档模板,用于新API文档的生成 +- **优化**: 目录结构,按功能模块分类管理 diff --git a/docs/开发文档/API/学生管理员授权关系API.md b/docs/开发文档/API/学生管理员授权关系API.md new file mode 100644 index 00000000..d76299ff --- /dev/null +++ b/docs/开发文档/API/学生管理员授权关系API.md @@ -0,0 +1,357 @@ +# 学生管理员授权关系API文档 + +## 1. 文档说明 + +### 1.1 API基础信息 +- **模块名称**: 学工管理 - 学生管理员授权关系 +- **模块代码**: ruoyi-xg +- **基础路径**: `/xgStudentManagerSource/studentManagerSource` +- **权限前缀**: `xgStudentManagerSource:studentManagerSource` +- **版本**: 1.0.0 +- **更新时间**: 2025-07-24 + +### 1.2 通用规范 +- **请求方式**: 支持GET、POST、PUT、DELETE +- **数据格式**: JSON +- **字符编码**: UTF-8 +- **认证方式**: Bearer Token +- **权限控制**: Sa-Token + 数据权限 + +### 1.3 响应格式 +```json +{ + "code": 200, + "msg": "操作成功", + "data": {}, + "timestamp": "2025-07-24T10:00:00" +} +``` + +## 2. 学生管理员授权关系接口 + +### 2.1 查询学生管理员授权关系列表 +- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/list` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:list` +- **功能描述**: 分页查询学生管理员授权关系列表 + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| pageNum | integer | 否 | 页码,默认1 | +| pageSize | integer | 否 | 每页大小,默认10 | +| managerId | long | 否 | 管理员ID | +| permissionType | string | 否 | 权限类型(1查看 2编辑 3完全管理) | +| authType | string | 否 | 授权类型(1全校级 2自定义 3班主任) | +| authSource | long | 否 | 授权来源ID(对应班级id) | +| status | string | 否 | 状态(0有效 1已撤销) | + +#### 响应数据 +```json +{ + "code": 200, + "msg": "查询成功", + "total": 10, + "rows": [ + { + "id": 1, + "managerId": 123, + "permissionType": "2", + "authType": "2", + "authSource": 456, + "status": "0", + "remark": "自定义管理员权限", + "createTime": "2025-07-24 10:00:00" + } + ] +} +``` + +### 2.2 获取学生管理员授权关系详细信息 +- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/{id}` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:query` +- **功能描述**: 根据主键查询学生管理员授权关系详情 + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| id | long | 是 | 主键ID | + +#### 响应数据 +```json +{ + "code": 200, + "msg": "查询成功", + "data": { + "id": 1, + "managerId": 123, + "permissionType": "2", + "authType": "2", + "authSource": 456, + "status": "0", + "remark": "自定义管理员权限", + "createTime": "2025-07-24 10:00:00", + "updateTime": "2025-07-24 10:00:00" + } +} +``` + +### 2.3 新增学生管理员授权关系 +- **接口路径**: POST `/xgStudentManagerSource/studentManagerSource` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:add` +- **功能描述**: 新增学生管理员授权关系 + +#### 请求参数 +```json +{ + "managerId": 123, + "permissionType": "2", + "authType": "2", + "authSource": 456, + "status": "0", + "remark": "自定义管理员权限" +} +``` + +#### 响应数据 +```json +{ + "code": 200, + "msg": "新增成功" +} +``` + +### 2.4 修改学生管理员授权关系 +- **接口路径**: PUT `/xgStudentManagerSource/studentManagerSource` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:edit` +- **功能描述**: 修改学生管理员授权关系 + +#### 请求参数 +```json +{ + "id": 1, + "managerId": 123, + "permissionType": "3", + "authType": "2", + "authSource": 456, + "status": "0", + "remark": "修改后的权限说明" +} +``` + +#### 响应数据 +```json +{ + "code": 200, + "msg": "修改成功" +} +``` + +### 2.5 删除学生管理员授权关系 +- **接口路径**: DELETE `/xgStudentManagerSource/studentManagerSource/{ids}` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:remove` +- **功能描述**: 删除学生管理员授权关系(支持批量删除) + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| ids | long[] | 是 | 主键ID数组 | + +#### 响应数据 +```json +{ + "code": 200, + "msg": "删除成功" +} +``` + +### 2.6 自定义学生管理员授予部门权限 +- **接口路径**: POST `/xgStudentManagerSource/studentManagerSource/grantDeptAuth` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:grantDeptAuth` +- **功能描述**: 为指定管理员批量授予多个部门的权限 + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| managerId | long | 是 | 管理员ID | +| authSourceIds | long[] | 是 | 资源ID列表(部门ID数组) | + +#### 响应数据 +```json +{ + "code": 200, + "msg": "授权成功" +} +``` + +### 2.7 获取指定管理员的授权资源名称列表 +- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/authSourceNames` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:query` +- **功能描述**: 获取指定管理员已授权的资源名称列表 + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| managerId | long | 是 | 管理员ID | + +#### 响应数据 +```json +{ + "code": 200, + "msg": "查询成功", + "data": [ + "计算机学院", + "计算机2023-1班", + "计算机2023-2班" + ] +} +``` + +### 2.8 获取当前用户的学生管理权限部门树 🆕 +- **接口路径**: GET `/xgStudentManagerSource/studentManagerSource/currentUserAuthTree` +- **权限标识**: `xgStudentManagerSource:studentManagerSource:query` +- **功能描述**: 获取当前登录用户的学生管理权限部门树形结构,只有班级节点可以点击 + +#### 请求参数 +无需入参,自动获取当前登录用户信息 + +#### 接口逻辑 +1. **第一步**: 通过当前登录用户ID,关联 `xg_student_manager` 与 `xg_student_manager_source` 表,获取授权来源信息 + - 查询条件:`xg_student_manager.user_id = 当前用户ID AND xg_student_manager.deleted = '0' AND xg_student_manager.status = '0'` + - 关联条件:`xg_student_manager_source.manager_id = xg_student_manager.id AND xg_student_manager_source.status = '0' AND xg_student_manager_source.deleted = '0'` + +2. **第二步**: 根据授权来源关联 `sys_dept` 表获取部门数据和所有子节点 + - 查询条件:`sys_dept.dept_id IN (auth_source列表) AND sys_dept.status = '0' AND sys_dept.del_flag = '0'` + - 同时获取所有子部门:通过 `ancestors` 字段查找子节点 + +3. **第三步**: 向上查找父节点直到根节点(id=101) + - 通过 `ancestors` 字段解析父节点层级关系 + - 构建完整的部门树结构 + +#### 响应数据 +```json +{ + "code": 200, + "msg": "查询成功", + "data": [ + { + "deptId": 101, + "parentId": null, + "deptName": "杭州职业技术学院", + "deptCategory": "university", + "orderNum": 1, + "clickable": false, + "children": [ + { + "deptId": 102, + "parentId": 101, + "deptName": "计算机学院", + "deptCategory": "college", + "orderNum": 1, + "clickable": false, + "children": [ + { + "deptId": 103, + "parentId": 102, + "deptName": "计算机科学与技术专业", + "deptCategory": "major", + "orderNum": 1, + "clickable": false, + "children": [ + { + "deptId": 104, + "parentId": 103, + "deptName": "计算机2023-1班", + "deptCategory": "class", + "orderNum": 1, + "clickable": true, + "children": [] + }, + { + "deptId": 105, + "parentId": 103, + "deptName": "计算机2023-2班", + "deptCategory": "class", + "orderNum": 2, + "clickable": true, + "children": [] + } + ] + } + ] + } + ] + } + ] +} +``` + +#### 响应字段说明 +| 字段名 | 类型 | 说明 | +|--------|------|------| +| deptId | long | 部门ID | +| parentId | long | 父部门ID | +| deptName | string | 部门名称 | +| deptCategory | string | 部门类别编码 | +| orderNum | integer | 显示顺序 | +| clickable | boolean | 是否可点击(只有班级节点可点击) | +| children | array | 子部门列表 | + +#### 使用说明 +- 该接口无需传参,自动获取当前登录用户的权限范围 +- 返回的树形结构包含完整的层级关系,从根节点到叶子节点 +- `clickable` 字段标识节点是否可点击,只有班级节点(包含"班"字或dept_category包含"class")设置为true +- 前端可根据 `clickable` 字段控制节点的交互行为 +- 树形结构按 `orderNum` 字段排序 + +## 3. 数据字典 + +### 3.1 权限类型 (permissionType) +| 值 | 说明 | +|----|------| +| 1 | 查看 | +| 2 | 编辑 | +| 3 | 完全管理 | + +### 3.2 授权类型 (authType) +| 值 | 说明 | +|----|------| +| 1 | 全校级 | +| 2 | 自定义 | +| 3 | 班主任 | + +### 3.3 状态 (status) +| 值 | 说明 | +|----|------| +| 0 | 有效 | +| 1 | 已撤销 | + +## 4. 权限说明 + +### 4.1 数据权限控制 +- **超级管理员**: 可管理所有学生管理员授权关系 +- **学工管理员**: 可管理所有学生管理员授权关系 +- **二级学院管理员**: 只能管理本学院相关的授权关系 +- **普通用户**: 只能查看自己的权限信息 + +### 4.2 操作权限控制 +- **查询**: 所有有相关权限的用户 +- **新增**: 学工管理员、二级学院管理员 +- **修改**: 学工管理员、二级学院管理员 +- **删除**: 学工管理员、二级学院管理员 +- **授权**: 学工管理员、二级学院管理员 + +## 5. 注意事项 + +1. 所有接口都需要Bearer Token认证 +2. 删除操作为逻辑删除,不会物理删除数据 +3. 授权关系具有层级性,上级权限包含下级权限 +4. 支持多租户数据隔离 +5. 获取当前用户权限树接口会自动过滤无权限的部门 +6. 部门树构建时会自动补全父节点层级关系 + +--- + +**文档更新时间**: 2025-07-24 +**文档版本**: 1.0.0 +**维护人员**: Cursor AI +**更新说明**: 新增学生管理员授权关系管理接口,包含获取当前用户权限部门树功能 \ No newline at end of file diff --git a/docs/开发文档/API/宿舍管理员信息API.md b/docs/开发文档/API/宿舍管理员信息API.md new file mode 100644 index 00000000..58f1fc8e --- /dev/null +++ b/docs/开发文档/API/宿舍管理员信息API.md @@ -0,0 +1,259 @@ +# 宿舍管理员信息API文档 + +## 1. API概述 +本文档提供宿舍管理员信息相关的API接口说明,包括管理员信息的查询、新增、修改、删除等功能,以及获取可用教师列表的接口。 + +## 2. 基本信息 +- **模块名称**:宿舍管理员信息管理 +- **接口前缀**:`/xgStudentManager/studentManager` +- **数据权限**:需要相应的权限才能访问接口 + +## 3. API列表 + +### 3.1 查询宿舍管理员信息列表 + +- **接口地址**:`/xgStudentManager/studentManager/list` +- **请求方式**:GET +- **权限标识**:`xgStudentManager:studentManager:list` +- **请求参数**: + +| 参数名 | 类型 | 是否必须 | 描述 | +|------------|--------|----------|-----------------------------------------------| +| managerName| string | 否 | 管理员姓名,支持模糊查询 | +| managerType| string | 否 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) | +| managerLevel| number | 否 | 管理级别(1-3,1为最高) | +| phone | string | 否 | 联系电话 | +| gender | string | 否 | 性别(0男 1女 2未知) | +| status | string | 否 | 状态(0正常 1停用) | +| pageNum | number | 是 | 页码 | +| pageSize | number | 是 | 每页记录数 | + +- **返回示例**: +```json +{ + "total": 2, + "rows": [ + { + "id": 1, + "managerName": "张三", + "managerType": "1", + "managerLevel": 1, + "userId": 103, + "phone": "13800138001", + "gender": "0", + "status": "0", + "remark": "全校管理员", + "createTime": "2025-07-24 10:00:00", + "updateTime": "2025-07-24 10:00:00" + } + ], + "code": 200, + "msg": "查询成功" +} +``` + +### 3.2 获取宿舍管理员信息详细信息 + +- **接口地址**:`/xgStudentManager/studentManager/{id}` +- **请求方式**:GET +- **权限标识**:`xgStudentManager:studentManager:query` +- **请求参数**: + +| 参数名 | 类型 | 是否必须 | 描述 | +|-------|--------|----------|-------| +| id | number | 是 | 主键ID | + +- **返回示例**: +```json +{ + "data": { + "id": 1, + "managerName": "张三", + "managerType": "1", + "managerLevel": 1, + "userId": 103, + "phone": "13800138001", + "gender": "0", + "status": "0", + "remark": "全校管理员", + "createTime": "2025-07-24 10:00:00", + "updateTime": "2025-07-24 10:00:00" + }, + "code": 200, + "msg": "操作成功" +} +``` + +### 3.3 新增宿舍管理员信息 + +- **接口地址**:`/xgStudentManager/studentManager` +- **请求方式**:POST +- **权限标识**:`xgStudentManager:studentManager:add` +- **请求参数**: + +| 参数名 | 类型 | 是否必须 | 描述 | +|------------|--------|----------|-----------------------------------------------| +| managerName| string | 是 | 管理员姓名 | +| managerType| string | 是 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) | +| managerLevel| number | 是 | 管理级别(1-3,1为最高) | +| userId | number | 是 | 关联用户ID | +| phone | string | 是 | 联系电话 | +| gender | string | 是 | 性别(0男 1女 2未知) | +| status | string | 否 | 状态(0正常 1停用),默认0 | +| remark | string | 否 | 备注 | + +- **返回示例**: +```json +{ + "code": 200, + "msg": "操作成功" +} +``` + +### 3.4 修改宿舍管理员信息 + +- **接口地址**:`/xgStudentManager/studentManager` +- **请求方式**:PUT +- **权限标识**:`xgStudentManager:studentManager:edit` +- **请求参数**: + +| 参数名 | 类型 | 是否必须 | 描述 | +|------------|--------|----------|-----------------------------------------------| +| id | number | 是 | 主键ID | +| managerName| string | 是 | 管理员姓名 | +| managerType| string | 是 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) | +| managerLevel| number | 是 | 管理级别(1-3,1为最高) | +| userId | number | 是 | 关联用户ID | +| phone | string | 是 | 联系电话 | +| gender | string | 是 | 性别(0男 1女 2未知) | +| status | string | 否 | 状态(0正常 1停用) | +| remark | string | 否 | 备注 | + +- **返回示例**: +```json +{ + "code": 200, + "msg": "操作成功" +} +``` + +### 3.5 删除宿舍管理员信息 + +- **接口地址**:`/xgStudentManager/studentManager/{ids}` +- **请求方式**:DELETE +- **权限标识**:`xgStudentManager:studentManager:remove` +- **请求参数**: + +| 参数名 | 类型 | 是否必须 | 描述 | +|-------|--------|----------|-----------------------| +| ids | array | 是 | 主键ID数组,格式:[1,2] | + +- **返回示例**: +```json +{ + "code": 200, + "msg": "操作成功" +} +``` + +### 3.6 导出宿舍管理员信息 + +- **接口地址**:`/xgStudentManager/studentManager/export` +- **请求方式**:POST +- **权限标识**:`xgStudentManager:studentManager:export` +- **请求参数**:与查询列表接口参数相同 +- **返回内容**:Excel文件 + +### 3.7 获取可用教师列表 + +- **接口地址**:`/xgStudentManager/studentManager/listAvailableTeachers` +- **请求方式**:GET +- **权限标识**:`xgStudentManager:studentManager:list` +- **请求参数**: + +| 参数名 | 类型 | 是否必须 | 描述 | +|------------|--------|----------|-----------------------------------------------| +| managerType| string | 是 | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) | + +- **返回示例**: +```json +{ + "data": [ + { + "id": 101, + "managerName": "张三", + "phone": "13800138001", + "gender": "0" + }, + { + "id": 102, + "managerName": "李四", + "phone": "13800138002", + "gender": "1" + } + ], + "code": 200, + "msg": "操作成功" +} +``` + +## 获取当前正在教学的班主任信息 + +- **接口路径**:`/xgStudentManager/studentManager/listActiveClassTeachers` +- **请求方式**:GET +- **权限标识**:`xgStudentManager:studentManager:list` +- **入参**: + - `phone`(可选,string):手机号,模糊查询 + - `name`(可选,string):姓名,模糊查询 +- **出参**: + - `name`:姓名 + - `phone`:手机号 + - `sex`:性别 + - `className`:班级名称 +- **返回示例**: +```json +{ + "code": 200, + "msg": "操作成功", + "data": [ + { + "name": "张三", + "phone": "13800001111", + "sex": "0", + "className": "2025级1班" + } + ] +} +``` +- **说明**: + - 仅返回当前“正在教学”的班主任(班级状态为1,未删除,班主任ID有效,用户状态正常)。 + - 支持姓名和手机号的模糊查询,均为可选参数。 + +## 4. 数据结构说明 + +### 4.1 宿舍管理员对象 + +| 字段名 | 类型 | 描述 | +|------------|--------|-----------------------------------------------| +| id | number | 主键ID | +| managerName| string | 管理员姓名 | +| managerType| string | 管理员类型(1 全校管理员 2 自定义管理员 3 班主任) | +| managerLevel| number | 管理级别(1-3,1为最高) | +| userId | number | 关联用户ID | +| phone | string | 联系电话 | +| gender | string | 性别(0男 1女 2未知) | +| status | string | 状态(0正常 1停用) | +| deleted | string | 删除标志(0代表存在 1代表删除) | +| remark | string | 备注 | +| createBy | number | 创建者 | +| createTime | date | 创建时间 | +| updateBy | number | 更新者 | +| updateTime | date | 更新时间 | + +## 5. 错误码说明 + +| 错误码 | 描述 | 解决方案 | +|-------|----------------|-----------------------------| +| 500 | 系统内部错误 | 联系系统管理员 | +| 401 | 未授权 | 检查用户权限或重新登录 | +| 400 | 请求参数错误 | 检查请求参数是否符合要求 | \ No newline at end of file diff --git a/web/src/api/studentMsg/index.ts b/web/src/api/studentMsg/index.ts index f3855ff3..6683c467 100644 --- a/web/src/api/studentMsg/index.ts +++ b/web/src/api/studentMsg/index.ts @@ -9,12 +9,17 @@ import { StudentQuery, StudentVO, StudentForm, XgDeptTreeVO, R, TableDataInfo } */ export const XgDeptTreeSelect = (belongDeptId?: number): AxiosPromise => { // 实际项目中连接后端接口 + // return request({ + // url: '/system/user/deptTree', + // method: 'get', + // params: { + // belongDeptId + // } + // }); + return request({ - url: '/system/user/deptTree', - method: 'get', - params: { - belongDeptId - } + url: '/xgStudentManagerSource/studentManagerSource/currentUserAuthTree', + method: 'get' }); // // 模拟数据,直接返回与页面组件期望格式一致的数据 diff --git a/web/src/api/studentMsg/types.ts b/web/src/api/studentMsg/types.ts index 7c0a8245..afe3f1c7 100644 --- a/web/src/api/studentMsg/types.ts +++ b/web/src/api/studentMsg/types.ts @@ -49,6 +49,7 @@ export interface StudentVO { // 学生表单对象 export interface StudentForm { + // 原有字段 studentId?: number | string; deptId?: number; studentNo: string; @@ -64,6 +65,102 @@ export interface StudentForm { classId?: number; address?: string; remark?: string; + + // 基础信息字段 + student_no?: string; + id_card?: string; + name?: string; + name_english?: string; + former_name?: string; + gender?: string; + birth_date?: string; + nationality?: string; + native_place?: string; + political_status?: string; + hukou_location?: string; + home_address?: string; + current_address?: string; + postal_code?: string; + photo_url?: string; + photo_path?: string; + phone?: string; + is_boarder?: number; + + // 扩展信息字段 + education_level?: string; + household_register_type?: string; + religion?: string; + source_region?: string; + graduate_school?: string; + qq?: string; + wechat?: string; + marital_status?: string; + emergency_contact_name?: string; + emergency_contact_phone?: string; + emergency_contact_relation?: string; + is_poor_student?: number; + is_minority?: number; + is_disabled?: number; + is_orphan?: number; + is_left_behind_child?: number; + is_single_child?: number; + is_low_income?: number; + has_loan?: number; + loan_amount?: string; + specialties?: string; + awards?: string; + violations?: string; + social_activities?: string; + + // 家庭信息字段 + father_name?: string; + father_phone?: string; + father_work_unit?: string; + mother_name?: string; + mother_phone?: string; + mother_work_unit?: string; + guardian_name?: string; + guardian_phone?: string; + guardian_relation?: string; + family_income?: string; + per_capita_income?: string; + income_source?: string; + family_economic_status?: string; + family_members?: string; + + // 健康信息字段 + height?: string; + weight?: string; + blood_type?: string; + health_status?: string; + special_condition?: string; + medical_history?: string; + allergies?: string; + disability_type?: string; + disability_level?: string; + + // 学籍信息字段 + admission_category?: string; + student_status?: string; + enrollment_year?: string; + enrollment_date?: string; + school_system?: string; + academic_level?: string; + training_type?: string; + major_name?: string; + class_name?: string; + grade?: string; + college_name?: string; + counselor_name?: string; + class_teacher_name?: string; + dormitory_building?: string; + dormitory_room?: string; + + // 银行卡信息字段 + bank_card_no?: string; + bank_name?: string; + bank_branch?: string; + card_holder_name?: string; } // 统一响应类型 diff --git a/web/src/api/xgStudentManager/studentManager/index.ts b/web/src/api/xgStudentManager/studentManager/index.ts new file mode 100644 index 00000000..07e29bcc --- /dev/null +++ b/web/src/api/xgStudentManager/studentManager/index.ts @@ -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 => { + return request({ + url: '/xgStudentManager/studentManager/listAvailableTeachers', + method: 'get', + params: { managerType } + }); +}; + +/** + * 查询宿舍管理员信息列表 + * @param query + * @returns {*} + */ + +export const listStudentManager = (query?: StudentManagerQuery): AxiosPromise => { + return request({ + url: '/xgStudentManager/studentManager/list', + method: 'get', + params: query + }); +}; + +/** + * 查询宿舍管理员信息详细 + * @param id + */ +export const getStudentManager = (id: string | number): AxiosPromise => { + 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) => { + 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 + }); +}; diff --git a/web/src/api/xgStudentManager/studentManager/types.ts b/web/src/api/xgStudentManager/studentManager/types.ts new file mode 100644 index 00000000..6decf4ef --- /dev/null +++ b/web/src/api/xgStudentManager/studentManager/types.ts @@ -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; +} + + + diff --git a/web/src/api/xgStudentManagerSource/studentManagerSource/index.ts b/web/src/api/xgStudentManagerSource/studentManagerSource/index.ts new file mode 100644 index 00000000..e5804338 --- /dev/null +++ b/web/src/api/xgStudentManagerSource/studentManagerSource/index.ts @@ -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 => { + return request({ + url: '/xgStudentManagerSource/studentManagerSource/list', + method: 'get', + params: query + }); +}; + +/** + * 查询学生管理员授权关系详细 + * @param id + */ +export const getStudentManagerSource = (id: string | number): AxiosPromise => { + 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) => { + return request({ + url: '/xgStudentManagerSource/studentManagerSource/' + id, + method: 'delete' + }); +}; diff --git a/web/src/api/xgStudentManagerSource/studentManagerSource/types.ts b/web/src/api/xgStudentManagerSource/studentManagerSource/types.ts new file mode 100644 index 00000000..d9878323 --- /dev/null +++ b/web/src/api/xgStudentManagerSource/studentManagerSource/types.ts @@ -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; +} + + + diff --git a/web/src/views/studentMsg/authmsg/components/AdminDialog.vue b/web/src/views/studentMsg/authmsg/components/AdminDialog.vue index 1b499ad6..0fcfb415 100644 --- a/web/src/views/studentMsg/authmsg/components/AdminDialog.vue +++ b/web/src/views/studentMsg/authmsg/components/AdminDialog.vue @@ -8,7 +8,21 @@ > - + + +
+ {{ item.managerName }} + ({{ item.phone }}) ({{ item.userId }}) +
+
+
@@ -33,8 +47,68 @@ @@ -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; +} diff --git a/web/src/views/studentMsg/authmsg/index.vue b/web/src/views/studentMsg/authmsg/index.vue index 5e4acf23..bac3d497 100644 --- a/web/src/views/studentMsg/authmsg/index.vue +++ b/web/src/views/studentMsg/authmsg/index.vue @@ -8,7 +8,7 @@ - + @@ -30,11 +30,11 @@ - + - + @@ -57,13 +57,13 @@ - + - 搜索 + 搜索 重置 @@ -78,14 +78,30 @@ - + - + + + + - diff --git a/web/src/views/studentMsg/studentMsg/index.vue b/web/src/views/studentMsg/studentMsg/index.vue index 5583c02b..26f3355f 100644 --- a/web/src/views/studentMsg/studentMsg/index.vue +++ b/web/src/views/studentMsg/studentMsg/index.vue @@ -1,16 +1,16 @@