mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	仿钉钉流程设计-排他网关实现
This commit is contained in:
		| @ -18,8 +18,7 @@ import java.util.Objects; | |||||||
| public enum BpmSimpleModelNodeType implements IntArrayValuable { | public enum BpmSimpleModelNodeType implements IntArrayValuable { | ||||||
|  |  | ||||||
|     // TODO @jaosn:-1、0、1、4、-2 是前端已经定义好的么?感觉未来可以考虑搞成和 BPMN 尽量一致的单词哈;类似 usertask 用户审批; |     // TODO @jaosn:-1、0、1、4、-2 是前端已经定义好的么?感觉未来可以考虑搞成和 BPMN 尽量一致的单词哈;类似 usertask 用户审批; | ||||||
|     START_NODE(-1, "开始节点"), |     START_EVENT_NODE(0, "开始节点"), | ||||||
|     START_USER_NODE(0, "发起人结点"), |  | ||||||
|     APPROVE_USER_NODE (1, "审批人节点"), |     APPROVE_USER_NODE (1, "审批人节点"), | ||||||
|     EXCLUSIVE_GATEWAY_NODE(4, "排他网关"), |     EXCLUSIVE_GATEWAY_NODE(4, "排他网关"), | ||||||
|     END_NODE(-2, "结束节点"); |     END_NODE(-2, "结束节点"); | ||||||
|  | |||||||
| @ -358,44 +358,72 @@ public class BpmnModelUtils { | |||||||
|         // 单独添加 end event 节点 |         // 单独添加 end event 节点 | ||||||
|         addBpmnEndEventNode(mainProcess); |         addBpmnEndEventNode(mainProcess); | ||||||
|         // 添加节点之间的连线 Sequence Flow |         // 添加节点之间的连线 Sequence Flow | ||||||
|         addBpmnSequenceFlow(mainProcess, simpleModelNode); |         addBpmnSequenceFlow(mainProcess, simpleModelNode, BpmnModelConstants.END_EVENT_ID); | ||||||
|         // 自动布局 |         // 自动布局 | ||||||
|         new BpmnAutoLayout(bpmnModel).execute(); |         new BpmnAutoLayout(bpmnModel).execute(); | ||||||
|         return bpmnModel; |         return bpmnModel; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static void addBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node) { |     private static void addBpmnSequenceFlow(Process mainProcess, BpmSimpleModelNodeVO node, String endId) { | ||||||
|         // 节点为 null 退出 |         // 节点为 null 退出 | ||||||
|         if (node == null || node.getId() == null) { |         if (node == null || node.getId() == null) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         BpmSimpleModelNodeVO childNode = node.getChildNode(); |         BpmSimpleModelNodeVO childNode = node.getChildNode(); | ||||||
|         // 如果后续节点为 null. 添加与结束节点的连线 |         // 如果不是网关节点、且后续节点为 null. 添加与结束节点的连线 | ||||||
|         if (childNode == null || childNode.getId() == null) { |         if (!BpmSimpleModelNodeType.isGatewayNode(node.getType()) && (childNode == null || childNode.getId() == null)) { | ||||||
|             addBpmnSequenceFlowElement(mainProcess, node.getId(), BpmnModelConstants.END_EVENT_ID, null); |             addBpmnSequenceFlowElement(mainProcess, node.getId(), endId, null, null); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); |         BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(node.getType()); | ||||||
|         Assert.notNull(nodeType, "模型节点类型不支持"); |         Assert.notNull(nodeType, "模型节点类型不支持"); | ||||||
|         switch (nodeType) { |         switch (nodeType) { | ||||||
|             case START_NODE: |             case START_EVENT_NODE: | ||||||
|             case START_USER_NODE: |             case APPROVE_USER_NODE: { | ||||||
|             case APPROVE_USER_NODE: |                 addBpmnSequenceFlowElement(mainProcess, node.getId(), childNode.getId(), null, null); | ||||||
|                 addBpmnSequenceFlowElement(mainProcess, node.getId(), childNode.getId(), null); |                 // 递归调用后续节点 | ||||||
|  |                 addBpmnSequenceFlow(mainProcess, childNode,endId); | ||||||
|                 break; |                 break; | ||||||
|  |             } | ||||||
|  |             case EXCLUSIVE_GATEWAY_NODE: { | ||||||
|  |                 String gateWayEndId = ( childNode == null || childNode.getId() == null ) ? BpmnModelConstants.END_EVENT_ID : childNode.getId(); | ||||||
|  |                 List<BpmSimpleModelNodeVO> 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: { |             default: { | ||||||
|                 // TODO 其它节点类型的实现 |                 // 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); |         SequenceFlow sequenceFlow = new SequenceFlow(sourceId, targetId); | ||||||
|         if (StrUtil.isNotEmpty(conditionExpression)) { |         if (StrUtil.isNotEmpty(conditionExpression)) { | ||||||
|             sequenceFlow.setConditionExpression(conditionExpression); |             sequenceFlow.setConditionExpression(conditionExpression); | ||||||
|         } |         } | ||||||
|  |         if (StrUtil.isNotEmpty(seqFlowId)) { | ||||||
|  |             sequenceFlow.setId(seqFlowId); | ||||||
|  |         } | ||||||
|         mainProcess.addFlowElement(sequenceFlow); |         mainProcess.addFlowElement(sequenceFlow); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -407,13 +435,15 @@ public class BpmnModelUtils { | |||||||
|         BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(simpleModelNode.getType()); |         BpmSimpleModelNodeType nodeType = BpmSimpleModelNodeType.valueOf(simpleModelNode.getType()); | ||||||
|         Assert.notNull(nodeType, "模型节点类型不支持"); |         Assert.notNull(nodeType, "模型节点类型不支持"); | ||||||
|         switch (nodeType) { |         switch (nodeType) { | ||||||
|             case START_NODE: |             case START_EVENT_NODE: | ||||||
|                 addBpmnStartEventNode(mainProcess, simpleModelNode); |                 addBpmnStartEventNode(mainProcess, simpleModelNode); | ||||||
|                 break; |                 break; | ||||||
|             case START_USER_NODE: |  | ||||||
|             case APPROVE_USER_NODE: |             case APPROVE_USER_NODE: | ||||||
|                 addBpmnUserTaskEventNode(mainProcess, simpleModelNode); |                 addBpmnUserTaskEventNode(mainProcess, simpleModelNode); | ||||||
|                 break; |                 break; | ||||||
|  |             case EXCLUSIVE_GATEWAY_NODE: | ||||||
|  |                 addBpmnExclusiveGatewayNode(mainProcess, simpleModelNode); | ||||||
|  |                 break; | ||||||
|             default: { |             default: { | ||||||
|                 // TODO 其它节点类型的实现 |                 // TODO 其它节点类型的实现 | ||||||
|             } |             } | ||||||
| @ -427,7 +457,7 @@ public class BpmnModelUtils { | |||||||
|         // 如果是网关类型接口. 递归添加条件节点 |         // 如果是网关类型接口. 递归添加条件节点 | ||||||
|         if (BpmSimpleModelNodeType.isGatewayNode(simpleModelNode.getType()) && ArrayUtil.isNotEmpty(simpleModelNode.getConditionNodes())) { |         if (BpmSimpleModelNodeType.isGatewayNode(simpleModelNode.getType()) && ArrayUtil.isNotEmpty(simpleModelNode.getConditionNodes())) { | ||||||
|             for (BpmSimpleModelNodeVO node : 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) { |     private static void addBpmnEndEventNode(Process mainProcess) { | ||||||
|         EndEvent endEvent = new EndEvent(); |         EndEvent endEvent = new EndEvent(); | ||||||
|         endEvent.setId(BpmnModelConstants.END_EVENT_ID); |         endEvent.setId(BpmnModelConstants.END_EVENT_ID); | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ import java.util.Map; | |||||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 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.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.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_PARAM; | ||||||
| import static cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants.USER_TASK_CANDIDATE_STRATEGY; | 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; |             return null; | ||||||
|         } |         } | ||||||
|         BpmSimpleModelNodeVO rootNode = new BpmSimpleModelNodeVO(); |         BpmSimpleModelNodeVO rootNode = new BpmSimpleModelNodeVO(); | ||||||
|         rootNode.setType(START_NODE.getType()); |         rootNode.setType(START_EVENT_NODE.getType()); | ||||||
|         rootNode.setId(startEvent.getId()); |         rootNode.setId(startEvent.getId()); | ||||||
|         rootNode.setName(startEvent.getName()); |         rootNode.setName(startEvent.getName()); | ||||||
|         recursiveBuildSimpleModelNode(startEvent, rootNode); |         recursiveBuildSimpleModelNode(startEvent, rootNode); | ||||||
| @ -129,7 +129,7 @@ public class BpmSimpleModelServiceImpl implements BpmSimpleModelService { | |||||||
|  |  | ||||||
|     private List<SequenceFlow> validateCanConvertSimpleNode(BpmSimpleModelNodeType nodeType, FlowNode currentFlowNode) { |     private List<SequenceFlow> validateCanConvertSimpleNode(BpmSimpleModelNodeType nodeType, FlowNode currentFlowNode) { | ||||||
|         switch (nodeType) { |         switch (nodeType) { | ||||||
|             case START_NODE: |             case START_EVENT_NODE: | ||||||
|             case APPROVE_USER_NODE: { |             case APPROVE_USER_NODE: { | ||||||
|                 List<SequenceFlow> outgoingFlows = currentFlowNode.getOutgoingFlows(); |                 List<SequenceFlow> outgoingFlows = currentFlowNode.getOutgoingFlows(); | ||||||
|                 if (CollUtil.isNotEmpty(outgoingFlows) && outgoingFlows.size() > 1) { |                 if (CollUtil.isNotEmpty(outgoingFlows) && outgoingFlows.size() > 1) { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 jason
					jason