Commit 20c97d14413380fb668a836502440803c9685a06

Authored by jason
1 parent 0d738fa3

仿钉钉流程设计- 连续多级部门负责人, 支持选多个部门

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateAbstractDeptLeaderStrategy.java
1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy; 1 package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
4 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; 5 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
5 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 6 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
@@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; @@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
7 8
8 import java.util.Collections; 9 import java.util.Collections;
9 import java.util.LinkedHashSet; 10 import java.util.LinkedHashSet;
  11 +import java.util.List;
10 import java.util.Set; 12 import java.util.Set;
11 13
12 /** 14 /**
@@ -26,7 +28,7 @@ public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy implements BpmT @@ -26,7 +28,7 @@ public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy implements BpmT
26 * 获取上级部门的负责人 28 * 获取上级部门的负责人
27 * 29 *
28 * @param assignDept 指定部门 30 * @param assignDept 指定部门
29 - * @param level 第几级 31 + * @param level 第几级
30 * @return 部门负责人 Id 32 * @return 部门负责人 Id
31 */ 33 */
32 protected Long getAssignLevelDeptLeaderId(DeptRespDTO assignDept, Integer level) { 34 protected Long getAssignLevelDeptLeaderId(DeptRespDTO assignDept, Integer level) {
@@ -48,26 +50,29 @@ public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy implements BpmT @@ -48,26 +50,29 @@ public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy implements BpmT
48 /** 50 /**
49 * 获取连续上级部门的负责人, 包含指定部门的负责人 51 * 获取连续上级部门的负责人, 包含指定部门的负责人
50 * 52 *
51 - * @param assignDept 指定部门  
52 - * @param level 第几级 53 + * @param assignDeptIds 指定部门 Ids
  54 + * @param level 第几级
53 * @return 连续部门负责人 Id 55 * @return 连续部门负责人 Id
54 */ 56 */
55 - protected Set<Long> getMultiLevelDeptLeaderIds(DeptRespDTO assignDept, Integer level){ 57 + protected Set<Long> getMultiLevelDeptLeaderIds(List<Long> assignDeptIds, Integer level) {
56 Assert.isTrue(level > 0, "level 必须大于 0"); 58 Assert.isTrue(level > 0, "level 必须大于 0");
57 - if (assignDept == null) { 59 + if (CollUtil.isEmpty(assignDeptIds)) {
58 return Collections.emptySet(); 60 return Collections.emptySet();
59 } 61 }
60 Set<Long> deptLeaderIds = new LinkedHashSet<>(); // 保证有序 62 Set<Long> deptLeaderIds = new LinkedHashSet<>(); // 保证有序
61 - DeptRespDTO dept = assignDept;  
62 - for (int i = 0; i < level; i++) {  
63 - if (dept.getLeaderUserId() != null) {  
64 - deptLeaderIds.add(dept.getLeaderUserId()); 63 + DeptRespDTO dept;
  64 + for (Long deptId : assignDeptIds) {
  65 + dept = deptApi.getDept(deptId);
  66 + for (int i = 0; i < level; i++) {
  67 + if (dept.getLeaderUserId() != null) {
  68 + deptLeaderIds.add(dept.getLeaderUserId());
  69 + }
  70 + DeptRespDTO parentDept = deptApi.getDept(dept.getParentId());
  71 + if (parentDept == null) { // 找不到父级部门. 已经到了最高层级了
  72 + break;
  73 + }
  74 + dept = parentDept;
65 } 75 }
66 - DeptRespDTO parentDept = deptApi.getDept(dept.getParentId());  
67 - if (parentDept == null) { // 找不到父级部门. 已经到了最高层级了  
68 - break;  
69 - }  
70 - dept = parentDept;  
71 } 76 }
72 return deptLeaderIds; 77 return deptLeaderIds;
73 } 78 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateMultiLevelDeptLeaderStrategy.java
@@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils; @@ -6,7 +6,6 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils;
6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy; 6 import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
7 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum; 7 import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
8 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 8 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
9 -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;  
10 import org.flowable.engine.delegate.DelegateExecution; 9 import org.flowable.engine.delegate.DelegateExecution;
11 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
12 11
@@ -32,22 +31,21 @@ public class BpmTaskCandidateMultiLevelDeptLeaderStrategy extends BpmTaskCandida @@ -32,22 +31,21 @@ public class BpmTaskCandidateMultiLevelDeptLeaderStrategy extends BpmTaskCandida
32 31
33 @Override 32 @Override
34 public void validateParam(String param) { 33 public void validateParam(String param) {
35 - // 参数格式: ,分割。 前面一个指定指定部门Id, 后面一个是部门的层级 34 + // 参数格式: ,分割。前面的部门Id. 可以为多个。 最后一个为部门层级
36 List<Long> params = StrUtils.splitToLong(param, ","); 35 List<Long> params = StrUtils.splitToLong(param, ",");
37 - Assert.isTrue(params.size() == 2, "参数格式不匹配");  
38 - deptApi.validateDeptList(CollUtil.toList(params.get(0)));  
39 - Assert.isTrue(params.get(1) > 0, "部门层级必须大于 0"); 36 + List<List<Long>> splitList = CollUtil.split(params, params.size() - 1);
  37 + Assert.isTrue(splitList.size() == 2, "参数格式不匹配");
  38 + deptApi.validateDeptList(splitList.get(0));
  39 + Assert.isTrue(splitList.get(1).get(0) > 0, "部门层级必须大于 0");
40 } 40 }
41 41
42 @Override 42 @Override
43 public Set<Long> calculateUsers(DelegateExecution execution, String param) { 43 public Set<Long> calculateUsers(DelegateExecution execution, String param) {
44 - // 参数格式: ,分割。 前面一个指定指定部门Id, 后面一个是审批的层级 44 + // 参数格式: ,分割。前面的部门Id. 可以为多个。 最后一个为部门层级
45 List<Long> params = StrUtils.splitToLong(param, ","); 45 List<Long> params = StrUtils.splitToLong(param, ",");
46 - // TODO @芋艿 是否要支持多个部门。 是不是这种场景,一个部门就可以了  
47 - Long deptId = params.get(0);  
48 - Long level = params.get(1);  
49 - DeptRespDTO dept = deptApi.getDept(deptId);  
50 - return getMultiLevelDeptLeaderIds(dept, level.intValue()); 46 + List<List<Long>> splitList = CollUtil.split(params, params.size() - 1);
  47 + Long level = splitList.get(1).get(0);
  48 + return getMultiLevelDeptLeaderIds(splitList.get(0), level.intValue());
51 } 49 }
52 50
53 } 51 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy.java
@@ -15,8 +15,11 @@ import org.flowable.engine.runtime.ProcessInstance; @@ -15,8 +15,11 @@ import org.flowable.engine.runtime.ProcessInstance;
15 import org.springframework.context.annotation.Lazy; 15 import org.springframework.context.annotation.Lazy;
16 import org.springframework.stereotype.Component; 16 import org.springframework.stereotype.Component;
17 17
  18 +import java.util.Collections;
18 import java.util.Set; 19 import java.util.Set;
19 20
  21 +import static cn.hutool.core.collection.ListUtil.toList;
  22 +
20 /** 23 /**
21 * 发起人连续多级部门的负责人 {@link BpmTaskCandidateStrategy} 实现类 24 * 发起人连续多级部门的负责人 {@link BpmTaskCandidateStrategy} 实现类
22 * 25 *
@@ -52,9 +55,11 @@ public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTa @@ -52,9 +55,11 @@ public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTa
52 // 获得流程发起人 55 // 获得流程发起人
53 ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId()); 56 ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
54 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); 57 Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
55 -  
56 DeptRespDTO dept = getStartUserDept(startUserId); 58 DeptRespDTO dept = getStartUserDept(startUserId);
57 - return getMultiLevelDeptLeaderIds(dept, Integer.valueOf(param)); // 参数是部门的层级 59 + if (dept == null) {
  60 + return Collections.emptySet();
  61 + }
  62 + return getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
58 } 63 }
59 64
60 /** 65 /**