Commit d7e1b87b1bb4322ed67900988423c97448bbe805

Authored by jason
1 parent 7423f9dd

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

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;
6 6  
7 7 // TODO @芋艿:审批方式的名字,可能要看下;
8 8 /**
9   - * BPM 审批方式的枚举
  9 + * BPM 多人审批方式的枚举
10 10 *
11 11 * @author jason
12 12 */
... ... @@ -14,12 +14,10 @@ import lombok.Getter;
14 14 @AllArgsConstructor
15 15 public enum BpmApproveMethodEnum {
16 16  
17   - SINGLE_PERSON_APPROVE(1, "单人审批"),
18   - ALL_APPROVE(2, "多人会签(需所有审批人同意)"), // 会签
19   - APPROVE_BY_RATIO(3, "多人会签(按通过比例)"), // 会签(按通过比例)
20   - ANY_APPROVE_ALL_REJECT(4, "多人会签(通过只需一人,拒绝需要全员)"), // 会签(通过只需一人,拒绝需要全员)
21   - ANY_APPROVE(5, "多人或签(一名审批人通过即可)"), // 或签(通过只需一人,拒绝只需一人)
22   - SEQUENTIAL_APPROVE(6, "依次审批"); // 依次审批
  17 + RANDOM_SELECT_ONE_APPROVE(1, "随机挑选一人审批"),
  18 + APPROVE_BY_RATIO(2, "多人会签(按通过比例)"), // 会签(按通过比例)
  19 + ANY_APPROVE(3, "多人或签(一人通过或拒绝)"), // 或签(通过只需一人,拒绝只需一人)
  20 + SEQUENTIAL_APPROVE(4, "依次审批"); // 依次审批
23 21  
24 22 /**
25 23 * 审批方式
... ...
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;
15 15 import java.util.Objects;
16 16  
17 17 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
18   -import static cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT;
19 18 import static cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum.APPROVE_BY_RATIO;
20 19 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_METHOD;
21 20 import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_RATIO;
... ... @@ -41,46 +40,46 @@ public class CompleteByRejectCountExpression {
41 40 // 审批方式
42 41 Integer approveMethod = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_APPROVE_METHOD));
43 42 Assert.notNull(approveMethod, "审批方式不能空");
44   - // 计算拒绝的人数
45   - // TODO @jason:CollUtil.filter().size();貌似可以更简洁
  43 + if (!Objects.equals(APPROVE_BY_RATIO.getMethod(), approveMethod)) {
  44 + log.error("[completionCondition] the execution is [{}] 审批方式[{}] 不匹配", execution, approveMethod);
  45 + throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION);
  46 + }
  47 + // 获取拒绝人数
  48 + // TODO @jason:CollUtil.filter().size();貌似可以更简洁 @芋艿 CollUtil.filter().size() 使用这个会报错,好坑了.
46 49 Integer rejectCount = CollectionUtils.getSumValue(execution.getExecutions(),
47 50 item -> Objects.equals(BpmTaskStatusEnum.REJECT.getStatus(), item.getVariableLocal(BpmConstants.TASK_VARIABLE_STATUS, Integer.class)) ? 1 : 0,
48 51 Integer::sum, 0);
49   - // 同意的人数为 完成人数 - 拒绝人数
  52 + // 同意人数: 完成人数 - 拒绝人数
50 53 int agreeCount = nrOfCompletedInstances - rejectCount;
51   - // 1. 多人会签(通过只需一人,拒绝需要全员)
52   - if (Objects.equals(ANY_APPROVE_ALL_REJECT.getMethod(), approveMethod)) {
53   - // 1.1 一人同意. 会签任务完成
54   - if (agreeCount > 0) {
  54 + // 多人会签(按通过比例)
  55 + Integer approveRatio = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_APPROVE_RATIO));
  56 + Assert.notNull(approveRatio, "通过比例不能空");
  57 + if (Objects.equals(100, approveRatio)) {
  58 + // 所有人都同意
  59 + if (agreeCount == nrOfInstances) {
55 60 return true;
56   - } else {
57   - // 1.2 所有人都拒绝了。设置任务拒绝变量, 会签任务完成。 后续终止流程在 ServiceTask【MultiInstanceServiceTaskExpression】处理
58   - if (Objects.equals(nrOfInstances, rejectCount)) {
59   - execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE);
60   - return true;
61   - }
62   - return false;
63 61 }
64   - } else if (Objects.equals(APPROVE_BY_RATIO.getMethod(), approveMethod)) {
65   - Integer approveRatio = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_APPROVE_RATIO));
66   - Assert.notNull(approveRatio, "通过比例不能空");
67   - double approvePct = approveRatio / (double) 100;
68   - double realApprovePct = (double) agreeCount / nrOfInstances;
  62 + // 一个人拒绝了
  63 + if (rejectCount > 0) {
  64 + execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE);
  65 + return true;
  66 + }
  67 + } else {
69 68 // 判断通过比例
  69 + double approvePct = approveRatio / (double) 100;
  70 + double realApprovePct = (double) agreeCount / nrOfInstances;
70 71 if (realApprovePct >= approvePct) {
71 72 return true;
72 73 }
73   - double rejectPct = (100 - approveRatio) / (double) 100;
  74 + double rejectPct = (100 - approveRatio) / (double) 100;
74 75 double realRejectPct = (double) rejectCount / nrOfInstances;
75 76 // 判断拒绝比例
76 77 if (realRejectPct >= rejectPct) {
77 78 execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE);
78 79 return true;
79 80 }
80   - return false;
81 81 }
82   - log.error("[completionCondition] 按拒绝人数计算会签的完成条件的审批方式[{}],配置有误", approveMethod);
83   - throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION);
  82 + return false;
84 83 }
85 84  
86 85 }
... ...
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 {
506 506  
507 507 private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, Integer approveRatio, UserTask userTask) {
508 508 BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
509   - if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) {
  509 + if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.RANDOM_SELECT_ONE_APPROVE) {
510 510 return;
511 511 }
512 512 // 添加审批方式的扩展属性
... ... @@ -515,10 +515,7 @@ public class SimpleModelUtils {
515 515 MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics();
516 516 // 设置 collectionVariable。本系统用不到。会在 仅仅为了校验。
517 517 multiInstanceCharacteristics.setInputDataItem("${coll_userList}");
518   - if (bpmApproveMethodEnum == BpmApproveMethodEnum.ALL_APPROVE) {
519   - multiInstanceCharacteristics.setCompletionCondition(ALL_APPROVE_COMPLETE_EXPRESSION);
520   - multiInstanceCharacteristics.setSequential(false);
521   - } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE) {
  518 + if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE) {
522 519 multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION);
523 520 multiInstanceCharacteristics.setSequential(false);
524 521 userTask.setLoopCharacteristics(multiInstanceCharacteristics);
... ... @@ -527,9 +524,6 @@ public class SimpleModelUtils {
527 524 multiInstanceCharacteristics.setSequential(true);
528 525 multiInstanceCharacteristics.setLoopCardinality("1");
529 526 userTask.setLoopCharacteristics(multiInstanceCharacteristics);
530   - } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT ){
531   - multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION);
532   - multiInstanceCharacteristics.setSequential(false);
533 527 } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.APPROVE_BY_RATIO) {
534 528 multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION);
535 529 multiInstanceCharacteristics.setSequential(false);
... ...