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

This commit is contained in:
jason 2024-06-14 11:05:32 +08:00
parent 7423f9ddad
commit d7e1b87b1b
3 changed files with 30 additions and 39 deletions

View File

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

View File

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

View File

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