mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	仿钉钉流程设计- 会签按通过比率
This commit is contained in:
		| @@ -16,7 +16,7 @@ public enum BpmApproveMethodEnum { | |||||||
|  |  | ||||||
|     SINGLE_PERSON_APPROVE(1, "单人审批"), |     SINGLE_PERSON_APPROVE(1, "单人审批"), | ||||||
|     ALL_APPROVE(2, "多人会签(需所有审批人同意)"), // 会签 |     ALL_APPROVE(2, "多人会签(需所有审批人同意)"), // 会签 | ||||||
|     APPROVE_BY_RATIO(3, "多人会签(按比例投票)"), // 会签(按比例投票) |     APPROVE_BY_RATIO(3, "多人会签(按通过比例)"), // 会签(按通过比例) | ||||||
|     ANY_APPROVE_ALL_REJECT(4, "多人会签(通过只需一人,拒绝需要全员)"), // 会签(通过只需一人,拒绝需要全员) |     ANY_APPROVE_ALL_REJECT(4, "多人会签(通过只需一人,拒绝需要全员)"), // 会签(通过只需一人,拒绝需要全员) | ||||||
|     ANY_APPROVE(5, "多人或签(一名审批人通过即可)"), // 或签(通过只需一人,拒绝只需一人) |     ANY_APPROVE(5, "多人或签(一名审批人通过即可)"), // 或签(通过只需一人,拒绝只需一人) | ||||||
|     SEQUENTIAL_APPROVE(6, "依次审批"); // 依次审批 |     SEQUENTIAL_APPROVE(6, "依次审批"); // 依次审批 | ||||||
|   | |||||||
| @@ -55,6 +55,11 @@ public interface BpmnModelConstants { | |||||||
|      */ |      */ | ||||||
|     String USER_TASK_APPROVE_METHOD = "approveMethod"; |     String USER_TASK_APPROVE_METHOD = "approveMethod"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * BPMN UserTask 的扩展属性,当审批方式为按通过比例时, 标记会签通过比例 | ||||||
|  |      */ | ||||||
|  |     String USER_TASK_APPROVE_RATIO = "approveRatio"; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * BPMN ExtensionElement 的扩展属性,用于标记 服务任务附属的用户任务 Id |      * BPMN ExtensionElement 的扩展属性,用于标记 服务任务附属的用户任务 Id | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -16,7 +16,9 @@ import java.util.Objects; | |||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 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.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_METHOD; | ||||||
|  | import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_APPROVE_RATIO; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 按拒绝人数计算会签的完成条件的流程表达式实现 |  * 按拒绝人数计算会签的完成条件的流程表达式实现 | ||||||
| @@ -28,7 +30,7 @@ import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnMode | |||||||
| public class CompleteByRejectCountExpression { | public class CompleteByRejectCountExpression { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      *  会签的完成条件 |      * 会签的完成条件 | ||||||
|      */ |      */ | ||||||
|     public boolean completionCondition(DelegateExecution execution) { |     public boolean completionCondition(DelegateExecution execution) { | ||||||
|         FlowElement flowElement = execution.getCurrentFlowElement(); |         FlowElement flowElement = execution.getCurrentFlowElement(); | ||||||
| @@ -53,13 +55,29 @@ public class CompleteByRejectCountExpression { | |||||||
|             } else { |             } else { | ||||||
|                 // 1.2 所有人都拒绝了。设置任务拒绝变量, 会签任务完成。 后续终止流程在 ServiceTask【MultiInstanceServiceTaskExpression】处理 |                 // 1.2 所有人都拒绝了。设置任务拒绝变量, 会签任务完成。 后续终止流程在 ServiceTask【MultiInstanceServiceTaskExpression】处理 | ||||||
|                 if (Objects.equals(nrOfInstances, rejectCount)) { |                 if (Objects.equals(nrOfInstances, rejectCount)) { | ||||||
|                     execution.setVariable(String.format("%s_reject",flowElement.getId()), Boolean.TRUE); |                     execution.setVariable(String.format("%s_reject", flowElement.getId()), Boolean.TRUE); | ||||||
|                     return true; |                     return true; | ||||||
|                 } |                 } | ||||||
|                 return false; |                 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 (realApprovePct >= approvePct) { | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |             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; | ||||||
|         } |         } | ||||||
|         // TODO 多人会签(按比例投票) |  | ||||||
|         log.error("[completionCondition] 按拒绝人数计算会签的完成条件的审批方式[{}],配置有误", approveMethod); |         log.error("[completionCondition] 按拒绝人数计算会签的完成条件的审批方式[{}],配置有误", approveMethod); | ||||||
|         throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION); |         throw exception(GlobalErrorCodeConstants.ERROR_CONFIGURATION); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple; | package cn.iocoder.yudao.module.bpm.framework.flowable.core.simple; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.module.bpm.enums.definition.BpmApproveMethodEnum; | ||||||
| import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; | import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  |  | ||||||
| @@ -30,10 +31,14 @@ public class SimpleModelUserTaskConfig { | |||||||
|     private List<Map<String,String>> fieldsPermission; |     private List<Map<String,String>> fieldsPermission; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 审批方式 |      * 审批方式 {@link BpmApproveMethodEnum } | ||||||
|      */ |      */ | ||||||
|     private  Integer approveMethod; |     private  Integer approveMethod; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 通过比例  当审批方式为 多人会签(按通过比例) 需设置 | ||||||
|  |      */ | ||||||
|  |     private Integer approveRatio; | ||||||
|     /** |     /** | ||||||
|      * 超时处理 |      * 超时处理 | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -493,7 +493,7 @@ public class SimpleModelUtils { | |||||||
|         // 添加表单字段权限属性元素 |         // 添加表单字段权限属性元素 | ||||||
|         addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask); |         addFormFieldsPermission(userTaskConfig.getFieldsPermission(), userTask); | ||||||
|         // 处理多实例 |         // 处理多实例 | ||||||
|         processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTask); |         processMultiInstanceLoopCharacteristics(userTaskConfig.getApproveMethod(), userTaskConfig.getApproveRatio(), userTask); | ||||||
|         // 添加任务被拒绝的处理元素 |         // 添加任务被拒绝的处理元素 | ||||||
|         addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask); |         addTaskRejectElements(userTaskConfig.getRejectHandler(), userTask); | ||||||
|         return userTask; |         return userTask; | ||||||
| @@ -507,7 +507,7 @@ public class SimpleModelUtils { | |||||||
|         addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId()); |         addExtensionElement(userTask, USER_TASK_REJECT_RETURN_TASK_ID, rejectHandler.getReturnNodeId()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, UserTask userTask) { |     private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, Integer approveRatio, UserTask userTask) { | ||||||
|         BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod); |         BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod); | ||||||
|         if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) { |         if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.SINGLE_PERSON_APPROVE) { | ||||||
|             return; |             return; | ||||||
| @@ -530,11 +530,16 @@ public class SimpleModelUtils { | |||||||
|             multiInstanceCharacteristics.setSequential(true); |             multiInstanceCharacteristics.setSequential(true); | ||||||
|             multiInstanceCharacteristics.setLoopCardinality("1"); |             multiInstanceCharacteristics.setLoopCardinality("1"); | ||||||
|             userTask.setLoopCharacteristics(multiInstanceCharacteristics); |             userTask.setLoopCharacteristics(multiInstanceCharacteristics); | ||||||
|         } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT) { |         } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY_APPROVE_ALL_REJECT ){ | ||||||
|             multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION); |             multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION); | ||||||
|             multiInstanceCharacteristics.setSequential(false); |             multiInstanceCharacteristics.setSequential(false); | ||||||
|  |         } else if (bpmApproveMethodEnum == BpmApproveMethodEnum.APPROVE_BY_RATIO) { | ||||||
|  |             multiInstanceCharacteristics.setCompletionCondition(COMPLETE_BY_REJECT_COUNT_EXPRESSION); | ||||||
|  |             multiInstanceCharacteristics.setSequential(false); | ||||||
|  |             Assert.notNull(approveRatio, "通过比例不能为空"); | ||||||
|  |             // 添加通过比例的扩展属性 | ||||||
|  |             addExtensionElement(userTask, BpmnModelConstants.USER_TASK_APPROVE_RATIO, approveRatio.toString()); | ||||||
|         } |         } | ||||||
|         // TODO 会签(按比例投票 ) |  | ||||||
|         userTask.setLoopCharacteristics(multiInstanceCharacteristics); |         userTask.setLoopCharacteristics(multiInstanceCharacteristics); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 jason
					jason