From d88718071d649146b428485fe02e51d40f72a47b Mon Sep 17 00:00:00 2001 From: jason <2667446@qq.com> Date: Tue, 2 Apr 2024 20:50:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=BF=E9=92=89=E9=92=89=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1-=E6=8E=92=E4=BB=96=E7=BD=91=E5=85=B3?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../definition/BpmSimpleModelNodeType.java | 3 +- .../flowable/core/util/BpmnModelUtils.java | 69 +++++++++++++++---- .../definition/BpmSimpleModelServiceImpl.java | 6 +- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java index e607a1466..75889985e 100644 --- a/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java +++ b/yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/definition/BpmSimpleModelNodeType.java @@ -18,8 +18,7 @@ import java.util.Objects; public enum BpmSimpleModelNodeType implements IntArrayValuable { // TODO @jaosn:-1、0、1、4、-2 是前端已经定义好的么?感觉未来可以考虑搞成和 BPMN 尽量一致的单词哈;类似 usertask 用户审批; - START_NODE(-1, "开始节点"), - START_USER_NODE(0, "发起人结点"), + START_EVENT_NODE(0, "开始节点"), APPROVE_USER_NODE (1, "审批人节点"), EXCLUSIVE_GATEWAY_NODE(4, "排他网关"), END_NODE(-2, "结束节点"); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java index 7facfce35..17c36623b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java @@ -358,44 +358,72 @@ public class BpmnModelUtils { // 单独添加 end event 节点 addBpmnEndEventNode(mainProcess); // 添加节点之间的连线 Sequence Flow - addBpmnSequenceFlow(mainProcess, simpleModelNode); + addBpmnSequenceFlow(mainProcess, simpleModelNode, BpmnModelConstants.END_EVENT_ID); // 自动布局 new BpmnAutoLayout(bpmnModel).execute(); return bpmnModel; } - private static void addBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node) { + private static void addBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String endId) { // 节点为 null 退出 if (node == null || node.getId() == null) { return; } BpmSimpleModelNodeVO childNode = node.getChildNode(); - // 如果后续节点为 null. 添加与结束节点的连线 - if (childNode == null || childNode.getId() == null) { - addBpmnSequenceFlowElement(mainProcess, node.getId(), BpmnModelConstants.END_EVENT_ID, null); + // 如果不是网关节点、且后续节点为 null. 添加与结束节点的连线 + if (!BpmSimpleModelNodeType.isGatewayNode(node.getType()) && (childNode == null || childNode.getId() == null)) { + addBpmnSequenceFlowElement(mainProcess, node.getId(), endId, null, null); return; } BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); Assert.notNull(nodeType, "模型节点类型不支持"); switch (nodeType) { - case START_NODE: - case START_USER_NODE: - case APPROVE_USER_NODE: - addBpmnSequenceFlowElement(mainProcess, node.getId(), childNode.getId(), null); + case START_EVENT_NODE: + case APPROVE_USER_NODE: { + addBpmnSequenceFlowElement(mainProcess, node.getId(), childNode.getId(), null, null); + // 递归调用后续节点 + addBpmnSequenceFlow(mainProcess, childNode,endId); break; + } + case EXCLUSIVE_GATEWAY_NODE: { + String gateWayEndId = ( childNode == null || childNode.getId() == null ) ? BpmnModelConstants.END_EVENT_ID : childNode.getId(); + List conditionNodes = node.getConditionNodes(); + Assert.notEmpty(conditionNodes, "网关节点的条件节点不能为空"); + for (int i = 0; i < conditionNodes.size(); i++) { + BpmSimpleModelNodeVO item = conditionNodes.get(i); + BpmSimpleModelNodeVO nextNodeOnCondition = getNextNodeOnCondition(item); + if (nextNodeOnCondition != null && nextNodeOnCondition.getId() != null) { + addBpmnSequenceFlowElement(mainProcess, node.getId(), nextNodeOnCondition.getId(), + String.format("%s_SequenceFlow_%d", node.getId(), i+1), null); + addBpmnSequenceFlow(mainProcess, nextNodeOnCondition, gateWayEndId); + } else { + addBpmnSequenceFlowElement(mainProcess, node.getId(), gateWayEndId, + String.format("%s_SequenceFlow_%d", node.getId(), i+1), null); + } + } + // 递归调用后续节点 + addBpmnSequenceFlow(mainProcess, childNode, endId); + break; + } default: { // TODO 其它节点类型的实现 } } - // 递归调用后续节点 - addBpmnSequenceFlow(mainProcess, childNode); + } - private static void addBpmnSequenceFlowElement(Process mainProcess, String sourceId, String targetId, String conditionExpression) { + private static BpmSimpleModelNodeVO getNextNodeOnCondition(BpmSimpleModelNodeVO conditionNode) { + return conditionNode.getChildNode(); + } + + private static void addBpmnSequenceFlowElement(Process mainProcess, String sourceId, String targetId, String seqFlowId, String conditionExpression) { SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId); if (StrUtil.isNotEmpty(conditionExpression)) { sequenceFlow.setConditionExpression(conditionExpression); } + if (StrUtil.isNotEmpty(seqFlowId)) { + sequenceFlow.setId(seqFlowId); + } mainProcess.addFlowElement(sequenceFlow); } @@ -407,13 +435,15 @@ public class BpmnModelUtils { BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(simpleModelNode.getType()); Assert.notNull(nodeType, "模型节点类型不支持"); switch (nodeType) { - case START_NODE: + case START_EVENT_NODE: addBpmnStartEventNode(mainProcess, simpleModelNode); break; - case START_USER_NODE: case APPROVE_USER_NODE: addBpmnUserTaskEventNode(mainProcess, simpleModelNode); break; + case EXCLUSIVE_GATEWAY_NODE: + addBpmnExclusiveGatewayNode(mainProcess, simpleModelNode); + break; default: { // TODO 其它节点类型的实现 } @@ -427,7 +457,7 @@ public class BpmnModelUtils { // 如果是网关类型接口. 递归添加条件节点 if (BpmSimpleModelNodeType.isGatewayNode(simpleModelNode.getType()) && ArrayUtil.isNotEmpty(simpleModelNode.getConditionNodes())) { for (BpmSimpleModelNodeVO node : simpleModelNode.getConditionNodes()) { - addBpmnFlowNode(mainProcess, node); + addBpmnFlowNode(mainProcess, node.getChildNode()); } } @@ -437,6 +467,15 @@ public class BpmnModelUtils { } } + private static void addBpmnExclusiveGatewayNode(Process mainProcess, BpmSimpleModelNodeVO node) { + Assert.notEmpty(node.getConditionNodes(), "网关节点的条件节点不能为空"); + ExclusiveGateway exclusiveGateway = new ExclusiveGateway(); + exclusiveGateway.setId(node.getId()); + // 条件节点的最后一个条件为 网关的 default sequence flow + exclusiveGateway.setDefaultFlow(String.format("%s_SequenceFlow_%d", node.getId(), node.getConditionNodes().size())); + mainProcess.addFlowElement(exclusiveGateway); + } + private static void addBpmnEndEventNode(Process mainProcess) { EndEvent endEvent = new EndEvent(); endEvent.setId(BpmnModelConstants.END_EVENT_ID); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmSimpleModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmSimpleModelServiceImpl.java index bc34a8acb..a632d2911 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmSimpleModelServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmSimpleModelServiceImpl.java @@ -20,7 +20,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.CONVERT_TO_SIMPLE_MODEL_NOT_SUPPORT; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.MODEL_NOT_EXISTS; -import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.START_NODE; +import static cn.iocoder.yudao.module.bpm.enums.definition.BpmSimpleModelNodeType.START_EVENT_NODE; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_CANDIDATE_PARAM; import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY; @@ -85,7 +85,7 @@ public class BpmSimpleModelServiceImpl implements BpmSimpleModelService { return null; } BpmSimpleModelNodeVO rootNode = new BpmSimpleModelNodeVO(); - rootNode.setType(START_NODE.getType()); + rootNode.setType(START_EVENT_NODE.getType()); rootNode.setId(startEvent.getId()); rootNode.setName(startEvent.getName()); recursiveBuildSimpleModelNode(startEvent, rootNode); @@ -129,7 +129,7 @@ public class BpmSimpleModelServiceImpl implements BpmSimpleModelService { private List validateCanConvertSimpleNode(BpmSimpleModelNodeType nodeType, FlowNode currentFlowNode) { switch (nodeType) { - case START_NODE: + case START_EVENT_NODE: case APPROVE_USER_NODE: { List outgoingFlows = currentFlowNode.getOutgoingFlows(); if (CollUtil.isNotEmpty(outgoingFlows) && outgoingFlows.size() > 1) {