Commit 040a1bcfad61bb6083dd6dae2f869fed312f56b4
1 parent
e7815dd7
【代码评审】工作流:连续多级部门负责人的实现
Showing
5 changed files
with
44 additions
and
39 deletions
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateAbstractDeptLeaderStrategy.java
| ... | ... | @@ -6,10 +6,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCand |
| 6 | 6 | import cn.iocoder.yudao.module.system.api.dept.DeptApi; |
| 7 | 7 | import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; |
| 8 | 8 | |
| 9 | -import java.util.Collections; | |
| 10 | -import java.util.LinkedHashSet; | |
| 11 | -import java.util.List; | |
| 12 | -import java.util.Set; | |
| 9 | +import java.util.*; | |
| 13 | 10 | |
| 14 | 11 | /** |
| 15 | 12 | * 部门的负责人 {@link BpmTaskCandidateStrategy} 抽象类 |
| ... | ... | @@ -25,44 +22,43 @@ public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy implements BpmT |
| 25 | 22 | } |
| 26 | 23 | |
| 27 | 24 | /** |
| 28 | - * 获取上级部门的负责人 | |
| 25 | + * 获得指定层级的部门负责人,只有第 level 的负责人 | |
| 29 | 26 | * |
| 30 | - * @param assignDept 指定部门 | |
| 31 | - * @param level 第几级 | |
| 32 | - * @return 部门负责人 Id | |
| 27 | + * @param dept 指定部门 | |
| 28 | + * @param level 第几级 | |
| 29 | + * @return 部门负责人的编号 | |
| 33 | 30 | */ |
| 34 | - protected Long getAssignLevelDeptLeaderId(DeptRespDTO assignDept, Integer level) { | |
| 31 | + protected Long getAssignLevelDeptLeaderId(DeptRespDTO dept, Integer level) { | |
| 35 | 32 | Assert.isTrue(level > 0, "level 必须大于 0"); |
| 36 | - if (assignDept == null) { | |
| 33 | + if (dept == null) { | |
| 37 | 34 | return null; |
| 38 | 35 | } |
| 39 | - DeptRespDTO dept = assignDept; | |
| 36 | + DeptRespDTO currentDept = dept; | |
| 40 | 37 | for (int i = 1; i < level; i++) { |
| 41 | - DeptRespDTO parentDept = deptApi.getDept(dept.getParentId()); | |
| 38 | + DeptRespDTO parentDept = deptApi.getDept(currentDept.getParentId()); | |
| 42 | 39 | if (parentDept == null) { // 找不到父级部门,到了最高级。返回最高级的部门负责人 |
| 43 | 40 | break; |
| 44 | 41 | } |
| 45 | - dept = parentDept; | |
| 42 | + currentDept = parentDept; | |
| 46 | 43 | } |
| 47 | - return dept.getLeaderUserId(); | |
| 44 | + return currentDept.getLeaderUserId(); | |
| 48 | 45 | } |
| 49 | 46 | |
| 50 | 47 | /** |
| 51 | - * 获取连续上级部门的负责人, 包含指定部门的负责人 | |
| 48 | + * 获得连续层级的部门负责人,包含 [1, level] 的负责人 | |
| 52 | 49 | * |
| 53 | - * @param assignDeptIds 指定部门 Ids | |
| 54 | - * @param level 第几级 | |
| 50 | + * @param deptIds 指定部门编号数组 | |
| 51 | + * @param level 最大层级 | |
| 55 | 52 | * @return 连续部门负责人 Id |
| 56 | 53 | */ |
| 57 | - protected Set<Long> getMultiLevelDeptLeaderIds(List<Long> assignDeptIds, Integer level) { | |
| 54 | + protected Set<Long> getMultiLevelDeptLeaderIds(List<Long> deptIds, Integer level) { | |
| 58 | 55 | Assert.isTrue(level > 0, "level 必须大于 0"); |
| 59 | - if (CollUtil.isEmpty(assignDeptIds)) { | |
| 60 | - return Collections.emptySet(); | |
| 56 | + if (CollUtil.isEmpty(deptIds)) { | |
| 57 | + return new HashSet<>(); | |
| 61 | 58 | } |
| 62 | 59 | Set<Long> deptLeaderIds = new LinkedHashSet<>(); // 保证有序 |
| 63 | - DeptRespDTO dept; | |
| 64 | - for (Long deptId : assignDeptIds) { | |
| 65 | - dept = deptApi.getDept(deptId); | |
| 60 | + for (Long deptId : deptIds) { | |
| 61 | + DeptRespDTO dept = deptApi.getDept(deptId); | |
| 66 | 62 | for (int i = 0; i < level; i++) { |
| 67 | 63 | if (dept.getLeaderUserId() != null) { |
| 68 | 64 | deptLeaderIds.add(dept.getLeaderUserId()); | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateMultiLevelDeptLeaderStrategy.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateDeptLeaderMultiStrategy.java
| ... | ... | @@ -18,20 +18,21 @@ import java.util.Set; |
| 18 | 18 | * @author jason |
| 19 | 19 | */ |
| 20 | 20 | @Component |
| 21 | -public class BpmTaskCandidateMultiLevelDeptLeaderStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy { | |
| 21 | +public class BpmTaskCandidateDeptLeaderMultiStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy { | |
| 22 | 22 | |
| 23 | - public BpmTaskCandidateMultiLevelDeptLeaderStrategy(DeptApi deptApi) { | |
| 23 | + public BpmTaskCandidateDeptLeaderMultiStrategy(DeptApi deptApi) { | |
| 24 | 24 | super(deptApi); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | @Override |
| 28 | 28 | public BpmTaskCandidateStrategyEnum getStrategy() { |
| 29 | - return BpmTaskCandidateStrategyEnum.MULTI_LEVEL_DEPT_LEADER; | |
| 29 | + return BpmTaskCandidateStrategyEnum.MULTI_DEPT_LEADER_MULTI; | |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | @Override |
| 33 | 33 | public void validateParam(String param) { |
| 34 | - // 参数格式: ,分割。前面的部门Id. 可以为多个。 最后一个为部门层级 | |
| 34 | + // TODO @jason:是不是可以 | 分隔 deptId 数组,和 level;这样后续可以加更多的参数。 | |
| 35 | + // 参数格式: , 分割。前面的部门编号,可以为多个。最后一个为部门层级 | |
| 35 | 36 | List<Long> params = StrUtils.splitToLong(param, ","); |
| 36 | 37 | List<List<Long>> splitList = CollUtil.split(params, params.size() - 1); |
| 37 | 38 | Assert.isTrue(splitList.size() == 2, "参数格式不匹配"); |
| ... | ... | @@ -41,6 +42,7 @@ public class BpmTaskCandidateMultiLevelDeptLeaderStrategy extends BpmTaskCandida |
| 41 | 42 | |
| 42 | 43 | @Override |
| 43 | 44 | public Set<Long> calculateUsers(DelegateExecution execution, String param) { |
| 45 | + // TODO @jason:是不是可以 | 分隔 deptId 数组,和 level;这样后续可以加更多的参数。 | |
| 44 | 46 | // 参数格式: ,分割。前面的部门Id. 可以为多个。 最后一个为部门层级 |
| 45 | 47 | List<Long> params = StrUtils.splitToLong(param, ","); |
| 46 | 48 | List<List<Long>> splitList = CollUtil.split(params, params.size() - 1); | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy.java renamed to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateStartUserDeptLeaderMultiStrategy.java
| ... | ... | @@ -15,7 +15,7 @@ import org.flowable.engine.runtime.ProcessInstance; |
| 15 | 15 | import org.springframework.context.annotation.Lazy; |
| 16 | 16 | import org.springframework.stereotype.Component; |
| 17 | 17 | |
| 18 | -import java.util.Collections; | |
| 18 | +import java.util.HashSet; | |
| 19 | 19 | import java.util.Set; |
| 20 | 20 | |
| 21 | 21 | import static cn.hutool.core.collection.ListUtil.toList; |
| ... | ... | @@ -26,7 +26,7 @@ import static cn.hutool.core.collection.ListUtil.toList; |
| 26 | 26 | * @author jason |
| 27 | 27 | */ |
| 28 | 28 | @Component |
| 29 | -public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy { | |
| 29 | +public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy { | |
| 30 | 30 | |
| 31 | 31 | @Resource |
| 32 | 32 | @Lazy |
| ... | ... | @@ -35,13 +35,13 @@ public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTa |
| 35 | 35 | @Resource |
| 36 | 36 | private AdminUserApi adminUserApi; |
| 37 | 37 | |
| 38 | - public BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy(DeptApi deptApi) { | |
| 38 | + public BpmTaskCandidateStartUserDeptLeaderMultiStrategy(DeptApi deptApi) { | |
| 39 | 39 | super(deptApi); |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | @Override |
| 43 | 43 | public BpmTaskCandidateStrategyEnum getStrategy() { |
| 44 | - return BpmTaskCandidateStrategyEnum.START_USER_MULTI_LEVEL_DEPT_LEADER; | |
| 44 | + return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER_MULTI; | |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | @Override |
| ... | ... | @@ -55,9 +55,10 @@ public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTa |
| 55 | 55 | // 获得流程发起人 |
| 56 | 56 | ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId()); |
| 57 | 57 | Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); |
| 58 | + // 获取发起人的 multi 部门负责人 | |
| 58 | 59 | DeptRespDTO dept = getStartUserDept(startUserId); |
| 59 | 60 | if (dept == null) { |
| 60 | - return Collections.emptySet(); | |
| 61 | + return new HashSet<>(); | |
| 61 | 62 | } |
| 62 | 63 | return getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级 |
| 63 | 64 | } | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateStartUserDeptLeaderStrategy.java
| ... | ... | @@ -15,10 +15,10 @@ import org.flowable.engine.runtime.ProcessInstance; |
| 15 | 15 | import org.springframework.context.annotation.Lazy; |
| 16 | 16 | import org.springframework.stereotype.Component; |
| 17 | 17 | |
| 18 | +import java.util.HashSet; | |
| 18 | 19 | import java.util.Set; |
| 19 | 20 | |
| 20 | 21 | import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; |
| 21 | -import static java.util.Collections.emptySet; | |
| 22 | 22 | |
| 23 | 23 | /** |
| 24 | 24 | * 发起人的部门负责人, 可以是上级部门负责人 {@link BpmTaskCandidateStrategy} 实现类 |
| ... | ... | @@ -27,11 +27,14 @@ import static java.util.Collections.emptySet; |
| 27 | 27 | */ |
| 28 | 28 | @Component |
| 29 | 29 | public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy { |
| 30 | + | |
| 30 | 31 | @Resource |
| 31 | - @Lazy | |
| 32 | + @Lazy // 避免循环依赖 | |
| 32 | 33 | private BpmProcessInstanceService processInstanceService; |
| 34 | + | |
| 33 | 35 | @Resource |
| 34 | 36 | private AdminUserApi adminUserApi; |
| 37 | + | |
| 35 | 38 | @Override |
| 36 | 39 | public BpmTaskCandidateStrategyEnum getStrategy() { |
| 37 | 40 | return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER; |
| ... | ... | @@ -52,10 +55,13 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidat |
| 52 | 55 | // 获得流程发起人 |
| 53 | 56 | ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId()); |
| 54 | 57 | Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); |
| 55 | - | |
| 58 | + // 获取发起人的部门负责人 | |
| 56 | 59 | DeptRespDTO dept = getStartUserDept(startUserId); |
| 60 | + if (dept == null) { | |
| 61 | + return new HashSet<>(); | |
| 62 | + } | |
| 57 | 63 | Long deptLeaderId = getAssignLevelDeptLeaderId(dept, Integer.valueOf(param)); // 参数是部门的层级 |
| 58 | - return deptLeaderId != null ? asSet(deptLeaderId) : emptySet(); | |
| 64 | + return deptLeaderId != null ? asSet(deptLeaderId) : new HashSet<>(); | |
| 59 | 65 | } |
| 60 | 66 | |
| 61 | 67 | /** | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmTaskCandidateStrategyEnum.java
| ... | ... | @@ -21,13 +21,13 @@ public enum BpmTaskCandidateStrategyEnum implements IntArrayValuable { |
| 21 | 21 | ROLE(10, "角色"), |
| 22 | 22 | DEPT_MEMBER(20, "部门的成员"), // 包括负责人 |
| 23 | 23 | DEPT_LEADER(21, "部门的负责人"), |
| 24 | - MULTI_LEVEL_DEPT_LEADER(23, "连续多级部门的负责人"), | |
| 24 | + MULTI_DEPT_LEADER_MULTI(23, "连续多级部门的负责人"), | |
| 25 | 25 | POST(22, "岗位"), |
| 26 | 26 | USER(30, "用户"), |
| 27 | 27 | START_USER_SELECT(35, "发起人自选"), // 申请人自己,可在提交申请时选择此节点的审批人 |
| 28 | 28 | START_USER(36, "发起人自己"), // 申请人自己, 一般紧挨开始节点,常用于发起人信息审核场景 |
| 29 | - START_USER_DEPT_LEADER(37, "发起人部门负责人"), // 可以是发起人上级部门负责人 | |
| 30 | - START_USER_MULTI_LEVEL_DEPT_LEADER(38, "发起人连续多级部门的负责人"), | |
| 29 | + START_USER_DEPT_LEADER(37, "发起人部门负责人"), | |
| 30 | + START_USER_DEPT_LEADER_MULTI(38, "发起人连续多级部门的负责人"), | |
| 31 | 31 | USER_GROUP(40, "用户组"), |
| 32 | 32 | EXPRESSION(60, "流程表达式"), // 表达式 ExpressionManager |
| 33 | 33 | ASSIGN_EMPTY(1, "审批人为空"), | ... | ... |