From 922c8b834e7792befbb1564de44cb6820bcf6dc9 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 30 Aug 2026 17:23:01 +0800 Subject: [PATCH] fix(bpm): 使用流程变量发起人 ID计算部门负责人 --- yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/AbstractBpmTaskCandidateDeptLeaderStrategy.java | 16 ++++++++++++++++ yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java | 4 ++-- yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategy.java | 9 +++++---- yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java | 12 ++++++++++++ yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest.java | 16 +++++++++++++--- yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategyTest.java | 16 +++++++++++++--- yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtilsTest.java | 24 ++++++++++++++++++++++++ 7 files changed, 85 insertions(+), 12 deletions(-) diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/AbstractBpmTaskCandidateDeptLeaderStrategy.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/AbstractBpmTaskCandidateDeptLeaderStrategy.java index cac3498..ae375d1 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/AbstractBpmTaskCandidateDeptLeaderStrategy.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/AbstractBpmTaskCandidateDeptLeaderStrategy.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.d import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -88,4 +89,19 @@ public abstract class AbstractBpmTaskCandidateDeptLeaderStrategy implements BpmT return deptApi.getDept(startUser.getDeptId()); } + /** + * 获取发起人的部门(优先使用流程变量中的发起人编号) + * + * @param startUserId 发起人 Id(流程变量不存在时使用) + * @param processVariables 流程变量 + * @return 发起人的部门 + */ + protected DeptRespDTO getStartUserDept(Long startUserId, Map processVariables) { + Long processStartUserId = FlowableUtils.getProcessInstanceStartUserId(processVariables); + if (processStartUserId != null && processStartUserId > 0) { + startUserId = processStartUserId; + } + return getStartUserDept(startUserId); + } + } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java index 00da98b..efd1675 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java @@ -49,7 +49,7 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends AbstractBp ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId()); Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); // 获取发起人的 multi 部门负责人 - DeptRespDTO dept = super.getStartUserDept(startUserId); + DeptRespDTO dept = super.getStartUserDept(startUserId, processInstance.getProcessVariables()); if (dept == null) { return new HashSet<>(); } @@ -60,7 +60,7 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends AbstractBp public Set calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param, Long startUserId, String processDefinitionId, Map processVariables) { int level = Integer.parseInt(param); // 参数是部门的层级 - DeptRespDTO dept = super.getStartUserDept(startUserId); + DeptRespDTO dept = super.getStartUserDept(startUserId, processVariables); if (dept == null) { return new HashSet<>(); } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategy.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategy.java index 115bb3c..86a01f9 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategy.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategy.java @@ -48,19 +48,20 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends AbstractBpmTask ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId()); Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); // 获取发起人的部门负责人 - return getStartUserDeptLeader(startUserId, param); + return getStartUserDeptLeader(startUserId, param, processInstance.getProcessVariables()); } @Override public Set calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param, Long startUserId, String processDefinitionId, Map processVariables) { // 获取发起人的部门负责人 - return getStartUserDeptLeader(startUserId, param); + return getStartUserDeptLeader(startUserId, param, processVariables); } - private Set getStartUserDeptLeader(Long startUserId, String param) { + private Set getStartUserDeptLeader(Long startUserId, String param, + Map processVariables) { int level = Integer.parseInt(param); // 参数是部门的层级 - DeptRespDTO dept = super.getStartUserDept(startUserId); + DeptRespDTO dept = super.getStartUserDept(startUserId, processVariables); if (dept == null) { return new HashSet<>(); } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java index fc21f70..89b2328 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.util; +import cn.hutool.core.convert.Convert; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; @@ -134,6 +135,17 @@ public class FlowableUtils { } /** + * 获得流程实例的发起用户 ID + * + * @param processVariables 流程实例的 variables + * @return 发起用户 ID + */ + public static Long getProcessInstanceStartUserId(Map processVariables) { + return processVariables == null ? null : Convert.toLong( + processVariables.get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID)); + } + + /** * 获得流程实例的审批原因 * * @param processInstance 流程实例 diff --git a/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest.java b/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest.java index 2f66a83..68b1e86 100644 --- a/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest.java +++ b/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; @@ -14,6 +15,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.stubbing.Answer; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; @@ -42,12 +45,16 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest extends BaseMo String param = "2"; // mock 方法(获得流程发起人) Long startUserId = 1L; + Long processVariableStartUserId = 2L; ProcessInstance processInstance = mock(ProcessInstance.class); DelegateExecution execution = mock(DelegateExecution.class); when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance); when(processInstance.getStartUserId()).thenReturn(startUserId.toString()); + Map processVariables = new HashMap<>(); + processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId); + when(processInstance.getProcessVariables()).thenReturn(processVariables); // mock 方法(获取发起人的 multi 部门负责人) - mockGetStartUserDept(startUserId); + mockGetStartUserDept(processVariableStartUserId); // 调用 Set userIds = strategy.calculateUsersByTask(execution, param); @@ -61,11 +68,14 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest extends BaseMo String param = "2"; // mock 方法 Long startUserId = 1L; - mockGetStartUserDept(startUserId); + Long processVariableStartUserId = 2L; + Map processVariables = new HashMap<>(); + processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId); + mockGetStartUserDept(processVariableStartUserId); // 调用 Set userIds = strategy.calculateUsersByActivity(null, null, param, - startUserId, null, null); + startUserId, null, processVariables); // 断言 assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds); } diff --git a/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategyTest.java b/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategyTest.java index a5f863f..48db3c7 100644 --- a/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategyTest.java +++ b/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/dept/BpmTaskCandidateStartUserDeptLeaderStrategyTest.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept; import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; @@ -14,6 +15,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.stubbing.Answer; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; @@ -42,12 +45,16 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategyTest extends BaseMockito String param = "2"; // mock 方法(获得流程发起人) Long startUserId = 1L; + Long processVariableStartUserId = 2L; ProcessInstance processInstance = mock(ProcessInstance.class); DelegateExecution execution = mock(DelegateExecution.class); when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance); when(processInstance.getStartUserId()).thenReturn(startUserId.toString()); + Map processVariables = new HashMap<>(); + processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId); + when(processInstance.getProcessVariables()).thenReturn(processVariables); // mock 方法(获取发起人的部门负责人) - mockGetStartUserDeptLeader(startUserId); + mockGetStartUserDeptLeader(processVariableStartUserId); // 调用 Set userIds = strategy.calculateUsersByTask(execution, param); @@ -61,11 +68,14 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategyTest extends BaseMockito String param = "2"; // mock 方法 Long startUserId = 1L; - mockGetStartUserDeptLeader(startUserId); + Long processVariableStartUserId = 2L; + Map processVariables = new HashMap<>(); + processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId); + mockGetStartUserDeptLeader(processVariableStartUserId); // 调用 Set userIds = strategy.calculateUsersByActivity(null, null, param, - startUserId, null, null); + startUserId, null, processVariables); // 断言 assertEquals(Sets.newLinkedHashSet(1001L), userIds); } diff --git a/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtilsTest.java b/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtilsTest.java index e1bebe1..67da990 100644 --- a/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtilsTest.java +++ b/yudao-module-bpm/src/test/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtilsTest.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -23,6 +24,29 @@ import static org.junit.jupiter.api.Assertions.assertNull; class FlowableUtilsTest { @Test + public void testGetProcessInstanceStartUserId() { + // 准备参数 + Map processVariables = new HashMap<>(); + processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, "1"); + + // 调用 + Long startUserId = FlowableUtils.getProcessInstanceStartUserId(processVariables); + + // 断言 + assertEquals(1L, startUserId); + } + + @Test + public void testGetProcessInstanceStartUserId_empty() { + // 准备参数 + Map processVariables = new HashMap<>(); + + // 调用 & 断言 + assertNull(FlowableUtils.getProcessInstanceStartUserId(processVariables)); + assertNull(FlowableUtils.getProcessInstanceStartUserId(null)); + } + + @Test public void testGetSummary_customSummary_parseDbFormFields() { // 准备参数:模拟 DB 中 form_fields 字段,列表里每个元素都是一个 form-create 字段 JSON。 BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionInfo(dbFormFields(), -- libgit2 0.21.4