From 89f4b7007a61c49b34780c5e10e8f5cb87382223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 22 Jun 2026 16:47:13 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E6=B5=81=E7=A8=8B=E5=8F=98=E9=87=8F=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=80=80=E5=9B=9E=E9=80=89=E6=8B=A9=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/FlwTaskServiceImpl.java | 94 ++++++++++++++++++- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index 95f20af7f..80e5087c0 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -29,12 +29,15 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.utils.IdGeneratorUtil; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.warm.flow.core.FlowEngine; +import org.dromara.warm.flow.core.constant.ExceptionCons; +import org.dromara.warm.flow.core.dto.FlowCombine; import org.dromara.warm.flow.core.dto.FlowParams; import org.dromara.warm.flow.core.entity.*; import org.dromara.warm.flow.core.enums.CooperateType; import org.dromara.warm.flow.core.enums.NodeType; import org.dromara.warm.flow.core.enums.SkipType; import org.dromara.warm.flow.core.enums.UserType; +import org.dromara.warm.flow.core.exception.FlowException; import org.dromara.warm.flow.core.service.*; import org.dromara.warm.flow.core.utils.ExpressionUtil; import org.dromara.warm.flow.core.utils.MapUtil; @@ -544,16 +547,30 @@ public class FlwTaskServiceImpl implements IFlwTaskService { return nodeService.getByNodeCodes(Collections.singletonList(node.getAnyNodeSkip()), task.getDefinitionId()); } //获取可驳回的前置节点 - List nodes = nodeService.previousNodeList(task.getDefinitionId(), nowNodeCode); + Long definitionId = task.getDefinitionId(); + FlowCombine flowCombine = defService.getFlowCombineNoDef(definitionId); + Map nodeMap = getPreviousNodeMap(nowNodeCode, flowCombine); List hisTaskList = hisTaskService.getByInsId(task.getInstanceId()); - Map nodeMap = StreamUtils.toIdentityMap(nodes, Node::getNodeCode); + Set reachableNodeCodes = new HashSet<>(); + if (CollUtil.isNotEmpty(hisTaskList)) { + Instance instance = insService.getById(task.getInstanceId()); + if (ObjectUtil.isNull(instance)) { + throw new ServiceException("流程实例不存在"); + } + collectReachableNodeCodes(reachableNodeCodes, instance, flowCombine); + if (!reachableNodeCodes.contains(nowNodeCode)) { + reachableNodeCodes.clear(); + } + } + Set added = new HashSet<>(); List backNodeList = new ArrayList<>(); for (HisTask hisTask : hisTaskList) { Node nodeValue = nodeMap.get(hisTask.getNodeCode()); if (nodeValue != null && NodeType.BETWEEN.getKey().equals(nodeValue.getNodeType()) + && (CollUtil.isEmpty(reachableNodeCodes) || reachableNodeCodes.contains(nodeValue.getNodeCode())) && added.add(nodeValue.getNodeCode())) { backNodeList.add(nodeValue); } @@ -562,7 +579,78 @@ public class FlwTaskServiceImpl implements IFlwTaskService { Collections.reverse(backNodeList); return backNodeList; } - return nodes; + if (CollUtil.isNotEmpty(hisTaskList)) { + return Collections.emptyList(); + } + return StreamUtils.filter(nodeMap.values(), e -> NodeType.BETWEEN.getKey().equals(e.getNodeType())); + } + + private Map getPreviousNodeMap(String nodeCode, FlowCombine flowCombine) { + if (ObjectUtil.isNull(flowCombine) || CollUtil.isEmpty(flowCombine.getAllNodes()) || CollUtil.isEmpty(flowCombine.getAllSkips())) { + return Collections.emptyMap(); + } + Map allNodeMap = StreamUtils.toIdentityMap(flowCombine.getAllNodes(), Node::getNodeCode); + Map> previousSkipMap = new HashMap<>(); + for (Skip skip : flowCombine.getAllSkips()) { + previousSkipMap.computeIfAbsent(skip.getNextNodeCode(), k -> new ArrayList<>()).add(skip); + } + + Map previousNodeMap = new LinkedHashMap<>(); + Set visitedNodeCodes = new HashSet<>(); + Deque nodeQueue = new ArrayDeque<>(); + visitedNodeCodes.add(nodeCode); + nodeQueue.add(nodeCode); + while (CollUtil.isNotEmpty(nodeQueue)) { + String currentNodeCode = nodeQueue.poll(); + List previousSkips = previousSkipMap.get(currentNodeCode); + if (CollUtil.isEmpty(previousSkips)) { + continue; + } + for (Skip previousSkip : previousSkips) { + String previousNodeCode = previousSkip.getNowNodeCode(); + if (!visitedNodeCodes.add(previousNodeCode)) { + continue; + } + Node previousNode = allNodeMap.get(previousNodeCode); + if (ObjectUtil.isNull(previousNode)) { + continue; + } + previousNodeMap.put(previousNodeCode, previousNode); + nodeQueue.add(previousNodeCode); + } + } + return previousNodeMap; + } + + private void collectReachableNodeCodes(Set nodeCodes, Instance instance, FlowCombine flowCombine) { + if (ObjectUtil.isNull(flowCombine) || CollUtil.isEmpty(flowCombine.getAllNodes())) { + return; + } + Deque nodeQueue = new ArrayDeque<>(); + flowCombine.getAllNodes().stream() + .filter(e -> NodeType.START.getKey().equals(e.getNodeType())) + .findFirst() + .ifPresent(nodeQueue::add); + + while (CollUtil.isNotEmpty(nodeQueue)) { + Node currentNode = nodeQueue.poll(); + if (ObjectUtil.isNull(currentNode) || !nodeCodes.add(currentNode.getNodeCode())) { + continue; + } + + try { + List nextNodes = nodeService.getNextNodeList(currentNode, null, SkipType.PASS.getKey(), + instance.getVariableMap(), null, flowCombine); + if (CollUtil.isNotEmpty(nextNodes)) { + nodeQueue.addAll(nextNodes); + } + } catch (FlowException e) { + // 条件变量缺失时跳过当前分支,其他引擎异常继续抛出。 + if (!ExceptionCons.NULL_CONDITION_VALUE.equals(e.getMessage())) { + throw e; + } + } + } } /**