feat(leave): 一年级请假二级学院与分管领导改走人文学院
按入学年与每年9月1日切届判定一年级;代理学院 dept_id 通过 sys_config 配置,提交时覆写选人,流程定义与销假不变。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
08fbb49e89
commit
a76fd32d71
5 files changed
+232
-48
No files matched your search
+2
-2
@@ -829,7 +829,7 @@ public class XgStudentMsgController extends BaseController {
|
||||
log.info("根据学生ID获取学院请假审批人列表 - 学生ID: {}", studentId);
|
||||
List<Long> approverUserIds = xgStudentMsgService.getCollegeLeaveApproversByStudentId(studentId);
|
||||
if (approverUserIds.isEmpty()) {
|
||||
return R.fail("未找到该学生所在学院的请假审批人");
|
||||
return R.fail("未找到学院请假审批人(一年级查人文学院角色 xsqj-ejxyspr),请联系管理员配置");
|
||||
}
|
||||
return R.ok(approverUserIds);
|
||||
}
|
||||
@@ -846,7 +846,7 @@ public class XgStudentMsgController extends BaseController {
|
||||
log.info("根据学生ID获取二级学院分管领导ID列表 - 学生ID: {}", studentId);
|
||||
List<Long> leaderIds = xgStudentMsgService.getCollegeLeadersByStudentId(studentId);
|
||||
if (leaderIds.isEmpty()) {
|
||||
return R.fail("未找到该学生所在学院的分管领导");
|
||||
return R.fail("未找到学院分管领导(一年级查人文学院 xg_college_leader),请联系管理员配置");
|
||||
}
|
||||
return R.ok(leaderIds);
|
||||
}
|
||||
|
||||
+8
@@ -68,6 +68,14 @@ public interface XgStudentMsgMapper extends BaseMapperPlus<XgStudentMsg, XgStude
|
||||
*/
|
||||
String selectCollegeIdByStudentId(@Param("studentId") Long studentId);
|
||||
|
||||
/**
|
||||
* 根据学生ID查询入学年份(优先班级 enrollment_year,其次学生 enrollment_year)
|
||||
*
|
||||
* @param studentId 学生ID
|
||||
* @return 入学年份,均无则返回 null
|
||||
*/
|
||||
Long selectEnrollmentYearByStudentId(@Param("studentId") Long studentId);
|
||||
|
||||
/**
|
||||
* 根据学院ID和角色Key查询具备该角色的用户列表
|
||||
*
|
||||
|
||||
+89
-46
@@ -1,5 +1,7 @@
|
||||
package org.dromara.xg.service.impl;
|
||||
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.service.ConfigService;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
@@ -49,12 +51,14 @@ import java.util.stream.Collectors;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
|
||||
/**
|
||||
* 学生信息Service业务层处理
|
||||
@@ -67,6 +71,14 @@ import java.util.HashSet;
|
||||
@Service
|
||||
public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
|
||||
|
||||
/** 一年级请假代理学院(人文学院)dept_id,配置于 sys_config */
|
||||
private static final String FRESHMAN_PROXY_COLLEGE_CONFIG_KEY = "xg.studentLeave.freshmanProxyCollegeId";
|
||||
|
||||
/** 请假二级学院审批角色 */
|
||||
private static final String LEAVE_COLLEGE_APPROVER_ROLE_KEY = "xsqj-ejxyspr";
|
||||
|
||||
private static final ZoneId SHANGHAI_ZONE = ZoneId.of("Asia/Shanghai");
|
||||
|
||||
private final XgStudentMsgMapper baseMapper;
|
||||
private final ISysUserService sysUserService;
|
||||
private final SysDeptMapper sysDeptMapper;
|
||||
@@ -76,6 +88,7 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
|
||||
private final XgClassMsgMapper xgClassMsgMapper;
|
||||
private final XgDormBedStudentMapper xgDormBedStudentMapper;
|
||||
private final XgSysDeptMapper xgSysDeptMapper;
|
||||
private final ConfigService configService;
|
||||
|
||||
/**
|
||||
* 查询学生信息
|
||||
@@ -1088,6 +1101,9 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
|
||||
|
||||
/**
|
||||
* 根据学生ID获取学院请假审批人列表
|
||||
* <p>
|
||||
* 一年级(按入学年、每年9月1日切届)走 sys_config 配置的代理学院(人文学院);
|
||||
* 二年级及以上走学生本学院。入学年缺失时禁止提交。
|
||||
*
|
||||
* @param studentId 学生ID
|
||||
* @return 请假审批人用户ID列表
|
||||
@@ -1095,34 +1111,16 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
|
||||
@Override
|
||||
public List<Long> getCollegeLeaveApproversByStudentId(Long studentId) {
|
||||
log.info("根据学生ID获取学院请假审批人列表 - 学生ID: {}", studentId);
|
||||
|
||||
// 1. 根据学生ID查询学院ID
|
||||
String collegeIdStr = baseMapper.selectCollegeIdByStudentId(studentId);
|
||||
Long collegeId = null;
|
||||
if (StringUtils.isNotBlank(collegeIdStr)) {
|
||||
try {
|
||||
collegeId = Long.valueOf(collegeIdStr);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("学院ID格式错误,无法转换为Long类型 - 学生ID: {}, collegeIdStr: {}", studentId, collegeIdStr);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
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());
|
||||
Long collegeId = resolveLeaveCollegeId(studentId);
|
||||
List<Long> approverUserIds = baseMapper.selectUserIdsByCollegeIdAndRoleKey(collegeId, LEAVE_COLLEGE_APPROVER_ROLE_KEY);
|
||||
log.info("找到的请假审批人数量: {}, collegeId: {}", approverUserIds.size(), collegeId);
|
||||
return approverUserIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据学生ID获取二级学院分管领导ID列表
|
||||
* <p>
|
||||
* 一年级走人文学院(配置代理学院),二年级及以上走本学院;入学年缺失禁止提交。
|
||||
*
|
||||
* @param studentId 学生ID
|
||||
* @return 分管领导ID列表
|
||||
@@ -1130,32 +1128,77 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
|
||||
@Override
|
||||
public List<Long> getCollegeLeadersByStudentId(Long studentId) {
|
||||
log.info("根据学生ID获取二级学院分管领导ID列表 - 学生ID: {}", studentId);
|
||||
|
||||
// 1. 根据学生ID查询学院ID
|
||||
String collegeIdStr = baseMapper.selectCollegeIdByStudentId(studentId);
|
||||
Long collegeId = null;
|
||||
if (StringUtils.isNotBlank(collegeIdStr)) {
|
||||
try {
|
||||
collegeId = Long.valueOf(collegeIdStr);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("学院ID格式错误,无法转换为Long类型 - 学生ID: {}, collegeIdStr: {}", studentId, collegeIdStr);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
if (collegeId == null) {
|
||||
log.warn("未找到学生对应的学院信息 - 学生ID: {}", studentId);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
log.info("学生所在学院ID: {}", collegeId);
|
||||
|
||||
// 2. 根据学院ID查询二级学院分管领导ID列表
|
||||
Long collegeId = resolveLeaveCollegeId(studentId);
|
||||
List<Long> leaderIds = baseMapper.selectCollegeLeaderIdsByCollegeId(collegeId);
|
||||
|
||||
log.info("找到的二级学院分管领导数量: {}", leaderIds.size());
|
||||
log.info("找到的二级学院分管领导数量: {}, collegeId: {}", leaderIds.size(), collegeId);
|
||||
return leaderIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析请假流程使用的学院ID:一年级 → 代理学院;非一年级 → 学生本学院。
|
||||
*/
|
||||
private Long resolveLeaveCollegeId(Long studentId) {
|
||||
Long enrollmentYear = baseMapper.selectEnrollmentYearByStudentId(studentId);
|
||||
if (enrollmentYear == null) {
|
||||
throw new ServiceException("学生入学年信息不完整,无法提交请假,请联系管理员维护班级或学生的入学年份");
|
||||
}
|
||||
|
||||
String collegeIdStr = baseMapper.selectCollegeIdByStudentId(studentId);
|
||||
Long ownCollegeId = parseCollegeId(collegeIdStr, studentId);
|
||||
if (ownCollegeId == null) {
|
||||
throw new ServiceException("未找到该学生所在学院信息,无法提交请假");
|
||||
}
|
||||
|
||||
if (!isFreshmanByEnrollmentYear(enrollmentYear)) {
|
||||
log.info("非一年级请假,使用学生本学院 - studentId: {}, enrollmentYear: {}, collegeId: {}",
|
||||
studentId, enrollmentYear, ownCollegeId);
|
||||
return ownCollegeId;
|
||||
}
|
||||
|
||||
Long proxyCollegeId = resolveFreshmanProxyCollegeId();
|
||||
log.info("一年级请假,使用代理学院 - studentId: {}, enrollmentYear: {}, proxyCollegeId: {}, ownCollegeId: {}",
|
||||
studentId, enrollmentYear, proxyCollegeId, ownCollegeId);
|
||||
return proxyCollegeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按入学年判断是否一年级。学年切换日:每年 9 月 1 日(Asia/Shanghai)。
|
||||
*/
|
||||
private boolean isFreshmanByEnrollmentYear(Long enrollmentYear) {
|
||||
LocalDate today = LocalDate.now(SHANGHAI_ZONE);
|
||||
int currentCohortYear = today.getMonthValue() >= 9 ? today.getYear() : today.getYear() - 1;
|
||||
return enrollmentYear.intValue() == currentCohortYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从系统参数读取一年级请假代理学院 dept_id。
|
||||
*/
|
||||
private Long resolveFreshmanProxyCollegeId() {
|
||||
String configValue = configService.getConfigValue(FRESHMAN_PROXY_COLLEGE_CONFIG_KEY);
|
||||
if (StringUtils.isBlank(configValue)) {
|
||||
throw new ServiceException("一年级请假代理学院未配置,请在系统参数中配置 "
|
||||
+ FRESHMAN_PROXY_COLLEGE_CONFIG_KEY);
|
||||
}
|
||||
try {
|
||||
return Long.valueOf(configValue.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ServiceException("一年级请假代理学院配置无效(应为部门ID数字),请检查参数 "
|
||||
+ FRESHMAN_PROXY_COLLEGE_CONFIG_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
private Long parseCollegeId(String collegeIdStr, Long studentId) {
|
||||
if (StringUtils.isBlank(collegeIdStr)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Long.valueOf(collegeIdStr);
|
||||
} catch (NumberFormatException e) {
|
||||
log.warn("学院ID格式错误 - 学生ID: {}, collegeIdStr: {}", studentId, collegeIdStr);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量申请床位
|
||||
*
|
||||
|
||||
+10
@@ -155,6 +155,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<!-- 根据学生ID查询入学年份:优先班级,其次学生本人 -->
|
||||
<select id="selectEnrollmentYearByStudentId" resultType="java.lang.Long">
|
||||
SELECT COALESCE(c.enrollment_year, s.enrollment_year)
|
||||
FROM xg_student_msg s
|
||||
LEFT JOIN xg_class_msg c ON s.class_id = c.id AND c.deleted = 0
|
||||
WHERE s.id = #{studentId}
|
||||
AND s.deleted = 0
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 根据学院ID和角色Key查询具备该角色的用户列表 -->
|
||||
<select id="selectUserIdsByCollegeIdAndRoleKey" resultType="java.lang.Long">
|
||||
SELECT DISTINCT u.user_id
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
-- =============================================================================
|
||||
-- 生产环境:一年级请假代理学院(人文学院)配置
|
||||
-- 日期:2026-09-16
|
||||
-- 配套代码:一年级请假时,二级学院审批人 / 分管领导改走 sys_config 配置的学院
|
||||
-- 销假流程无需执行本脚本
|
||||
-- =============================================================================
|
||||
-- 执行顺序:
|
||||
-- 1)先跑「一、核对」全部 SELECT,确认人文学院 dept_id、审批人、分管领导
|
||||
-- 2)若 1.1 的 dept_id 不是 202512231307170003,先改「二」里 INSERT/UPDATE 的 config_value
|
||||
-- 3)再执行「二、写入参数」
|
||||
-- 4)部署新后端并重启(或刷新系统参数缓存)
|
||||
-- =============================================================================
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 一、核对(只读,请先执行并人工确认)
|
||||
-- -----------------------------------------------------------------------------
|
||||
|
||||
-- 1.1 人文学院 dept_id(生产参考:202512231307170003 / xy-19,以本查询为准)
|
||||
SELECT dept_id,
|
||||
dept_name,
|
||||
dept_category,
|
||||
parent_id,
|
||||
status,
|
||||
del_flag
|
||||
FROM sys_dept
|
||||
WHERE dept_name = '人文学院'
|
||||
AND del_flag = '0';
|
||||
|
||||
-- 1.2 是否已存在配置
|
||||
SELECT config_id, config_key, config_value, remark
|
||||
FROM sys_config
|
||||
WHERE config_key = 'xg.studentLeave.freshmanProxyCollegeId';
|
||||
|
||||
-- 1.3 人文学院请假二级学院审批人(role_key = xsqj-ejxyspr)必须有人,否则一年级无法提交
|
||||
-- 将 @proxy_college_id 换成 1.1 查到的 dept_id
|
||||
SET @proxy_college_id = 202512231307170003;
|
||||
|
||||
SELECT u.user_id,
|
||||
u.user_name,
|
||||
u.nick_name,
|
||||
d.dept_id,
|
||||
d.dept_name,
|
||||
r.role_key
|
||||
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 = @proxy_college_id OR FIND_IN_SET(@proxy_college_id, d.ancestors));
|
||||
|
||||
-- 1.4 人文学院分管领导(xg_college_leader)必须有人,否则一年级长假无法提交
|
||||
SELECT id, college_id, college_name, leader_id, leader_name, deleted
|
||||
FROM xg_college_leader
|
||||
WHERE college_id = @proxy_college_id
|
||||
AND deleted = 0;
|
||||
|
||||
-- 1.5 入学年缺失的在籍学生(提交请假会被系统拒绝,建议上线前处理)
|
||||
SELECT s.id,
|
||||
s.student_no,
|
||||
s.name,
|
||||
s.enrollment_year AS student_enrollment_year,
|
||||
c.id AS class_id,
|
||||
c.class_name,
|
||||
c.enrollment_year AS class_enrollment_year
|
||||
FROM xg_student_msg s
|
||||
LEFT JOIN xg_class_msg c ON s.class_id = c.id AND c.deleted = 0
|
||||
WHERE s.deleted = 0
|
||||
AND IFNULL(s.student_status, '1') = '1'
|
||||
AND COALESCE(c.enrollment_year, s.enrollment_year) IS NULL
|
||||
LIMIT 200;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 二、写入系统参数(确认 1.1 的 dept_id 后执行)
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- !! 若生产人文学院 dept_id 与下方不一致,请先替换两处 '202512231307170003'
|
||||
|
||||
INSERT INTO sys_config (
|
||||
config_id,
|
||||
tenant_id,
|
||||
config_name,
|
||||
config_key,
|
||||
config_value,
|
||||
config_type,
|
||||
create_dept,
|
||||
create_by,
|
||||
create_time,
|
||||
remark
|
||||
)
|
||||
SELECT
|
||||
2026091601,
|
||||
'000000',
|
||||
'一年级请假代理学院ID',
|
||||
'xg.studentLeave.freshmanProxyCollegeId',
|
||||
'202512231307170003',
|
||||
'N',
|
||||
103,
|
||||
1,
|
||||
NOW(),
|
||||
'一年级学生请假时,二级学院审批人与分管领导改走此人文学院 dept_id;每年9月1日按入学年切届'
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM sys_config WHERE config_key = 'xg.studentLeave.freshmanProxyCollegeId'
|
||||
);
|
||||
|
||||
-- 若参数已存在但值不对,执行下面 UPDATE(按需取消注释并改 dept_id)
|
||||
-- UPDATE sys_config
|
||||
-- SET config_value = '202512231307170003',
|
||||
-- update_by = 1,
|
||||
-- update_time = NOW(),
|
||||
-- remark = '一年级学生请假时,二级学院审批人与分管领导改走此人文学院 dept_id;每年9月1日按入学年切届'
|
||||
-- WHERE config_key = 'xg.studentLeave.freshmanProxyCollegeId';
|
||||
|
||||
-- 写入后复查
|
||||
SELECT config_id, config_key, config_value, remark
|
||||
FROM sys_config
|
||||
WHERE config_key = 'xg.studentLeave.freshmanProxyCollegeId';
|
||||
|
||||
-- 完成后:部署本次后端代码并重启应用(或刷新系统参数缓存)
|
||||
Reference in new issue
Block a user