From 6b4d61ae4acf9bcd7d9dfaa95303a1676077b735 Mon Sep 17 00:00:00 2001 From: "962704835@qq.com" Date: Fri, 21 Nov 2025 21:37:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A5=E4=BC=8D=E4=BF=9D=E7=95=99=E5=AD=A6?= =?UTF-8?q?=E7=B1=8D=E7=94=B3=E8=AF=B7-=E7=9B=91=E5=90=AC=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApprovalAssigneeListener.java | 138 ++------------ .../StartApprovalAssigneeListener.java | 177 ++++++++++++++++++ .../impl/RtEnlistmentReserveServiceImpl.java | 2 +- 3 files changed, 189 insertions(+), 128 deletions(-) create mode 100644 srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/StartApprovalAssigneeListener.java diff --git a/srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/ApprovalAssigneeListener.java b/srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/ApprovalAssigneeListener.java index bdee1a8..19aea53 100644 --- a/srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/ApprovalAssigneeListener.java +++ b/srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/ApprovalAssigneeListener.java @@ -36,12 +36,6 @@ public class ApprovalAssigneeListener implements ExecutionListener { @Autowired private ISysUserService sysUserService; // 用户服务(查询部门/学院负责人) -// @Autowired -// private FlowBusinessService enlistmentReserveMapper; // 业务表Mapper - - @Autowired - private HistoryService historyService; // Flowable历史服务 - // 用于查询流程定义中的节点信息 @Autowired private RepositoryService repositoryService; @@ -76,11 +70,17 @@ public class ApprovalAssigneeListener implements ExecutionListener { approvalResult = num.longValue(); } - // 4. 后续逻辑不变:查询下一个节点负责人并更新变量 - Long nextAssigneeId = getNextAssignee(currentNodeName, processInstanceId, enlistmentId, currentActivityId, approvalOpinion, approvalResult); - if (nextAssigneeId != null) { - execution.setVariable("approval", nextAssigneeId); - execution.setVariable("currentNode", currentNodeName); + // 添加审批记录 + EnlistmentReserveMapper rtEnlistmentReserveMapper = (EnlistmentReserveMapper) SpringUtils.getBean(EnlistmentReserveMapper.class); + // 根据Id查询入伍申请记录 + EnlistmentReserve enlistmentReserve = rtEnlistmentReserveMapper.selectRtEnlistmentReserveById(enlistmentId); + saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion, approvalResult); + + // 如果到了最后一个审批人,则修改申请表审核状态 + if (currentNodeName.equals("教务处主管领导审批")){ + // 改变申请表中的审核状态(审核通过) + enlistmentReserve.setApplyStatus(2L); + rtEnlistmentReserveMapper.updateRtEnlistmentReserve(enlistmentReserve); } } @@ -99,122 +99,6 @@ public class ApprovalAssigneeListener implements ExecutionListener { return flowNode != null ? flowNode.getName() : null; } - /** - * 根据当前节点查询下一个节点的负责人 - */ - private Long getNextAssignee(String currentNodeName, String processInstanceId, Long enlistmentId, String currentActivityId, String approvalOpinion, Long approvalResult) { - EnlistmentReserveMapper rtEnlistmentReserveMapper = (EnlistmentReserveMapper) SpringUtils.getBean(EnlistmentReserveMapper.class); - // 根据Id查询入伍申请记录 - EnlistmentReserve enlistmentReserve = rtEnlistmentReserveMapper.selectRtEnlistmentReserveById(enlistmentId); - // 根据学生学号来获取对应辅导员的信息 - TeacherVo counselorInfo = rtEnlistmentReserveMapper.getCounselorInfo(enlistmentReserve.getStudentNo()); - // 获取辅导员的部门id - Long currentDeptId = counselorInfo.getDeptId(); - if (currentDeptId == null) { - throw new RuntimeException("未分配部门,无法匹配负责人"); - } - // 注意:节点名称需与BPMN模型中完全一致(区分大小写) - switch (currentNodeName) { - case "辅导员审批": - // 辅导员通过后 → 下一个节点:学务(筛选出角色ID=105,且与当前部门一致) - // 查询角色ID=105(学务)的所有用户 - SysUser queryUser = new SysUser(); - queryUser.setRoleId(105L); // 学务角色固定ID - List academicAffairsUsers = sysUserService.selectAllocatedList(queryUser); - if (academicAffairsUsers.isEmpty()) { - throw new RuntimeException("未查询到角色(学务)的用户"); - } - - // 从学务用户中筛选出部门ID与当前辅导员部门一致的用户 - SysUser targetAcademic = academicAffairsUsers.stream() - .filter(user -> currentDeptId.equals(user.getDeptId())) // 部门ID匹配 - .findFirst() // 取第一个匹配的学务(若有多个,可根据排序或优先级调整) - .orElseThrow(() -> new RuntimeException("未找到部门ID=" + currentDeptId + "的学务负责人")); - - // 添加审批记录 - saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion, approvalResult); - - // 返回匹配的学务用户ID(作为下一个节点负责人) - return targetAcademic.getUserId(); - - case "学务审批": - // 学务通过后 → 下一个节点:二级学院(角色ID=106,匹配学生所属学院) - // 查询当前流程对应的业务数据(获取学生所属学院ID) -// RtEnlistmentReserve reserve = enlistmentReserveMapper.selectRtEnlistmentReserveByProcessInstanceId(processInstanceId); -// if (reserve == null) { -// throw new RuntimeException("未查询到流程对应的业务数据,processInstanceId=" + processInstanceId); -// } - - // 查询角色ID=106(二级学院)的所有用户 - SysUser qUser = new SysUser(); - qUser.setRoleId(106L); // 二级学院角色固定ID=106 - List collegeUsers = sysUserService.selectAllocatedList(qUser); - if (collegeUsers.isEmpty()) { - throw new RuntimeException("未查询到角色(二级学院)的用户"); - } - - // 筛选出部门ID(学院ID)与登录用户所属学院一致的二级学院负责人 - SysUser targetCollegeLeader = collegeUsers.stream() - .filter(user -> currentDeptId.equals(user.getDeptId())) // 学院ID匹配(部门ID即学院ID) - .findFirst() - .orElseThrow(() -> new RuntimeException("未找到学院ID=" + currentDeptId + "的二级学院负责人(角色ID=106)")); - - - // 添加审批记录 - saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion, approvalResult); - - // 返回匹配的二级学院负责人ID - return targetCollegeLeader.getUserId(); - - case "二级学院审批": - // 二级学院通过后 → 下一个节点:学籍管理科 - - // 获取学籍管理科审核人 - List shenDataInfo = rtEnlistmentReserveMapper.getShenDataInfo("学籍管理科"); - - if (shenDataInfo.isEmpty()) { - throw new RuntimeException("未查询到对应的用户"); - } - - // 添加审批记录 - saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion, approvalResult); - - // 暂时选择学籍管理科第一个人作为审核人 - return shenDataInfo.get(0).getUserId(); - - case "学籍管理科审批": - // 学籍管理科通过后 → 下一个节点:教务处主管领导(假设部门ID=40) - - // 获取学教务处主管领导审核人 - List teacherVos = rtEnlistmentReserveMapper.getShenDataInfo("教务处主管领导"); - - if (teacherVos.isEmpty()) { - throw new RuntimeException("未查询到对应的用户"); - } - - // 添加审批记录 - saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion, approvalResult); - // 暂时选择教务处主管领导第一个人作为审核人 - return teacherVos.get(0).getUserId(); - - case "教务处主管领导审批": - // 最后一个节点通过后 → 流程结束(无需设置负责人) - - - // 添加审批记录 - saveApprovalRecord(enlistmentReserve.getId(), enlistmentReserve.getProcessInstanceId(),currentActivityId,currentNodeName, enlistmentReserve.getStudentName(), enlistmentReserve.getStudentNo(), approvalOpinion, approvalResult); - - // 改变申请表中的审核状态(审核通过) - enlistmentReserve.setApplyStatus(2L); - rtEnlistmentReserveMapper.updateRtEnlistmentReserve(enlistmentReserve); - - return null; - - default: - throw new RuntimeException("未配置节点[" + currentNodeName + "]的下一个负责人规则"); - } - } - /** * 通用审批记录保存方法 */ diff --git a/srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/StartApprovalAssigneeListener.java b/srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/StartApprovalAssigneeListener.java new file mode 100644 index 0000000..ae55c20 --- /dev/null +++ b/srs-flowable/src/main/java/com/srs/flowable/listener/enlistmentReserve/StartApprovalAssigneeListener.java @@ -0,0 +1,177 @@ +package com.srs.flowable.listener.enlistmentReserve; + +import com.srs.common.core.domain.entity.SysUser; + + +import com.srs.common.doman.vo.TeacherVo; +import com.srs.common.utils.SecurityUtils; +import com.srs.common.utils.spring.SpringUtils; +import com.srs.flowable.domain.EnlistmentReserve; +import com.srs.flowable.domain.EnlistmentReserveApproval; +import com.srs.flowable.mapper.EnlistmentReserveApprovalMapper; +import com.srs.flowable.mapper.EnlistmentReserveMapper; +import com.srs.system.service.ISysUserService; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.engine.HistoryService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ExecutionListener; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Date; +import java.util.List; + + +/** + * 审批流程负责人自动流转监听器 + * 用于节点审批之前时,更新下一个节点的负责人变量(approval) + */ +@Component("startApprovalAssigneeListener") // Spring Bean名称,与BPMN表达式对应 +public class StartApprovalAssigneeListener implements ExecutionListener { + + @Autowired + private ISysUserService sysUserService; // 用户服务(查询部门/学院负责人) + + // 用于查询流程定义中的节点信息 + @Autowired + private RepositoryService repositoryService; + + @Override + public void notify(DelegateExecution execution) { + // 1. 获取当前节点ID和流程定义ID + String currentActivityId = execution.getCurrentActivityId(); // 当前节点ID(兼容所有版本) + String processDefinitionId = execution.getProcessDefinitionId(); // 流程定义ID + + // 2. 根据节点ID查询节点名称(核心修正:通过流程定义获取名称) + String currentNodeName = getNodeNameByActivityId(processDefinitionId, currentActivityId); + if (currentNodeName == null) { + throw new RuntimeException("未找到节点ID=" + currentActivityId + "的名称"); + } + + // 获取申请表id + Long enlistmentId = Long.valueOf(execution.getVariable("enlistmentId").toString()); + + + // 后续逻辑不变:查询下一个节点负责人并更新变量 + Long nextAssigneeId = getNextAssignee(currentNodeName, enlistmentId); + if (nextAssigneeId != null) { + execution.setVariable("approval", nextAssigneeId); + execution.setVariable("currentNode", currentNodeName); + } + } + + /** + * 根据节点ID和流程定义ID,查询节点名称(兼容所有版本的核心方法) + */ + private String getNodeNameByActivityId(String processDefinitionId, String activityId) { + // 获取流程模型 + BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId); + if (bpmnModel == null) { + throw new RuntimeException("未找到流程定义ID=" + processDefinitionId + "的模型"); + } + + // 从模型中获取节点信息(FlowNode包含用户任务、网关等节点) + FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(activityId); + return flowNode != null ? flowNode.getName() : null; + } + + /** + * 根据当前节点查询下一个节点的负责人 + */ + private Long getNextAssignee(String currentNodeName, Long enlistmentId) { + EnlistmentReserveMapper rtEnlistmentReserveMapper = (EnlistmentReserveMapper) SpringUtils.getBean(EnlistmentReserveMapper.class); + // 根据Id查询入伍申请记录 + EnlistmentReserve enlistmentReserve = rtEnlistmentReserveMapper.selectRtEnlistmentReserveById(enlistmentId); + // 根据学生学号来获取对应辅导员的信息 + TeacherVo counselorInfo = rtEnlistmentReserveMapper.getCounselorInfo(enlistmentReserve.getStudentNo()); + // 获取辅导员的部门id + Long currentDeptId = counselorInfo.getDeptId(); + if (currentDeptId == null) { + throw new RuntimeException("未分配部门,无法匹配负责人"); + } + // 注意:节点名称需与BPMN模型中完全一致(区分大小写) + switch (currentNodeName) { + case "辅导员审批": + // 辅导员开始审批前 → 找到对应辅导员 + // 返回匹配的辅导员用户ID(作为当前节点负责人) + return counselorInfo.getUserId(); + + case "学务审批": + + // 学务开始审批前 → 找到对应学务 + // 查询角色ID=105(学务)的所有用户 + SysUser queryUser = new SysUser(); + queryUser.setRoleId(105L); // 学务角色固定ID + List academicAffairsUsers = sysUserService.selectAllocatedList(queryUser); + if (academicAffairsUsers.isEmpty()) { + throw new RuntimeException("未查询到角色(学务)的用户"); + } + + // 从学务用户中筛选出部门ID与当前辅导员部门一致的用户 + SysUser targetAcademic = academicAffairsUsers.stream() + .filter(user -> currentDeptId.equals(user.getDeptId())) // 部门ID匹配 + .findFirst() // 取第一个匹配的学务(若有多个,可根据排序或优先级调整) + .orElseThrow(() -> new RuntimeException("未找到部门ID=" + currentDeptId + "的学务负责人")); + + + // 返回匹配的学务用户ID(作为当前节点负责人) + return targetAcademic.getUserId(); + + case "二级学院审批": + + // 二级学院开始审批前 → 找到对应二级学院 + // 查询角色ID=106(二级学院)的所有用户 + SysUser qUser = new SysUser(); + qUser.setRoleId(106L); // 二级学院角色固定ID=106 + List collegeUsers = sysUserService.selectAllocatedList(qUser); + if (collegeUsers.isEmpty()) { + throw new RuntimeException("未查询到角色(二级学院)的用户"); + } + + // 筛选出部门ID(学院ID)与登录用户所属学院一致的二级学院负责人 + SysUser targetCollegeLeader = collegeUsers.stream() + .filter(user -> currentDeptId.equals(user.getDeptId())) // 学院ID匹配(部门ID即学院ID) + .findFirst() + .orElseThrow(() -> new RuntimeException("未找到学院ID=" + currentDeptId + "的二级学院负责人(角色ID=106)")); + + + // 返回匹配的二级学院负责人ID + return targetCollegeLeader.getUserId(); + + case "学籍管理科审批": + + // 学籍管理科开始审批前 → 找到对应学籍管理科 + + // 获取学籍管理科审核人 + List shenDataInfo = rtEnlistmentReserveMapper.getShenDataInfo("学籍管理科"); + + if (shenDataInfo.isEmpty()) { + throw new RuntimeException("未查询到对应的用户"); + } + + + // 暂时选择学籍管理科第一个人作为审核人 + return shenDataInfo.get(0).getUserId(); + + case "教务处主管领导审批": + // 教务处主管领导开始审批前 → 找到对应教务处主管领导 + + // 获取学教务处主管领导审核人 + List teacherVos = rtEnlistmentReserveMapper.getShenDataInfo("教务处主管领导"); + + if (teacherVos.isEmpty()) { + throw new RuntimeException("未查询到对应的用户"); + } + + // 暂时选择教务处主管领导第一个人作为审核人 + return teacherVos.get(0).getUserId(); + + default: + throw new RuntimeException("未配置节点[" + currentNodeName + "]的当前负责人规则"); + } + } +} \ No newline at end of file diff --git a/srs-routine/src/main/java/com/srs/routine/service/impl/RtEnlistmentReserveServiceImpl.java b/srs-routine/src/main/java/com/srs/routine/service/impl/RtEnlistmentReserveServiceImpl.java index 046925c..3e3d236 100644 --- a/srs-routine/src/main/java/com/srs/routine/service/impl/RtEnlistmentReserveServiceImpl.java +++ b/srs-routine/src/main/java/com/srs/routine/service/impl/RtEnlistmentReserveServiceImpl.java @@ -209,7 +209,7 @@ public class RtEnlistmentReserveServiceImpl extends ServiceImpl