Files
hzdyjs/docs/变更管理/code-adjust-record-2025-01-27-college-leave-approvers-query.md
T
2025-08-05 14:00:23 +08:00

7.9 KiB
Raw Blame History

学院请假审批人查询API接口实现变更记录

变更日期: 2025-01-27
变更人员: AI Assistant
变更类型: 功能新增

📋 变更概述

在学生信息管理模块中新增了一个API接口,用于根据学生ID查询所在学院的请假审批人列表。

🎯 业务需求

  • 接口入参:studentId(学生ID)
  • 业务逻辑:
    1. 通过xg_student_msg.id关联入参studentId学生id,deleted = 0,获取到college_id
    2. 从sys_user表中,找到college_id对应的组织及子组织下,具备xsqj-ejxyspr这个角色的人员list
    3. 查询条件:
      • sys_dept是组织表:del_flag = 0, status = 0
      • sys_user是用户表:del_flag = 0, status = 0, account_type = 1
      • sys_user_role是用户与角色的关联表
      • sys_role是角色表:role_key = 'xsqj-ejxyspr'
  • 返回结果:请假审批人用户ID列表

🔧 技术实现

1. Mapper接口扩展

文件: backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java

/**
 * 根据学生ID查询学院ID
 *
 * @param studentId 学生ID
 * @return 学院ID
 */
Long selectCollegeIdByStudentId(@Param("studentId") Long studentId);

/**
 * 根据学院ID和角色Key查询具备该角色的用户列表
 *
 * @param collegeId 学院ID
 * @param roleKey 角色Key
 * @return 用户ID列表
 */
List<Long> selectUserIdsByCollegeIdAndRoleKey(@Param("collegeId") Long collegeId, @Param("roleKey") String roleKey);

2. Mapper XML SQL实现

文件: backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml

<!-- 根据学生ID查询学院ID -->
<select id="selectCollegeIdByStudentId" resultType="java.lang.Long">
    SELECT college_id
    FROM xg_student_msg
    WHERE id = #{studentId}
      AND deleted = 0
</select>

