Commit 26dd8b66702230129ba48a6d87bcda399c06a974
1 parent
b6a9b5dd
fix:获取下一个节点审批人为空时,返回new HashMap<>(),避免下级使用空指针
review: 优化审批时,校验选择的下一个节点的审批人,是否合法
Showing
2 changed files
with
32 additions
and
39 deletions
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); |
| @@ -214,12 +214,12 @@ public class FlowableUtils { | @@ -214,12 +214,12 @@ public class FlowableUtils { | ||
| 214 | * 获得流程实例的审批用户选择的下一个节点的审批人 Map | 214 | * 获得流程实例的审批用户选择的下一个节点的审批人 Map |
| 215 | * | 215 | * |
| 216 | * @param processVariables 流程变量 | 216 | * @param processVariables 流程变量 |
| 217 | - * @return 审批用户选择的下一个节点的审批人Map Map | 217 | + * @return 审批用户选择的下一个节点的审批人Map |
| 218 | */ | 218 | */ |
| 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/task/BpmTaskServiceImpl.java
| @@ -558,18 +558,12 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -558,18 +558,12 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 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 去完成任务 | 560 | // 2.3 调用 BPM complete 去完成任务 |
| 561 | - // 其中,variables 是存储动态表单到 local 任务级别。过滤一下,避免 ProcessInstance 系统级的变量被占用 | ||
| 562 | - if (CollUtil.isNotEmpty(reqVO.getVariables())) { | ||
| 563 | - // 校验并处理 APPROVE_USER_SELECT 当前审批人,选择下一节点审批人的逻辑 | ||
| 564 | - Map<String, Object> variables = validateAndSetNextAssignees(task.getTaskDefinitionKey(), reqVO.getVariables(), | ||
| 565 | - bpmnModel, reqVO.getNextAssignees(), instance); | ||
| 566 | - // 完成任务 | ||
| 567 | - runtimeService.setVariables(task.getProcessInstanceId(), variables); | ||
| 568 | - taskService.complete(task.getId(), variables, true); | ||
| 569 | - } else { | ||
| 570 | - // 完成任务 | ||
| 571 | - taskService.complete(task.getId()); | ||
| 572 | - } | 561 | + // 校验并处理 APPROVE_USER_SELECT 当前审批人,选择下一节点审批人的逻辑 |
| 562 | + Map<String, Object> variables = validateAndSetNextAssignees(task.getTaskDefinitionKey(), reqVO.getVariables(), | ||
| 563 | + bpmnModel, reqVO.getNextAssignees(), instance); | ||
| 564 | + // 完成任务 | ||
| 565 | + runtimeService.setVariables(task.getProcessInstanceId(), variables); | ||
| 566 | + taskService.complete(task.getId(), variables, true); | ||
| 573 | 567 | ||
| 574 | // 【加签专属】处理加签任务 | 568 | // 【加签专属】处理加签任务 |
| 575 | handleParentTaskIfSign(task.getParentTaskId()); | 569 | handleParentTaskIfSign(task.getParentTaskId()); |
| @@ -590,51 +584,50 @@ public class BpmTaskServiceImpl implements BpmTaskService { | @@ -590,51 +584,50 @@ public class BpmTaskServiceImpl implements BpmTaskService { | ||
| 590 | */ | 584 | */ |
| 591 | private Map<String, Object> validateAndSetNextAssignees(String taskDefinitionKey, Map<String, Object> variables, BpmnModel bpmnModel, | 585 | private Map<String, Object> validateAndSetNextAssignees(String taskDefinitionKey, Map<String, Object> variables, BpmnModel bpmnModel, |
| 592 | Map<String, List<Long>> nextAssignees, ProcessInstance processInstance) { | 586 | Map<String, List<Long>> nextAssignees, ProcessInstance processInstance) { |
| 593 | - // 下一个节点参数为空,不做处理,表示流程正常流转,无需选择下一个节点的审判人 | ||
| 594 | - // TODO @小北:会出现漏选,其实需要的情况哇? | ||
| 595 | - if (CollUtil.isEmpty(nextAssignees)) { | ||
| 596 | - return variables; | ||
| 597 | - } | ||
| 598 | // 1. 获取下一个将要执行的节点集合 | 587 | // 1. 获取下一个将要执行的节点集合 |
| 599 | FlowElement flowElement = bpmnModel.getFlowElement(taskDefinitionKey); | 588 | FlowElement flowElement = bpmnModel.getFlowElement(taskDefinitionKey); |
| 600 | List<FlowNode> nextFlowNodes = getNextFlowNodes(flowElement, bpmnModel, variables); | 589 | List<FlowNode> nextFlowNodes = getNextFlowNodes(flowElement, bpmnModel, variables); |
| 601 | - | ||
| 602 | // 2. 循环下一个将要执行的节点集合 | 590 | // 2. 循环下一个将要执行的节点集合 |
| 603 | - Map<String, List<Long>> processVariables = new HashMap<>(); | 591 | + Map<String, List<Long>> processVariables; |
| 604 | for (FlowNode nextFlowNode : nextFlowNodes) { | 592 | for (FlowNode nextFlowNode : nextFlowNodes) { |
| 605 | - if (!nextAssignees.containsKey(nextFlowNode.getId())) { | ||
| 606 | - throw exception(TASK_TARGET_NODE_NOT_EXISTS, nextFlowNode.getName()); | ||
| 607 | - } | ||
| 608 | - List<Long> assignees = nextAssignees.get(nextFlowNode.getId()); | ||
| 609 | - // 2.1 情况一:如果节点中的审批人策略为 发起人自选 | 593 | + // 获取任务节点中的审批人策略 |
| 610 | Integer candidateStrategy = parseCandidateStrategy(nextFlowNode); | 594 | Integer candidateStrategy = parseCandidateStrategy(nextFlowNode); |
| 595 | + // 2.1 情况一:如果节点中的审批人策略为 发起人自选 | ||
| 611 | if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy())) { | 596 | if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.START_USER_SELECT.getStrategy())) { |
| 612 | - processVariables = FlowableUtils.getStartUserSelectAssignees(processInstance.getProcessVariables()); | ||
| 613 | - if (processVariables == null) { | ||
| 614 | - processVariables = new HashMap<>(); | ||
| 615 | - } | ||
| 616 | - List<Long> startUserSelectAssignee = processVariables.get(nextFlowNode.getId()); | ||
| 617 | - // 特殊:如果当前节点已经存在审批人,则不允许覆盖 | ||
| 618 | - if (CollUtil.isNotEmpty(startUserSelectAssignee)) { | ||
| 619 | - continue; | ||
| 620 | - } | ||
| 621 | // 如果节点存在,但未配置审批人 | 597 | // 如果节点存在,但未配置审批人 |
| 598 | + List<Long> assignees = nextAssignees != null ? nextAssignees.get(nextFlowNode.getId()) : null; | ||
| 622 | if (CollUtil.isEmpty(assignees)) { | 599 | if (CollUtil.isEmpty(assignees)) { |
| 623 | throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName()); | 600 | throw exception(PROCESS_INSTANCE_START_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName()); |
| 624 | } | 601 | } |
| 602 | + processVariables = FlowableUtils.getStartUserSelectAssignees(processInstance.getProcessVariables()); | ||
| 603 | + if (CollUtil.isNotEmpty(processVariables)) { | ||
| 604 | + List<Long> startUserSelectAssignee = processVariables.get(nextFlowNode.getId()); | ||
| 605 | + // 特殊:如果当前节点已经存在审批人,则不允许覆盖 | ||
| 606 | + if (CollUtil.isNotEmpty(startUserSelectAssignee)) { | ||
| 607 | + continue; | ||
| 608 | + } | ||
| 609 | + } | ||
| 625 | // 校验通过的全部节点和审批人 | 610 | // 校验通过的全部节点和审批人 |
| 626 | - processVariables.put(nextFlowNode.getId(), assignees); | 611 | + processVariables.put(nextFlowNode.getId(), nextAssignees.get(nextFlowNode.getId())); |
| 627 | variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, processVariables); | 612 | variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES, processVariables); |
| 628 | } | 613 | } |
| 629 | // 2.2 情况二:如果节点中的审批人策略为 审批人,在审批时选择下一个节点的审批人,并且该节点的审批人为空 | 614 | // 2.2 情况二:如果节点中的审批人策略为 审批人,在审批时选择下一个节点的审批人,并且该节点的审批人为空 |
| 630 | if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy())) { | 615 | if (ObjUtil.equals(candidateStrategy, BpmTaskCandidateStrategyEnum.APPROVE_USER_SELECT.getStrategy())) { |
| 631 | // 如果节点存在,但未配置审批人 | 616 | // 如果节点存在,但未配置审批人 |
| 617 | + List<Long> assignees = nextAssignees != null ? nextAssignees.get(nextFlowNode.getId()) : null; | ||
| 632 | if (CollUtil.isEmpty(assignees)) { | 618 | if (CollUtil.isEmpty(assignees)) { |
| 633 | throw exception(PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName()); | 619 | throw exception(PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG, nextFlowNode.getName()); |
| 634 | } | 620 | } |
| 621 | + processVariables = FlowableUtils.getApproveUserSelectAssignees(processInstance.getProcessVariables()); | ||
| 622 | + if (CollUtil.isNotEmpty(processVariables)) { | ||
| 623 | + List<Long> approveUserSelectAssignee = processVariables.get(nextFlowNode.getId()); | ||
| 624 | + // 特殊:如果当前节点已经存在审批人,则不允许覆盖 | ||
| 625 | + if (CollUtil.isNotEmpty(approveUserSelectAssignee)) { | ||
| 626 | + continue; | ||
| 627 | + } | ||
| 628 | + } | ||
| 635 | // 校验通过的全部节点和审批人 | 629 | // 校验通过的全部节点和审批人 |
| 636 | - processVariables.put(nextFlowNode.getId(), assignees); | ||
| 637 | - // TODO @小北:是不是要类似情况一的做法,通过 PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES 拿一下?因为如果 task1 是审批人自选,task2 是审批人自选,看着会覆盖? | 630 | + processVariables.put(nextFlowNode.getId(), nextAssignees.get(nextFlowNode.getId())); |
| 638 | variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES, processVariables); | 631 | variables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES, processVariables); |
| 639 | } | 632 | } |
| 640 | } | 633 | } |