Przeglądaj źródła

仿钉钉流程设计- 简化多人审批方式

jason 1 rok temu
rodzic
commit
d7e1b87b1b

+ 5 - 7
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmApproveMethodEnum.java

@@ -6,7 +6,7 @@ import lombok.Getter;
 
 // TODO @芋艿:审批方式的名字,可能要看下;
 /**
- * BPM 审批方式的枚举
+ * BPM 多人审批方式的枚举
  *
  * @author jason
  */
@@ -14,12 +14,10 @@ import lombok.Getter;
 @AllArgsConstructor
 public enum BpmApproveMethodEnum {
 
-    SINGLE_PERSON_APPROVE(1, "单人审批"),
-    ALL_APPROVE(2, "多人会签(需所有审批人同意)"), // 会签
-    APPROVE_BY_RATIO(3, "多人会签(按通过比例)"), // 会签(按通过比例)
-    ANY_APPROVE_ALL_REJECT(4, "多人会签(通过只需一人,拒绝需要全员)"), // 会签(通过只需一人,拒绝需要全员)
-    ANY_APPROVE(5, "多人或签(一名审批人通过即可)"), // 或签(通过只需一人,拒绝只需一人)
-    SEQUENTIAL_APPROVE(6, "依次审批"); // 依次审批
+    RANDOM_SELECT_ONE_APPROVE(1, "随机挑选一人审批"),
+    APPROVE_BY_RATIO(2, "多人会签(按通过比例)"), // 会签(按通过比例)
+    ANY_APPROVE(3, "多人或签(一人通过或拒绝)"), // 或签(通过只需一人,拒绝只需一人)
+    SEQUENTIAL_APPROVE(4, "依次审批"); // 依次审批
 
     /**
      * 审批方式

+ 23 - 24
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/custom/expression/CompleteByRejectCountExpression.java

@@ -15,7 +15,6 @@ import org.springframework.stereotype.Component;
 import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT;
 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum.APPROVE_BY_RATIO;
 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_METHOD;
 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_RATIO;
@@ -41,46 +40,46 @@ public class CompleteByRejectCountExpression {
         // 审批方式
         Integer approveMethod = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_APPROVE_METHOD));
         Assert.notNull(approveMethod, "审批方式不能空");
-        // 计算拒绝的人数
-        // TODO @jason:CollUtil.filter().size();貌似可以更简洁
+        if (!Objects.equals(APPROVE_BY_RATIO.getMethod(), approveMethod)) {
+            log.error("[completionCondition] the execution is [{}] 审批方式[{}] 不匹配", execution, approveMethod);
+            throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION);
+        }
+        // 获取拒绝人数
+        // TODO @jason:CollUtil.filter().size();貌似可以更简洁 @芋艿 CollUtil.filter().size() 使用这个会报错,好坑了.
         Integer rejectCount = CollectionUtils.getSumValue(execution.getExecutions(),
                 item -> Objects.equals(BpmTaskStatusEnum.REJECT.getStatus(), item.getVariableLocal(BpmConstants.TASK_VARIABLE_STATUS, Integer.class)) ? 1 : 0,
                 Integer::sum, 0);
-        // 同意的人数为 完成人数 - 拒绝人数
+         // 同意人数: 完成人数 - 拒绝人数
         int agreeCount = nrOfCompletedInstances - rejectCount;
-        // 1. 多人会签(通过只需一人,拒绝需要全员)
-        if (Objects.equals(ANY_APPROVE_ALL_REJECT.getMethod(), approveMethod)) {
-            // 1.1 一人同意. 会签任务完成
-            if (agreeCount > 0) {
+        // 多人会签(按通过比例)
+        Integer approveRatio = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_APPROVE_RATIO));
+        Assert.notNull(approveRatio, "通过比例不能空");
+        if (Objects.equals(100, approveRatio)) {
+            // 所有人都同意
+            if (agreeCount == nrOfInstances) {
                 return true;
-            } else {
-                // 1.2 所有人都拒绝了。设置任务拒绝变量, 会签任务完成。 后续终止流程在 ServiceTask【MultiInstanceServiceTaskExpression】处理
-                if (Objects.equals(nrOfInstances, rejectCount)) {
-                    execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE);
-                    return true;
-                }
-                return false;
             }
-        } else if (Objects.equals(APPROVE_BY_RATIO.getMethod(), approveMethod)) {
-            Integer approveRatio = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_APPROVE_RATIO));
-            Assert.notNull(approveRatio, "通过比例不能空");
-            double approvePct =  approveRatio / (double) 100;
-            double realApprovePct = (double) agreeCount / nrOfInstances;
+            // 一个人拒绝了
+            if (rejectCount > 0) {
+                execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE);
+                return true;
+            }
+        } else {
             // 判断通过比例
+            double approvePct = approveRatio / (double) 100;
+            double realApprovePct = (double) agreeCount / nrOfInstances;
             if (realApprovePct >= approvePct) {
                 return true;
             }
-            double rejectPct =  (100 - approveRatio) / (double) 100;
+            double rejectPct = (100 - approveRatio) / (double) 100;
             double realRejectPct = (double) rejectCount / nrOfInstances;
             // 判断拒绝比例
             if (realRejectPct >= rejectPct) {
                 execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE);
                 return true;
             }
-            return false;
         }
-        log.error("[completionCondition] 按拒绝人数计算会签的完成条件的审批方式[{}],配置有误", approveMethod);
-        throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION);
+        return false;
     }
 
 }

+ 2 - 8
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java

@@ -506,7 +506,7 @@ public class SimpleModelUtils {
 
     private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, Integer approveRatio, UserTask userTask) {
         BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
-        if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) {
+        if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.RANDOM_SELECT_ONE_APPROVE) {
             return;
         }
         // 添加审批方式的扩展属性
@@ -515,10 +515,7 @@ public class SimpleModelUtils {
         MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics();
         //  设置 collectionVariable。本系统用不到。会在 仅仅为了校验。
         multiInstanceCharacteristics.setInputDataItem("${coll_userList}");
-        if (bpmApproveMethodEnum == BpmApproveMethodEnum.ALL_APPROVE) {
-            multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
-            multiInstanceCharacteristics.setSequential(false);
-        } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE) {
+        if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE) {
             multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION);
             multiInstanceCharacteristics.setSequential(false);
             userTask.setLoopCharacteristics(multiInstanceCharacteristics);
@@ -527,9 +524,6 @@ public class SimpleModelUtils {
             multiInstanceCharacteristics.setSequential(true);
             multiInstanceCharacteristics.setLoopCardinality("1");
             userTask.setLoopCharacteristics(multiInstanceCharacteristics);
-        } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT ){
-            multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION);
-            multiInstanceCharacteristics.setSequential(false);
         } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.APPROVE_BY_RATIO) {
             multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION);
             multiInstanceCharacteristics.setSequential(false);