REQ-2924-修复查询退回节点报错问题

This commit is contained in:
yangqicheng 2024-09-14 10:42:36 +08:00
parent 2bff396e6b
commit d6e837df53

View File

@ -1,7 +1,9 @@
package cn.axzo.workflow.core.service.impl;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO;
@ -55,12 +57,10 @@ import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.flowable.bpmn.model.BaseElement;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.bpmn.model.ServiceTask;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
@ -69,7 +69,6 @@ import org.flowable.engine.ManagementService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
@ -101,6 +100,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -365,45 +365,54 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService {
//流程为空已经结束返回空
throw new WorkflowEngineException(PROCESS_INSTANCE_NOT_EXISTS);
}
List<HistoricActivityInstance> hisList = historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceStartTime()
.asc()
.list();
List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
if (CollectionUtils.isEmpty(activeActivityIds)) {
return Collections.emptyList();
List<BpmnHistoricTaskInstanceVO> tasks = this.getHistoricTaskListByProcessInstanceId(processInstanceId, null);
tasks.sort(Comparator.comparing(BpmnHistoricTaskInstanceVO::getCreateTime));
LinkedList<Pair<String, List<BpmnHistoricTaskInstanceVO>>> executedList = new LinkedList<>();
for (BpmnHistoricTaskInstanceVO vo : tasks) {
Pair<String, List<BpmnHistoricTaskInstanceVO>> last = org.springframework.util.CollectionUtils.isEmpty(executedList) ? null : executedList.getLast();
if (last != null && last.getLeft().equals(vo.getTaskDefinitionKey())) {
last.getRight().add(vo);
continue;
}
ArrayList<BpmnHistoricTaskInstanceVO> objects = new ArrayList<>();
objects.add(vo);
executedList.addLast(Pair.of(vo.getTaskDefinitionKey(), objects));
}
List<FlowElement> flowElements = bpmnProcessModelService.findFlowElements(task.getProcessDefinitionId());
if (CollectionUtils.isEmpty(flowElements)) {
return Collections.emptyList();
}
//考虑会签
Map<String, FlowElement> flowElementMap = flowElements.stream().collect(Collectors.toMap(BaseElement::getId, f -> f));
List<FlowElement> executePath = new ArrayList<>();
for (HistoricActivityInstance his : hisList) {
FlowElement flowElement = flowElementMap.get(his.getActivityId());
if (flowElement != null) {
FlowElement previousNode = CollectionUtils.isEmpty(executePath) ? null : executePath.get(executePath.size() - 1);
//上一级直接连接不是同一个节点表示跳转过去的,
if (previousNode != null && !his.getActivityId().equals(previousNode.getId()) && (previousNode instanceof UserTask || previousNode instanceof ServiceTask) && !(flowElement instanceof SequenceFlow)) {
int i = executePath.size() - 1;
for (; i >= 0; i--) {
if (executePath.get(i).getId().equals(flowElement.getId())) {
break;
}
List<Pair<String, List<BpmnHistoricTaskInstanceVO>>> valuableList = new LinkedList<>();
for (Pair<String, List<BpmnHistoricTaskInstanceVO>> pair : executedList) {
List<BpmnHistoricTaskInstanceVO> taskInstanceVOList = pair.getRight();
Optional<BpmnHistoricTaskInstanceVO> backTaskOpt = taskInstanceVOList
.stream()
.filter(t -> t.getResult() != null)
.filter(t -> t.getResult() == BpmnProcessInstanceResultEnum.BACKED)
.findFirst();
if (backTaskOpt.isPresent()) {
String deleteReason = backTaskOpt.get().getDeleteReason();
String changeParentActivityTo = deleteReason
.replace("Change parent activity to ", "")
.replace("Change activity to ", "");
if (org.springframework.util.CollectionUtils.isEmpty(valuableList)) {
throw new ServiceException("状态异常,首个节点进行了退回操作");
}
int j = valuableList.size() - 1;
for (; j >= 0; j--) {
Pair<String, List<BpmnHistoricTaskInstanceVO>> vPair = valuableList.get(j);
if (vPair.getLeft().equals(changeParentActivityTo)) {
break;
}
//去掉跳过的路径
executePath = executePath.subList(0, i);
}
if (previousNode == null || !previousNode.getId().equals(his.getActivityId())) {
executePath.add(flowElement);
}
valuableList = valuableList.subList(0, j);
} else {
valuableList.add(pair);
}
}
List<FlowElement> flowElements = bpmnProcessModelService.findFlowElements(processInstance.getProcessDefinitionId());
Map<String, FlowElement> flowElementMap = flowElements.stream().collect(Collectors.toMap(BaseElement::getId, f -> f));
AtomicInteger index = new AtomicInteger(0);
List<BpmnOptionalNodeDTO> resultList = executePath.stream()
.filter(flowElement -> !activeActivityIds.contains(flowElement.getId())) //排除当前节点
List<BpmnOptionalNodeDTO> resultList = valuableList
.stream()
.filter(pair -> !task.getTaskDefinitionKey().equals(pair.getLeft())) //排除当前节点
.map(pair -> flowElementMap.get(pair.getLeft()))
.filter(flowElement -> {
BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY);
return currentNodeType == NODE_TASK || currentNodeType == NODE_BUSINESS;