Commit 24261cf767fea0e71d813e590e12d3debb7b97db

Authored by YunaiV
1 parent 9ae18fe5

【代码评审】BPM:计算下一个节点的审批人(审批人自选)

yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
@@ -908,12 +908,13 @@ public class BpmnModelUtils { @@ -908,12 +908,13 @@ public class BpmnModelUtils {
908 */ 908 */
909 private static SequenceFlow findMatchSequenceFlowByExclusiveGateway(Gateway gateway, Map<String, Object> variables) { 909 private static SequenceFlow findMatchSequenceFlowByExclusiveGateway(Gateway gateway, Map<String, Object> variables) {
910 // TODO 表单无可编辑字段时variables为空,流程走向会出现问题,比如流程审批过程中无需要修改的字段值, 910 // TODO 表单无可编辑字段时variables为空,流程走向会出现问题,比如流程审批过程中无需要修改的字段值,
  911 + // TODO @小北:是不是还是保证,编辑的时候,如果计算下一个节点,还是 variables 是完整体?而不是空的!!!(可以微信讨论下)
911 SequenceFlow matchSequenceFlow; 912 SequenceFlow matchSequenceFlow;
912 - if (CollUtil.isNotEmpty(variables)){ 913 + if (CollUtil.isNotEmpty(variables)) {
913 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(), 914 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),
914 flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId()) 915 flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId())
915 && (evalConditionExpress(variables, flow.getConditionExpression()))); 916 && (evalConditionExpress(variables, flow.getConditionExpression())));
916 - }else { 917 + } else {
917 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(), 918 matchSequenceFlow = CollUtil.findOne(gateway.getOutgoingFlows(),
918 flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId())); 919 flow -> ObjUtil.notEqual(gateway.getDefaultFlow(), flow.getId()));
919 } 920 }
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/FlowableUtils.java
@@ -194,7 +194,7 @@ public class FlowableUtils { @@ -194,7 +194,7 @@ public class FlowableUtils {
194 @SuppressWarnings("unchecked") 194 @SuppressWarnings("unchecked")
195 public static Map<String, List<Long>> getStartUserSelectAssignees(Map<String, Object> processVariables) { 195 public static Map<String, List<Long>> getStartUserSelectAssignees(Map<String, Object> processVariables) {
196 if (processVariables == null) { 196 if (processVariables == null) {
197 - return null; 197 + return new HashMap<>();
198 } 198 }
199 return (Map<String, List<Long>>) processVariables.get( 199 return (Map<String, List<Long>>) processVariables.get(
200 BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES); 200 BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES);
@@ -219,7 +219,7 @@ public class FlowableUtils { @@ -219,7 +219,7 @@ public class FlowableUtils {
219 @SuppressWarnings("unchecked") 219 @SuppressWarnings("unchecked")
220 public static Map<String, List<Long>> getApproveUserSelectAssignees(Map<String, Object> processVariables) { 220 public static Map<String, List<Long>> getApproveUserSelectAssignees(Map<String, Object> processVariables) {
221 if (processVariables == null) { 221 if (processVariables == null) {
222 - return null; 222 + return new HashMap<>();
223 } 223 }
224 return (Map<String, List<Long>>) processVariables.get( 224 return (Map<String, List<Long>>) processVariables.get(
225 BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES); 225 BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES);
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
@@ -231,7 +231,7 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -231,7 +231,7 @@ public class BpmModelServiceImpl implements BpmModelService {
231 repositoryService.saveModel(model); 231 repositoryService.saveModel(model);
232 } 232 }
233 233
234 - private void validateBpmnXml(byte[] bpmnBytes, int type) { 234 + private void validateBpmnXml(byte[] bpmnBytes, Integer type) {
235 BpmnModel bpmnModel = BpmnModelUtils.getBpmnModel(bpmnBytes); 235 BpmnModel bpmnModel = BpmnModelUtils.getBpmnModel(bpmnBytes);
236 if (bpmnModel == null) { 236 if (bpmnModel == null) {
237 throw exception(MODEL_NOT_EXISTS); 237 throw exception(MODEL_NOT_EXISTS);
@@ -248,6 +248,7 @@ public class BpmModelServiceImpl implements BpmModelService { @@ -248,6 +248,7 @@ public class BpmModelServiceImpl implements BpmModelService {
248 throw exception(MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS, userTask.getId()); 248 throw exception(MODEL_DEPLOY_FAIL_BPMN_USER_TASK_NAME_NOT_EXISTS, userTask.getId());
249 } 249 }
250 }); 250 });
  251 + // TODO @小北:是不是可以 UserTask firUserTask = CollUtil.get(userTasks, BpmModelTypeEnum.BPMN.getType().equals(type) ? 0 : 1);然后,最好判空。。。极端情况下,没 usertask ,哈哈哈哈。
251 // 3. 校验第一个用户任务节点的规则类型是否为“审批人自选” 252 // 3. 校验第一个用户任务节点的规则类型是否为“审批人自选”
252 Map<Integer, UserTask> userTaskMap = new HashMap<>(); 253 Map<Integer, UserTask> userTaskMap = new HashMap<>();
253 // BPMN 设计器,校验第一个用户任务节点 254 // BPMN 设计器,校验第一个用户任务节点
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
@@ -557,12 +557,11 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -557,12 +557,11 @@ public class BpmTaskServiceImpl implements BpmTaskService {
557 // 2.2 添加评论 557 // 2.2 添加评论
558 taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(), 558 taskService.addComment(task.getId(), task.getProcessInstanceId(), BpmCommentTypeEnum.APPROVE.getType(),
559 BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason())); 559 BpmCommentTypeEnum.APPROVE.formatComment(reqVO.getReason()));
560 - // 2.3 调用 BPM complete 去完成任务  
561 - // 校验并处理 APPROVE_USER_SELECT 当前审批人,选择下一节点审批人的逻辑 560 + // 2.3 校验并处理 APPROVE_USER_SELECT 当前审批人,选择下一节点审批人的逻辑
562 Map<String, Object> variables = validateAndSetNextAssignees(task.getTaskDefinitionKey(), reqVO.getVariables(), 561 Map<String, Object> variables = validateAndSetNextAssignees(task.getTaskDefinitionKey(), reqVO.getVariables(),
563 bpmnModel, reqVO.getNextAssignees(), instance); 562 bpmnModel, reqVO.getNextAssignees(), instance);
564 - // 完成任务  
565 runtimeService.setVariables(task.getProcessInstanceId(), variables); 563 runtimeService.setVariables(task.getProcessInstanceId(), variables);
  564 + // 2.4 调用 BPM complete 去完成任务
566 taskService.complete(task.getId(), variables, true); 565 taskService.complete(task.getId(), variables, true);
567 566
568 // 【加签专属】处理加签任务 567 // 【加签专属】处理加签任务
@@ -587,10 +586,10 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -587,10 +586,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
587 // 1. 获取下一个将要执行的节点集合 586 // 1. 获取下一个将要执行的节点集合
588 FlowElement flowElement = bpmnModel.getFlowElement(taskDefinitionKey); 587 FlowElement flowElement = bpmnModel.getFlowElement(taskDefinitionKey);
589 List<FlowNode> nextFlowNodes = getNextFlowNodes(flowElement, bpmnModel, variables); 588 List<FlowNode> nextFlowNodes = getNextFlowNodes(flowElement, bpmnModel, variables);
590 - // 2. 循环下一个将要执行的节点集合 589 +
  590 + // 2. 校验选择的下一个节点的审批人,是否合法
591 Map<String, List<Long>> processVariables; 591 Map<String, List<Long>> processVariables;
592 for (FlowNode nextFlowNode : nextFlowNodes) { 592 for (FlowNode nextFlowNode : nextFlowNodes) {
593 - // 获取任务节点中的审批人策略  
594 Integer candidateStrategy = parseCandidateStrategy(nextFlowNode); 593 Integer candidateStrategy = parseCandidateStrategy(nextFlowNode);
595 // 2.1 情况一:如果节点中的审批人策略为 发起人自选 594 // 2.1 情况一:如果节点中的审批人策略为 发起人自选
596 if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy())) { 595 if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy())) {
@@ -600,16 +599,16 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -600,16 +599,16 @@ public class BpmTaskServiceImpl implements BpmTaskService {
600 throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName()); 599 throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName());
601 } 600 }
602 processVariables = FlowableUtils.getStartUserSelectAssignees(processInstance.getProcessVariables()); 601 processVariables = FlowableUtils.getStartUserSelectAssignees(processInstance.getProcessVariables());
603 - if (processVariables == null){ 602 + // 特殊:如果当前节点已经存在审批人,则不允许覆盖
  603 + // TODO @小北:【不用改】通过 if return,让逻辑更简洁一点;虽然会多判断一次 processVariables,但是 if else 层级更少。
  604 + if (processVariables != null
  605 + && CollUtil.isNotEmpty(processVariables.get(nextFlowNode.getId()))) {
  606 + continue;
  607 + }
  608 + // 设置 PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES
  609 + if (processVariables == null) {
604 processVariables = new HashMap<>(); 610 processVariables = new HashMap<>();
605 - }else {  
606 - List<Long> startUserSelectAssignee = processVariables.get(nextFlowNode.getId());  
607 - // 特殊:如果当前节点已经存在审批人,则不允许覆盖  
608 - if (CollUtil.isNotEmpty(startUserSelectAssignee)) {  
609 - continue;  
610 - }  
611 } 611 }
612 - // 校验通过的全部节点和审批人  
613 processVariables.put(nextFlowNode.getId(), assignees); 612 processVariables.put(nextFlowNode.getId(), assignees);
614 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, processVariables); 613 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, processVariables);
615 } 614 }
@@ -621,16 +620,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { @@ -621,16 +620,17 @@ public class BpmTaskServiceImpl implements BpmTaskService {
621 throw exception(PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName()); 620 throw exception(PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName());
622 } 621 }
623 processVariables = FlowableUtils.getApproveUserSelectAssignees(processInstance.getProcessVariables()); 622 processVariables = FlowableUtils.getApproveUserSelectAssignees(processInstance.getProcessVariables());
624 - if (processVariables == null){ 623 + if (processVariables == null) {
625 processVariables = new HashMap<>(); 624 processVariables = new HashMap<>();
626 - }else { 625 + } else {
627 List<Long> approveUserSelectAssignee = processVariables.get(nextFlowNode.getId()); 626 List<Long> approveUserSelectAssignee = processVariables.get(nextFlowNode.getId());
628 // 特殊:如果当前节点已经存在审批人,则不允许覆盖 627 // 特殊:如果当前节点已经存在审批人,则不允许覆盖
  628 + // TODO @小北:这种,应该可以覆盖呢。
629 if (CollUtil.isNotEmpty(approveUserSelectAssignee)) { 629 if (CollUtil.isNotEmpty(approveUserSelectAssignee)) {
630 continue; 630 continue;
631 } 631 }
632 } 632 }
633 - // 校验通过的全部节点和审批人 633 + // 设置 PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES
634 processVariables.put(nextFlowNode.getId(), assignees); 634 processVariables.put(nextFlowNode.getId(), assignees);
635 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES, processVariables); 635 variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES, processVariables);
636 } 636 }