<!-- 根据学院ID和角色Key查询具备该角色的用户列表 -->
<select id="selectUserIdsByCollegeIdAndRoleKey" resultType="java.lang.Long">
    SELECT DISTINCT u.user_id
    FROM sys_user u
    INNER JOIN sys_user_role ur ON u.user_id = ur.user_id
    INNER JOIN sys_role r ON ur.role_id = r.role_id
    INNER JOIN sys_dept d ON u.dept_id = d.dept_id
    WHERE u.del_flag = '0'
      AND u.status = '0'
      AND u.account_type = '1'
      AND d.del_flag = '0'
      AND d.status = '0'
      AND r.role_key = #{roleKey}
      AND (d.dept_id = #{collegeId} OR FIND_IN_SET(#{collegeId}, d.ancestors))
</select>

3. Service接口扩展

文件: backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java

/**
 * 根据学生ID获取学院请假审批人列表
 *
 * @param studentId 学生ID
 * @return 请假审批人用户ID列表
 */
List<Long> getCollegeLeaveApproversByStudentId(Long studentId);

4. Service实现类扩展

文件: backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java

/**
 * 根据学生ID获取学院请假审批人列表
 *
 * @param studentId 学生ID
 * @return 请假审批人用户ID列表
 */
@Override
public List<Long> getCollegeLeaveApproversByStudentId(Long studentId) {
    log.info("根据学生ID获取学院请假审批人列表 - 学生ID: {}", studentId);
    
    // 1. 根据学生ID查询学院ID
    Long collegeId = baseMapper.selectCollegeIdByStudentId(studentId);
    if (collegeId == null) {
        log.warn("未找到学生对应的学院信息 - 学生ID: {}", studentId);
        return new ArrayList<>();
    }
    
    log.info("学生所在学院ID: {}", collegeId);
    
    // 2. 根据学院ID和角色Key查询具备请假审批角色的用户列表
    List<Long> approverUserIds = baseMapper.selectUserIdsByCollegeIdAndRoleKey(collegeId, "xsqj-ejxyspr");
    
    log.info("找到的请假审批人数量: {}", approverUserIds.size());
    return approverUserIds;
}

5. Controller API接口

文件: backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java

/**
 * 根据学生ID获取学院请假审批人列表
 *
 * @param studentId 学生ID
 * @return 请假审批人用户ID列表
 */
@SaCheckPermission("studentMsg:studentMsg:query")
@GetMapping("/getCollegeLeaveApprovers/{studentId}")
public R<List<Long>> getCollegeLeaveApprovers(@NotNull(message = "学生ID不能为空") @PathVariable Long studentId) {
    log.info("根据学生ID获取学院请假审批人列表 - 学生ID: {}", studentId);
    List<Long> approverUserIds = xgStudentMsgService.getCollegeLeaveApproversByStudentId(studentId);
    if (approverUserIds.isEmpty()) {
        return R.fail("未找到该学生所在学院的请假审批人");
    }
    return R.ok(approverUserIds);
}

📡 API接口详情

接口信息

  • 请求路径: GET /studentMsg/studentMsg/getCollegeLeaveApprovers/{studentId}
  • 权限要求: studentMsg:studentMsg:query
  • 入参: studentId (路径参数,Long类型)
  • 返回: R<List> 统一响应格式

请求示例

GET /studentMsg/studentMsg/getCollegeLeaveApprovers/123456

响应示例

成功响应:

{
    "code": 200,
    "msg": "操作成功",
    "data": [789012, 789013, 789014]
}

失败响应:

{
    "code": 500,
    "msg": "未找到该学生所在学院的请假审批人",
    "data": null
}

🔍 数据库查询逻辑

第一步:查询学生所在学院ID

SELECT college_id
FROM xg_student_msg
WHERE id = #{studentId}
  AND deleted = 0

第二步:查询学院及子组织下具备请假审批角色的用户

SELECT DISTINCT u.user_id
FROM sys_user u
INNER JOIN sys_user_role ur ON u.user_id = ur.user_id
INNER JOIN sys_role r ON ur.role_id = r.role_id
INNER JOIN sys_dept d ON u.dept_id = d.dept_id
WHERE u.del_flag = '0'
  AND u.status = '0'
  AND u.account_type = '1'
  AND d.del_flag = '0'
  AND d.status = '0'
  AND r.role_key = 'xsqj-ejxyspr'
  AND (d.dept_id = #{collegeId} OR FIND_IN_SET(#{collegeId}, d.ancestors))

📊 表关联关系

  1. xg_student_msg (学生信息表) → college_id
  2. sys_dept (部门表) → dept_id, ancestors (祖级列表)
  3. sys_user (用户表) → dept_id, user_id
  4. sys_user_role (用户角色关联表) → user_id, role_id
  5. sys_role (角色表) → role_id, role_key

✅ 实现特点

  1. 数据完整性: 确保只查询未删除的学生、用户、部门和角色信息
  2. 权限控制: 使用@SaCheckPermission注解进行权限验证
  3. 参数验证: 使用@NotNull注解验证入参
  4. 日志记录: 添加详细的日志记录便于调试
  5. 错误处理: 当未找到审批人时返回友好的错误提示
  6. 统一响应: 使用R<List>统一响应格式
  7. 组织层级: 支持查询学院及其子组织下的审批人
  8. 角色过滤: 精确匹配角色Key为'xsqj-ejxyspr'的用户

🧪 测试建议

  1. 正常场景测试:
    • 使用存在的学生ID测试
    • 验证返回的审批人列表
  2. 异常场景测试:
    • 使用不存在的学生ID
    • 使用已删除的学生ID
    • 使用空值或无效值
    • 测试学院下没有审批人的情况
  3. 权限测试: 验证权限控制是否生效
  4. 数据完整性测试: 验证查询条件是否正确过滤

📝 相关文档

  • 学生信息管理API文档: docs/开发文档/API/学生信息管理API.md
  • 学生信息表结构: docs/设计文档/database/学工管理-学生信息管理新版/xg_student_msg 学生信息表.sql
  • 系统用户表结构: docs/设计文档/database/学工管理-学生信息管理/05-system-management-module.sql

🔧 技术要点

  1. FIND_IN_SET函数: 用于查询ancestors字段中是否包含指定的学院ID
  2. DISTINCT去重: 避免重复的用户ID
  3. 多表关联: 通过INNER JOIN关联用户、角色、部门表
  4. 条件过滤: 严格按照业务要求过滤有效数据

变更完成时间: 2025-01-27
变更状态: ✅ 已完成
下一步: 进行功能测试和API文档更新