Browse Source

【代码评审】工作流:连续多级部门负责人的实现

YunaiV 11 months ago
parent
commit
040a1bcfad

+ 19 - 23
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
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
 
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  * 部门的负责人 {@link BpmTaskCandidateStrategy} 抽象类
@@ -25,44 +22,43 @@ public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy implements BpmT
     }
 
     /**
-     * 获取上级部门的负责人
+     * 获得指定层级的部门负责人,只有第 level 的负责人
      *
-     * @param assignDept 指定部门
-     * @param level      第几级
-     * @return 部门负责人 Id
+     * @param dept 指定部门
+     * @param level 第几级
+     * @return 部门负责人的编号
      */
-    protected Long getAssignLevelDeptLeaderId(DeptRespDTO assignDept, Integer level) {
+    protected Long getAssignLevelDeptLeaderId(DeptRespDTO dept, Integer level) {
         Assert.isTrue(level > 0, "level 必须大于 0");
-        if (assignDept == null) {
+        if (dept == null) {
             return null;
         }
-        DeptRespDTO dept = assignDept;
+        DeptRespDTO currentDept = dept;
         for (int i = 1; i < level; i++) {
-            DeptRespDTO parentDept = deptApi.getDept(dept.getParentId());
+            DeptRespDTO parentDept = deptApi.getDept(currentDept.getParentId());
             if (parentDept == null) { // 找不到父级部门,到了最高级。返回最高级的部门负责人
                 break;
             }
-            dept = parentDept;
+            currentDept = parentDept;
         }
-        return dept.getLeaderUserId();
+        return currentDept.getLeaderUserId();
     }
 
     /**
-     * 获取连续上级部门的负责人, 包含指定部门的负责人
+     * 获得连续层级的部门负责人,包含 [1, level] 的负责人
      *
-     * @param assignDeptIds 指定部门 Ids
-     * @param level         第几
+     * @param deptIds 指定部门编号数组
+     * @param level 最大层
      * @return 连续部门负责人 Id
      */
-    protected Set<Long> getMultiLevelDeptLeaderIds(List<Long> assignDeptIds, Integer level) {
+    protected Set<Long> getMultiLevelDeptLeaderIds(List<Long> deptIds, Integer level) {
         Assert.isTrue(level > 0, "level 必须大于 0");
-        if (CollUtil.isEmpty(assignDeptIds)) {
-            return Collections.emptySet();
+        if (CollUtil.isEmpty(deptIds)) {
+            return new HashSet<>();
         }
         Set<Long> deptLeaderIds = new LinkedHashSet<>(); // 保证有序
-        DeptRespDTO dept;
-        for (Long deptId : assignDeptIds) {
-            dept = deptApi.getDept(deptId);
+        for (Long deptId : deptIds) {
+            DeptRespDTO dept = deptApi.getDept(deptId);
             for (int i = 0; i < level; i++) {
                 if (dept.getLeaderUserId() != null) {
                     deptLeaderIds.add(dept.getLeaderUserId());

+ 6 - 4
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateMultiLevelDeptLeaderStrategy.java → 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;
  * @author jason
  */
 @Component
-public class BpmTaskCandidateMultiLevelDeptLeaderStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
+public class BpmTaskCandidateDeptLeaderMultiStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
 
-    public BpmTaskCandidateMultiLevelDeptLeaderStrategy(DeptApi deptApi) {
+    public BpmTaskCandidateDeptLeaderMultiStrategy(DeptApi deptApi) {
         super(deptApi);
     }
 
     @Override
     public BpmTaskCandidateStrategyEnum getStrategy() {
-        return BpmTaskCandidateStrategyEnum.MULTI_LEVEL_DEPT_LEADER;
+        return BpmTaskCandidateStrategyEnum.MULTI_DEPT_LEADER_MULTI;
     }
 
     @Override
     public void validateParam(String param) {
-        // 参数格式: ,分割。前面的部门Id. 可以为多个。 最后一个为部门层级
+        // TODO @jason:是不是可以 | 分隔 deptId 数组,和 level;这样后续可以加更多的参数。
+        // 参数格式: , 分割。前面的部门编号,可以为多个。最后一个为部门层级
         List<Long> params = StrUtils.splitToLong(param, ",");
         List<List<Long>> splitList = CollUtil.split(params, params.size() - 1);
         Assert.isTrue(splitList.size() == 2, "参数格式不匹配");
@@ -41,6 +42,7 @@ public class BpmTaskCandidateMultiLevelDeptLeaderStrategy extends BpmTaskCandida
 
     @Override
     public Set<Long> calculateUsers(DelegateExecution execution, String param) {
+        // TODO @jason:是不是可以 | 分隔 deptId 数组,和 level;这样后续可以加更多的参数。
         // 参数格式: ,分割。前面的部门Id. 可以为多个。 最后一个为部门层级
         List<Long> params = StrUtils.splitToLong(param, ",");
         List<List<Long>> splitList = CollUtil.split(params, params.size() - 1);

+ 6 - 5
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/candidate/strategy/BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy.java → 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;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
 
-import java.util.Collections;
+import java.util.HashSet;
 import java.util.Set;
 
 import static cn.hutool.core.collection.ListUtil.toList;
@@ -26,7 +26,7 @@ import static cn.hutool.core.collection.ListUtil.toList;
  * @author jason
  */
 @Component
-public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
+public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
 
     @Resource
     @Lazy
@@ -35,13 +35,13 @@ public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTa
     @Resource
     private AdminUserApi adminUserApi;
 
-    public BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy(DeptApi deptApi) {
+    public BpmTaskCandidateStartUserDeptLeaderMultiStrategy(DeptApi deptApi) {
         super(deptApi);
     }
 
     @Override
     public BpmTaskCandidateStrategyEnum getStrategy() {
-        return BpmTaskCandidateStrategyEnum.START_USER_MULTI_LEVEL_DEPT_LEADER;
+        return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER_MULTI;
     }
 
     @Override
@@ -55,9 +55,10 @@ public class BpmTaskCandidateStartUserMultiLevelDeptLeaderStrategy extends BpmTa
         // 获得流程发起人
         ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
         Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
+        // 获取发起人的 multi 部门负责人
         DeptRespDTO dept = getStartUserDept(startUserId);
         if (dept == null) {
-           return Collections.emptySet();
+           return new HashSet<>();
         }
         return getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
     }

+ 10 - 4
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;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Component;
 
+import java.util.HashSet;
 import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
-import static java.util.Collections.emptySet;
 
 /**
  * 发起人的部门负责人, 可以是上级部门负责人 {@link BpmTaskCandidateStrategy} 实现类
@@ -27,11 +27,14 @@ import static java.util.Collections.emptySet;
  */
 @Component
 public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
+
     @Resource
-    @Lazy
+    @Lazy // 避免循环依赖
     private BpmProcessInstanceService processInstanceService;
+
     @Resource
     private AdminUserApi adminUserApi;
+
     @Override
     public BpmTaskCandidateStrategyEnum getStrategy() {
         return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER;
@@ -52,10 +55,13 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidat
         // 获得流程发起人
         ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
         Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
-
+        // 获取发起人的部门负责人
         DeptRespDTO dept = getStartUserDept(startUserId);
+        if (dept == null) {
+            return new HashSet<>();
+        }
         Long deptLeaderId =  getAssignLevelDeptLeaderId(dept, Integer.valueOf(param)); // 参数是部门的层级
-        return deptLeaderId != null ? asSet(deptLeaderId) : emptySet();
+        return deptLeaderId != null ? asSet(deptLeaderId) : new HashSet<>();
     }
 
     /**

+ 3 - 3
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 {
     ROLE(10, "角色"),
     DEPT_MEMBER(20, "部门的成员"), // 包括负责人
     DEPT_LEADER(21, "部门的负责人"),
-    MULTI_LEVEL_DEPT_LEADER(23, "连续多级部门的负责人"),
+    MULTI_DEPT_LEADER_MULTI(23, "连续多级部门的负责人"),
     POST(22, "岗位"),
     USER(30, "用户"),
     START_USER_SELECT(35, "发起人自选"), // 申请人自己,可在提交申请时选择此节点的审批人
     START_USER(36, "发起人自己"), // 申请人自己, 一般紧挨开始节点,常用于发起人信息审核场景
-    START_USER_DEPT_LEADER(37, "发起人部门负责人"), // 可以是发起人上级部门负责人
-    START_USER_MULTI_LEVEL_DEPT_LEADER(38, "发起人连续多级部门的负责人"),
+    START_USER_DEPT_LEADER(37, "发起人部门负责人"),
+    START_USER_DEPT_LEADER_MULTI(38, "发起人连续多级部门的负责人"),
     USER_GROUP(40, "用户组"),
     EXPRESSION(60, "流程表达式"), // 表达式 ExpressionManager
     ASSIGN_EMPTY(1, "审批人为空"),