From 7b791f71717da627b9609a1b189776a81166bb3f Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Thu, 12 Sep 2024 14:42:53 +0800 Subject: [PATCH] =?UTF-8?q?REQ-2924-=E8=B0=83=E6=95=B4=E9=80=80=E5=9B=9E?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E6=A0=A1=E9=AA=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/code/BpmnTaskRespCode.java | 1 + .../core/common/utils/BpmnModelUtils.java | 91 ++++++++++++++ .../engine/cmd/CustomBackTaskAsyncCmd.java | 39 ++++-- .../core/engine/cmd/CustomBackTaskCmd.java | 40 ++++--- .../engine/cmd/helper/CustomTaskHelper.java | 111 +++++++++--------- 5 files changed, 198 insertions(+), 84 deletions(-) create mode 100644 workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnModelUtils.java diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java index 663f31544..ff4fec3a7 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/code/BpmnTaskRespCode.java @@ -38,6 +38,7 @@ public enum BpmnTaskRespCode implements IModuleRespCode { PROCESS_CANT_SET_ASSIGNEE("021", "当前审批状态不允许设置审批人"), ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT("022", String.format("人员数量超过限制,节点审批人限制数量为: %d!", APPROVAL_ASSIGNER_LIMIT_NUMBER)), BACK_TARGET_ACTIVITY_NOT_EXISTS("023", "回退到指定节点【{}】失败!"), + BACK_NODE_CANNOT_REACHABLE("024", "退回节点【{}】不可达,不允许退回"), ; private final String code; diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnModelUtils.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnModelUtils.java new file mode 100644 index 000000000..80ace39f9 --- /dev/null +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/common/utils/BpmnModelUtils.java @@ -0,0 +1,91 @@ +package cn.axzo.workflow.core.common.utils; + +import org.flowable.bpmn.model.EventSubProcess; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowElementsContainer; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.bpmn.model.SequenceFlow; +import org.flowable.bpmn.model.StartEvent; +import org.flowable.bpmn.model.SubProcess; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class BpmnModelUtils { + + /** + * 节点是否可达 + * @param process + * @param sourceElement + * @param targetElement + * @return + */ + public static boolean isReachable(org.flowable.bpmn.model.Process process, FlowNode sourceElement, FlowNode targetElement) { + return isReachable(process, sourceElement, targetElement, new HashSet<>()); + } + + public static boolean isReachable(org.flowable.bpmn.model.Process process, FlowNode sourceElement, FlowNode targetElement, Set visitedElements) { + // Special case: start events in an event subprocess might exist as an execution and are most likely be able to + // reach the target + // when the target is in the event subprocess, but should be ignored as they are not 'real' runtime executions + // (but rather waiting for trigger) + if (sourceElement instanceof StartEvent && isInEventSubprocess(sourceElement)) { + return false; + } + // No outgoing seq flow: could be the end of eg . the process or an embedded subprocess + if (sourceElement.getOutgoingFlows().isEmpty()) { + visitedElements.add(sourceElement.getId()); + FlowElementsContainer parentElement = process.findParent(sourceElement); + if (parentElement instanceof SubProcess) { + sourceElement = (SubProcess) parentElement; + // 子流程的结束节点,若目标节点在该子流程中,说明无法到达,返回false + if (((SubProcess) sourceElement).getFlowElement(targetElement.getId()) != null) { + return false; + } + } else { + return false; + } + } + if (sourceElement.getId().equals(targetElement.getId())) { + return true; + } + // To avoid infinite looping, we must capture every node we visit + // and check before going further in the graph if we have already + // visited the node. + visitedElements.add(sourceElement.getId()); + // 当前节点能够到达子流程,且目标节点在子流程中,说明可以到达,返回true + if (sourceElement instanceof SubProcess && ((SubProcess) sourceElement).getFlowElement(targetElement.getId()) != null) { + return true; + } + List sequenceFlows = sourceElement.getOutgoingFlows(); + if (sequenceFlows != null && !sequenceFlows.isEmpty()) { + for (SequenceFlow sequenceFlow : sequenceFlows) { + String targetRef = sequenceFlow.getTargetRef(); + FlowNode sequenceFlowTarget = (FlowNode) process.getFlowElement(targetRef, true); + if (sequenceFlowTarget != null && !visitedElements.contains(sequenceFlowTarget.getId())) { + boolean reachable = isReachable(process, sequenceFlowTarget, targetElement, visitedElements); + if (reachable) { + return true; + } + } + } + } + return false; + } + + protected static boolean isInEventSubprocess(FlowNode flowNode) { + FlowElementsContainer flowElementsContainer = flowNode.getParentContainer(); + while (flowElementsContainer != null) { + if (flowElementsContainer instanceof EventSubProcess) { + return true; + } + if (flowElementsContainer instanceof FlowElement) { + flowElementsContainer = ((FlowElement) flowElementsContainer).getParentContainer(); + } else { + flowElementsContainer = null; + } + } + return false; + } +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java index 0dbfda785..be5ecb500 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskAsyncCmd.java @@ -1,34 +1,39 @@ package cn.axzo.workflow.core.engine.cmd; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO; -import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler; +import cn.axzo.workflow.core.common.exception.WorkflowEngineException; +import cn.axzo.workflow.core.common.utils.BpmnModelUtils; import cn.axzo.workflow.core.engine.job.AsyncBackTaskJobHandler; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.bpmn.model.Process; import org.flowable.common.engine.impl.interceptor.CommandContext; -import org.flowable.engine.TaskService; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.engine.impl.util.ProcessDefinitionUtil; import org.flowable.job.service.JobService; import org.flowable.job.service.impl.persistence.entity.JobEntity; import org.flowable.task.api.Task; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstanceQuery; +import org.flowable.task.service.TaskService; import org.flowable.task.service.impl.persistence.entity.TaskEntity; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.Serializable; import java.util.Objects; +import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE; +import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS; import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask; +@Slf4j public class CustomBackTaskAsyncCmd extends AbstractCommand implements Serializable { private static final long serialVersionUID = 1773108485033787095L; - private static final Logger log = LoggerFactory.getLogger(CustomBackTaskAsyncCmd.class); - private final BpmnTaskBackAuditDTO dto; public CustomBackTaskAsyncCmd(BpmnTaskBackAuditDTO dto) { @@ -41,17 +46,25 @@ public class CustomBackTaskAsyncCmd extends AbstractCommand implements S CommandContextUtil.getProcessEngineConfiguration(commandContext); HistoricTaskInstanceQuery taskQuery = processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); - TaskService taskService = processEngineConfiguration.getTaskService(); + TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService(); HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult(); - Task task = taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult(); - if (Objects.isNull(task)) { - log.info("任务不存在: {}", dto.getTaskId()); - } - validTask(historicTaskInstance, (TaskEntity) task, dto.getApprover(), null); + TaskEntity taskEntity = taskService.getTask(dto.getTaskId()); + validTask(historicTaskInstance, taskEntity, dto.getApprover(), dto.getNodeTypes()); - return startAsync(processEngineConfiguration, task); + Process process = ProcessDefinitionUtil.getProcess(taskEntity.getProcessDefinitionId()); + FlowElement targetFlowElement = process.getFlowElement(dto.getToActivityId(), true); + if (Objects.isNull(targetFlowElement)) { + throw new WorkflowEngineException(BACK_TARGET_ACTIVITY_NOT_EXISTS, dto.getToActivityId()); + } + FlowElement sourceFlowElement = process.getFlowElement(taskEntity.getTaskDefinitionKey(), true); + // 退回节点到当前节点不可达到,不允许退回 + if (!BpmnModelUtils.isReachable(process, (FlowNode) sourceFlowElement, (FlowNode) targetFlowElement)) { + throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId()); + } + + return startAsync(processEngineConfiguration, taskEntity); } private String startAsync(ProcessEngineConfigurationImpl processEngineConfiguration, Task task) { diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java index 3cb67d09b..53881df93 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java @@ -2,18 +2,21 @@ package cn.axzo.workflow.core.engine.cmd; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO; import cn.axzo.workflow.core.common.exception.WorkflowEngineException; +import cn.axzo.workflow.core.common.utils.BpmnModelUtils; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; -import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.bpmn.model.Process; import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.common.engine.impl.interceptor.CommandContext; import org.flowable.engine.RuntimeService; -import org.flowable.engine.TaskService; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.engine.impl.util.ProcessDefinitionUtil; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstanceQuery; +import org.flowable.task.service.TaskService; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import java.io.Serializable; @@ -26,6 +29,7 @@ import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE; import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED; +import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS; import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment; import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment; @@ -40,14 +44,14 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ private final BpmnTaskBackAuditDTO dto; - private static String operationDesc = "回退至"; + private static final String OPERATION_DESC = "回退至"; @Override public String paramToJsonString() { Map params = new HashMap<>(); params.put("taskId", dto.getTaskId()); params.put("advice", dto.getAdvice()); - params.put("operationDesc", operationDesc); + params.put("operationDesc", OPERATION_DESC); params.put("attachmentList", JSON.toJSONString(dto.getAttachmentList())); params.put("approver", JSON.toJSONString(dto.getApprover())); params.put("nodeTypes", JSON.toJSONString(dto.getNodeTypes())); @@ -61,36 +65,40 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); HistoricTaskInstanceQuery taskQuery = - processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); - TaskService taskService = processEngineConfiguration.getTaskService(); + processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); + TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService(); HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult(); - TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(dto.getTaskId()).singleResult(); + TaskEntity task = taskService.getTask(dto.getTaskId()); validTask(historicTaskInstance, task, dto.getApprover(), dto.getNodeTypes()); - BpmnModel bpmnModel = processEngineConfiguration.getRepositoryService().getBpmnModel(historicTaskInstance.getProcessDefinitionId()); - FlowElement flowElement = bpmnModel.getFlowElement(dto.getToActivityId()); - if (Objects.isNull(flowElement)) { + Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); + FlowElement targetFlowElement = process.getFlowElement(dto.getToActivityId(), true); + if (Objects.isNull(targetFlowElement)) { throw new WorkflowEngineException(BACK_TARGET_ACTIVITY_NOT_EXISTS, dto.getToActivityId()); } - + FlowElement sourceFlowElement = process.getFlowElement(task.getTaskDefinitionKey(), true); + // 退回节点到当前节点不可达到,不允许退回 + if (!BpmnModelUtils.isReachable(process, (FlowNode) sourceFlowElement, (FlowNode) targetFlowElement)) { + throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId()); + } batchAddAttachment(commandContext, task.getProcessInstanceId(), dto.getTaskId(), dto.getAttachmentList(), dto.getApprover()); Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId()); addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice()); - addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, operationDesc + flowElement.getName()); + addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, OPERATION_DESC + targetFlowElement.getName()); Authentication.setAuthenticatedUserId(null); RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + dto.getTaskId(), BACKED.getStatus()); runtimeService.createChangeActivityStateBuilder() - .processInstanceId(task.getProcessInstanceId()) - .moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId()) - .changeState(); + .processInstanceId(task.getProcessInstanceId()) + .moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId()) + .changeState(); return null; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java index 8f3503ac1..9a182aa80 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/helper/CustomTaskHelper.java @@ -63,6 +63,7 @@ import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ASSIGNER_NUMBER import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_ASSIGN_NOT_SELF; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS; import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE; +import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.TASK_TYPE_MISMATCH; import static org.flowable.task.api.Task.DEFAULT_PRIORITY; /** @@ -80,13 +81,13 @@ public class CustomTaskHelper { return; } ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); Map executionVariables = new HashMap<>(); executionVariables.put("assigneeName", newTaskAssignee.buildAssigneeId()); RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); Execution subExecution = runtimeService.addMultiInstanceExecution(originTask.getTaskDefinitionKey(), - originTask.getProcessInstanceId(), executionVariables); + originTask.getProcessInstanceId(), executionVariables); setParentTaskId(originTask, subExecution); } @@ -96,19 +97,19 @@ public class CustomTaskHelper { return; } ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); runtimeService.deleteMultiInstanceExecution(originTask.getExecutionId(), false); } private static void setParentTaskId(TaskEntity originTask, Execution subExecution) { CommandContextUtil.getEntityCache().findInCache(TaskEntity.class).stream() - .filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId())) - .findAny().ifPresent(i -> i.setParentTaskId(originTask.getId())); + .filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId())) + .findAny().ifPresent(i -> i.setParentTaskId(originTask.getId())); CommandContextUtil.getEntityCache().findInCache(HistoricTaskInstanceEntity.class).stream() - .filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId())) - .findAny().ifPresent(i -> i.setParentTaskId(originTask.getId())); + .filter(i -> Objects.equals(i.getExecutionId(), subExecution.getId())) + .findAny().ifPresent(i -> i.setParentTaskId(originTask.getId())); } /** @@ -121,7 +122,7 @@ public class CustomTaskHelper { public static void validTask(HistoricTaskInstance historicTaskInstance, TaskEntity taskEntity, BpmnTaskDelegateAssigner originTaskAssigner, List nodeTypes) { if (Objects.nonNull(historicTaskInstance) && - (Objects.nonNull(historicTaskInstance.getEndTime()) || Objects.isNull(taskEntity))) { + (Objects.nonNull(historicTaskInstance.getEndTime()) || Objects.isNull(taskEntity))) { throw new WorkflowEngineException(TASK_HAS_BEEN_COMPLETE); } @@ -154,7 +155,7 @@ public class CustomTaskHelper { //不包含对应的任务 if (!nodeTypes.contains(nodeType)) { // log.warn(TASK_TYPE_MISMATCH.getMessage(), nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(","))); - throw new WorkflowEngineException(ASSIGNER_NUMBER_EXCEEDS_NUMBER_LIMIT, nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(","))); + throw new WorkflowEngineException(TASK_TYPE_MISMATCH, nodeType.getDesc(), nodeTypes.stream().map(BpmnFlowNodeType::getDesc).collect(Collectors.joining(","))); } } } @@ -171,14 +172,14 @@ public class CustomTaskHelper { TaskEntity taskEntity, List targetAssigneeList) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); // 这个节点下所有审批人快照 String activityListSnapshot = - INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey(); + INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + taskEntity.getTaskDefinitionKey(); List taskAssignerListSnapshot = - runtimeService.getVariable(taskEntity.getProcessInstanceId(), activityListSnapshot, List.class); + runtimeService.getVariable(taskEntity.getProcessInstanceId(), activityListSnapshot, List.class); AtomicInteger existsCount = new AtomicInteger(); taskAssignerListSnapshot.forEach(i -> { targetAssigneeList.forEach(j -> { @@ -228,12 +229,12 @@ public class CustomTaskHelper { return; } ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); TaskService taskService = processEngineConfiguration.getTaskService(); Authentication.setAuthenticatedUserId(assigner.buildAssigneeId()); attachmentList.forEach(dto -> { Attachment attachment = taskService.createAttachment(dto.getType().getType(), taskId, processInstanceId, - dto.getName(), dto.getDescription(), dto.getUrl()); + dto.getName(), dto.getDescription(), dto.getUrl()); taskService.saveAttachment(attachment); }); Authentication.setAuthenticatedUserId(null); @@ -256,7 +257,7 @@ public class CustomTaskHelper { return; } ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); String userId = Authentication.getAuthenticatedUserId(); CommentEntity comment = processEngineConfiguration.getCommentEntityManager().create(); @@ -281,7 +282,7 @@ public class CustomTaskHelper { public static Attachment addAttachment(CommandContext commandContext, Task task, AttachmentDTO attachmentDto) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); AttachmentEntity attachment = processEngineConfiguration.getAttachmentEntityManager().create(); attachment.setName(attachmentDto.getName()); attachment.setProcessInstanceId(task.getProcessInstanceId()); @@ -297,11 +298,11 @@ public class CustomTaskHelper { ExecutionEntity processInstance = null; if (task.getProcessInstanceId() != null) { processInstance = - processEngineConfiguration.getExecutionEntityManager().findById(task.getProcessInstanceId()); + processEngineConfiguration.getExecutionEntityManager().findById(task.getProcessInstanceId()); } processEngineConfiguration.getHistoryManager().createAttachmentComment((TaskEntity) task, processInstance, - attachmentDto.getName(), true); + attachmentDto.getName(), true); return attachment; } @@ -320,15 +321,15 @@ public class CustomTaskHelper { * @return */ public static Task createVirtualTask(CommandContext commandContext, ExtAxHiTaskInstService extAxHiTaskInstService - , String processInstanceId, String nodeName, String taskDefinitionKey, String advice, + , String processInstanceId, String nodeName, String taskDefinitionKey, String advice, BpmnTaskDelegateAssigner assigner, String extTaskInstStatus, AddComment addComment) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); HistoryService historyService = processEngineConfiguration.getHistoryService(); HistoricProcessInstance processInstance = - historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); + historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); TaskService taskService = processEngineConfiguration.getTaskService(); IdGenerator idGenerator = processEngineConfiguration.getIdGenerator(); @@ -345,12 +346,12 @@ public class CustomTaskHelper { if (Objects.nonNull(assigner)) { CommandContextUtil.getEntityCache().findInCache(TaskEntity.class).stream() - .filter(i -> Objects.equals(i.getId(), task.getId())).findAny() - .ifPresent(i -> i.setAssignee(assigner.buildAssigneeId())); + .filter(i -> Objects.equals(i.getId(), task.getId())).findAny() + .ifPresent(i -> i.setAssignee(assigner.buildAssigneeId())); CommandContextUtil.getEntityCache().findInCache(HistoricTaskInstanceEntity.class).stream() - .filter(i -> Objects.equals(i.getId(), task.getId())).findAny() - .ifPresent(i -> i.setAssignee(assigner.buildAssigneeId())); + .filter(i -> Objects.equals(i.getId(), task.getId())).findAny() + .ifPresent(i -> i.setAssignee(assigner.buildAssigneeId())); } // 添加审批意见 @@ -359,7 +360,7 @@ public class CustomTaskHelper { addComment(commandContext, task, addComment); CustomTaskHelper.createExtTaskInst(extAxHiTaskInstService, task.getProcessInstanceId(), task.getId(), - task.getTaskDefinitionKey(), assigner, extTaskInstStatus); + task.getTaskDefinitionKey(), assigner, extTaskInstStatus); task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), extTaskInstStatus); // 保存任务 @@ -378,7 +379,7 @@ public class CustomTaskHelper { public static Task completeVirtualTask(CommandContext commandContext, Task task) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); + CommandContextUtil.getProcessEngineConfiguration(commandContext); TaskService taskService = processEngineConfiguration.getTaskService(); taskService.complete(task.getId()); return task; @@ -415,10 +416,10 @@ public class CustomTaskHelper { return delegateAssigners; } return new ArrayList<>(delegateAssigners.stream() - .filter(i -> StringUtils.hasText(i.getPersonId())) - .filter(i -> !Objects.equals(i.getPersonId(), "null")) - .collect(Collectors.toMap(BpmnTaskDelegateAssigner::getPersonId, Function.identity(), (s, t) -> s)) - .values()); + .filter(i -> StringUtils.hasText(i.getPersonId())) + .filter(i -> !Objects.equals(i.getPersonId(), "null")) + .collect(Collectors.toMap(BpmnTaskDelegateAssigner::getPersonId, Function.identity(), (s, t) -> s)) + .values()); } /** @@ -445,27 +446,27 @@ public class CustomTaskHelper { List result = new ArrayList<>(); List taskInstances = historyService.createHistoricTaskInstanceQuery() - .processInstanceId(processInstanceId) - .orderByHistoricTaskInstanceStartTime() - .desc().list(); + .processInstanceId(processInstanceId) + .orderByHistoricTaskInstanceStartTime() + .desc().list(); List vos = historicTaskInstanceConverter.toVosSkipSystemOperation(taskInstances, - serviceVersion); + serviceVersion); Map variableInstanceMap = - // 不能使用框架提供的历史变量 API 查询,有 BUG - historyService.createNativeHistoricVariableInstanceQuery() - .sql("select * from ACT_HI_VARINST t where t.proc_inst_id_= #{processInstanceId}") - .parameter("processInstanceId", processInstanceId) - .list().stream() - .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, - Function.identity(), (s, t) -> s)); + // 不能使用框架提供的历史变量 API 查询,有 BUG + historyService.createNativeHistoricVariableInstanceQuery() + .sql("select * from ACT_HI_VARINST t where t.proc_inst_id_= #{processInstanceId}") + .parameter("processInstanceId", processInstanceId) + .list().stream() + .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, + Function.identity(), (s, t) -> s)); vos.forEach(vo -> { HistoricVariableInstance assginerSnapshot = - variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + vo.getTaskId(), - null); + variableInstanceMap.getOrDefault(INTERNAL_TASK_RELATION_ASSIGNEE_INFO + vo.getTaskId(), + null); if (Objects.isNull(assginerSnapshot)) { assginerSnapshot = - variableInstanceMap.getOrDefault(OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskId(), null); + variableInstanceMap.getOrDefault(OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT + vo.getTaskId(), null); } if (Objects.nonNull(assginerSnapshot)) { BpmnTaskDelegateAssigner assigner = BpmnTaskDelegateAssigner.toObjectCompatible(assginerSnapshot.getValue()); @@ -481,27 +482,27 @@ public class CustomTaskHelper { ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); List taskDefinitionKeys = process.getFlowElements().stream() - .filter(i -> Objects.equals(BpmnMetaParserHelper.getNodeType(i).orElse(null), BpmnFlowNodeType.NODE_CARBON_COPY)) - .map(FlowElement::getId) - .collect(Collectors.toList()); + .filter(i -> Objects.equals(BpmnMetaParserHelper.getNodeType(i).orElse(null), BpmnFlowNodeType.NODE_CARBON_COPY)) + .map(FlowElement::getId) + .collect(Collectors.toList()); if (CollectionUtils.isEmpty(taskDefinitionKeys)) { return Collections.emptyList(); } List variableInstances = processEngineConfiguration.getHistoryService().createHistoricVariableInstanceQuery() - .variableNameLike(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT) - .processInstanceId(processInstanceId) - .list(); + .variableNameLike(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT) + .processInstanceId(processInstanceId) + .list(); if (CollectionUtils.isEmpty(variableInstances)) { return Collections.emptyList(); } List result = new ArrayList<>(); taskDefinitionKeys.forEach(j -> { variableInstances.stream() - .filter(i -> Objects.equals(i.getVariableName(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + j)) - .findFirst().ifPresent(i -> { - result.addAll((List) i.getValue()); - }); + .filter(i -> Objects.equals(i.getVariableName(), INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + j)) + .findFirst().ifPresent(i -> { + result.addAll((List) i.getValue()); + }); }); return result; }