Commit 5c2fcdce1554d1d6a9267bf308dbe8a289538e90
1 parent
12108e73
仿钉钉流程设计- 会签按通过比率
Showing
5 changed files
with
42 additions
and
9 deletions
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmApproveMethodEnum.java
| @@ -16,7 +16,7 @@ public enum BpmApproveMethodEnum { | @@ -16,7 +16,7 @@ public enum BpmApproveMethodEnum { | ||
| 16 | 16 | ||
| 17 | SINGLE_PERSON_APPROVE(1, "单人审批"), | 17 | SINGLE_PERSON_APPROVE(1, "单人审批"), |
| 18 | ALL_APPROVE(2, "多人会签(需所有审批人同意)"), // 会签 | 18 | ALL_APPROVE(2, "多人会签(需所有审批人同意)"), // 会签 |
| 19 | - APPROVE_BY_RATIO(3, "多人会签(按比例投票)"), // 会签(按比例投票) | 19 | + APPROVE_BY_RATIO(3, "多人会签(按通过比例)"), // 会签(按通过比例) |
| 20 | ANY_APPROVE_ALL_REJECT(4, "多人会签(通过只需一人,拒绝需要全员)"), // 会签(通过只需一人,拒绝需要全员) | 20 | ANY_APPROVE_ALL_REJECT(4, "多人会签(通过只需一人,拒绝需要全员)"), // 会签(通过只需一人,拒绝需要全员) |
| 21 | ANY_APPROVE(5, "多人或签(一名审批人通过即可)"), // 或签(通过只需一人,拒绝只需一人) | 21 | ANY_APPROVE(5, "多人或签(一名审批人通过即可)"), // 或签(通过只需一人,拒绝只需一人) |
| 22 | SEQUENTIAL_APPROVE(6, "依次审批"); // 依次审批 | 22 | SEQUENTIAL_APPROVE(6, "依次审批"); // 依次审批 |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/enums/BpmnModelConstants.java
| @@ -56,6 +56,11 @@ public interface BpmnModelConstants { | @@ -56,6 +56,11 @@ public interface BpmnModelConstants { | ||
| 56 | String USER_TASK_APPROVE_METHOD = "approveMethod"; | 56 | String USER_TASK_APPROVE_METHOD = "approveMethod"; |
| 57 | 57 | ||
| 58 | /** | 58 | /** |
| 59 | + * BPMN UserTask 的扩展属性,当审批方式为按通过比例时, 标记会签通过比例 | ||
| 60 | + */ | ||
| 61 | + String USER_TASK_APPROVE_RATIO = "approveRatio"; | ||
| 62 | + | ||
| 63 | + /** | ||
| 59 | * BPMN ExtensionElement 的扩展属性,用于标记 服务任务附属的用户任务 Id | 64 | * BPMN ExtensionElement 的扩展属性,用于标记 服务任务附属的用户任务 Id |
| 60 | */ | 65 | */ |
| 61 | String SERVICE_TASK_ATTACH_USER_TASK_ID = "attachUserTaskId"; | 66 | String SERVICE_TASK_ATTACH_USER_TASK_ID = "attachUserTaskId"; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/expression/CompleteByRejectCountExpression.java
| @@ -16,7 +16,9 @@ import java.util.Objects; | @@ -16,7 +16,9 @@ import java.util.Objects; | ||
| 16 | 16 | ||
| 17 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 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; | 18 | import static cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT; |
| 19 | +import static cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum.APPROVE_BY_RATIO; | ||
| 19 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_METHOD; | 20 | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_METHOD; |
| 21 | +import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_RATIO; | ||
| 20 | 22 | ||
| 21 | /** | 23 | /** |
| 22 | * 按拒绝人数计算会签的完成条件的流程表达式实现 | 24 | * 按拒绝人数计算会签的完成条件的流程表达式实现 |
| @@ -28,7 +30,7 @@ import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnMode | @@ -28,7 +30,7 @@ import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnMode | ||
| 28 | public class CompleteByRejectCountExpression { | 30 | public class CompleteByRejectCountExpression { |
| 29 | 31 | ||
| 30 | /** | 32 | /** |
| 31 | - * 会签的完成条件 | 33 | + * 会签的完成条件 |
| 32 | */ | 34 | */ |
| 33 | public boolean completionCondition(DelegateExecution execution) { | 35 | public boolean completionCondition(DelegateExecution execution) { |
| 34 | FlowElement flowElement = execution.getCurrentFlowElement(); | 36 | FlowElement flowElement = execution.getCurrentFlowElement(); |
| @@ -53,13 +55,29 @@ public class CompleteByRejectCountExpression { | @@ -53,13 +55,29 @@ public class CompleteByRejectCountExpression { | ||
| 53 | } else { | 55 | } else { |
| 54 | // 1.2 所有人都拒绝了。设置任务拒绝变量, 会签任务完成。 后续终止流程在 ServiceTask【MultiInstanceServiceTaskExpression】处理 | 56 | // 1.2 所有人都拒绝了。设置任务拒绝变量, 会签任务完成。 后续终止流程在 ServiceTask【MultiInstanceServiceTaskExpression】处理 |
| 55 | if (Objects.equals(nrOfInstances, rejectCount)) { | 57 | if (Objects.equals(nrOfInstances, rejectCount)) { |
| 56 | - execution.setVariable(String.format("%s_reject",flowElement.getId()), Boolean.TRUE); | 58 | + execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE); |
| 57 | return true; | 59 | return true; |
| 58 | } | 60 | } |
| 59 | return false; | 61 | return false; |
| 60 | } | 62 | } |
| 63 | + } else if (Objects.equals(APPROVE_BY_RATIO.getMethod(), approveMethod)) { | ||
| 64 | + Integer approveRatio = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_APPROVE_RATIO)); | ||
| 65 | + Assert.notNull(approveRatio, "通过比例不能空"); | ||
| 66 | + double approvePct = approveRatio / (double) 100; | ||
| 67 | + double realApprovePct = (double) agreeCount / nrOfInstances; | ||
| 68 | + // 判断通过比例 | ||
| 69 | + if (realApprovePct >= approvePct) { | ||
| 70 | + return true; | ||
| 71 | + } | ||
| 72 | + double rejectPct = (100 - approveRatio) / (double) 100; | ||
| 73 | + double realRejectPct = (double) rejectCount / nrOfInstances; | ||
| 74 | + // 判断拒绝比例 | ||
| 75 | + if (realRejectPct >= rejectPct) { | ||
| 76 | + execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE); | ||
| 77 | + return true; | ||
| 78 | + } | ||
| 79 | + return false; | ||
| 61 | } | 80 | } |
| 62 | - // TODO 多人会签(按比例投票) | ||
| 63 | log.error("[completionCondition] 按拒绝人数计算会签的完成条件的审批方式[{}],配置有误", approveMethod); | 81 | log.error("[completionCondition] 按拒绝人数计算会签的完成条件的审批方式[{}],配置有误", approveMethod); |
| 64 | throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION); | 82 | throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION); |
| 65 | } | 83 | } |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/simple/SimpleModelUserTaskConfig.java
| 1 | package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple; | 1 | package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; | ||
| 3 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; | 4 | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; |
| 4 | import lombok.Data; | 5 | import lombok.Data; |
| 5 | 6 | ||
| @@ -30,11 +31,15 @@ public class SimpleModelUserTaskConfig { | @@ -30,11 +31,15 @@ public class SimpleModelUserTaskConfig { | ||
| 30 | private List<Map<String,String>> fieldsPermission; | 31 | private List<Map<String,String>> fieldsPermission; |
| 31 | 32 | ||
| 32 | /** | 33 | /** |
| 33 | - * 审批方式 | 34 | + * 审批方式 {@link BpmApproveMethodEnum } |
| 34 | */ | 35 | */ |
| 35 | private Integer approveMethod; | 36 | private Integer approveMethod; |
| 36 | 37 | ||
| 37 | /** | 38 | /** |
| 39 | + * 通过比例 当审批方式为 多人会签(按通过比例) 需设置 | ||
| 40 | + */ | ||
| 41 | + private Integer approveRatio; | ||
| 42 | + /** | ||
| 38 | * 超时处理 | 43 | * 超时处理 |
| 39 | */ | 44 | */ |
| 40 | private TimeoutHandler timeoutHandler; | 45 | private TimeoutHandler timeoutHandler; |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
| @@ -493,7 +493,7 @@ public class SimpleModelUtils { | @@ -493,7 +493,7 @@ public class SimpleModelUtils { | ||
| 493 | // 添加表单字段权限属性元素 | 493 | // 添加表单字段权限属性元素 |
| 494 | addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask); | 494 | addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask); |
| 495 | // 处理多实例 | 495 | // 处理多实例 |
| 496 | - processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTask); | 496 | + processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTaskConfig.getApproveRatio(), userTask); |
| 497 | // 添加任务被拒绝的处理元素 | 497 | // 添加任务被拒绝的处理元素 |
| 498 | addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask); | 498 | addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask); |
| 499 | return userTask; | 499 | return userTask; |
| @@ -507,7 +507,7 @@ public class SimpleModelUtils { | @@ -507,7 +507,7 @@ public class SimpleModelUtils { | ||
| 507 | addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId()); | 507 | addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId()); |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | - private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, UserTask userTask) { | 510 | + private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, Integer approveRatio, UserTask userTask) { |
| 511 | BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod); | 511 | BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod); |
| 512 | if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) { | 512 | if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) { |
| 513 | return; | 513 | return; |
| @@ -530,11 +530,16 @@ public class SimpleModelUtils { | @@ -530,11 +530,16 @@ public class SimpleModelUtils { | ||
| 530 | multiInstanceCharacteristics.setSequential(true); | 530 | multiInstanceCharacteristics.setSequential(true); |
| 531 | multiInstanceCharacteristics.setLoopCardinality("1"); | 531 | multiInstanceCharacteristics.setLoopCardinality("1"); |
| 532 | userTask.setLoopCharacteristics(multiInstanceCharacteristics); | 532 | userTask.setLoopCharacteristics(multiInstanceCharacteristics); |
| 533 | - } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT) { | 533 | + } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT ){ |
| 534 | multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION); | 534 | multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION); |
| 535 | multiInstanceCharacteristics.setSequential(false); | 535 | multiInstanceCharacteristics.setSequential(false); |
| 536 | + } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.APPROVE_BY_RATIO) { | ||
| 537 | + multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION); | ||
| 538 | + multiInstanceCharacteristics.setSequential(false); | ||
| 539 | + Assert.notNull(approveRatio, "通过比例不能为空"); | ||
| 540 | + // 添加通过比例的扩展属性 | ||
| 541 | + addExtensionElement(userTask, BpmnModelConstants.USER_TASK_APPROVE_RATIO, approveRatio.toString()); | ||
| 536 | } | 542 | } |
| 537 | - // TODO 会签(按比例投票 ) | ||
| 538 | userTask.setLoopCharacteristics(multiInstanceCharacteristics); | 543 | userTask.setLoopCharacteristics(multiInstanceCharacteristics); |
| 539 | } | 544 | } |
| 540 | 545 |