本篇文章为你整理了OA 系统工作流引擎 Camunda 实践(1)()的详细内容,包含有 OA 系统工作流引擎 Camunda 实践(1),希望能帮助你了解 OA 系统工作流引擎 Camunda 实践(1)。
Camunda是Activiti最大的贡献者之一(除Alfresco以外),同时也是它一个主 要的执行咨询合作伙伴。camunda表示Activiti可能太拘束于Alfresco对以文档为中心的工作流的需求(这个也是BPMN约束使然),而忽视了Activiti起步时 的更为普遍的BPM平台。camunda宣布他们正从Activiti 分裂出一个新的开源工程,那就是camunda BPM
官网
https://camunda.com/
下载
https://camunda.com/download/
Camunda文档中文站
http://camunda-cn.shaochenfeng.com/
学习路线知识点
https://www.processon.com/view/link/622da3ba1e085307a23dc108#map
由于公司业务限制,没有用到表单引擎和BPMN.js
模型是后端调用Camunda api(BpmnModelInstance、BpmnDiagram)自动生成的(老板嫌弃BPMN.js画的BPMN图丑),表单引擎比较复杂都是单独写,没用到在线表单生成
目前已实现功能点(国内常见的操作都能实现):发起,审批通过,驳回,转交他人审批,退回历史节点,前置加签/后置加签,撤回,重新发起,作废,转阅,催办
后面有部分代码,我也业务代码删除了,童鞋们可以参考一下,有疑问可以私信我。
效果图:
流程定义添加
用户发起:
审批:
后续相关代码实现
// 工作流引擎camunda-bpm依赖
implementation "org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter:7.16.0"
implementation "org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter-webapp:7.16.0"
implementation "org.camunda.bpm:camunda-engine-plugin-spin:7.16.0"
implementation "org.camunda.spin:camunda-spin-dataformat-all:1.16.0"
Camunda工具类
1 package com.oa.business.flow.utils.camunda;
3 import cn.hutool.core.bean.BeanUtil;
4 import cn.hutool.core.collection.CollUtil;
5 import cn.hutool.core.lang.Snowflake;
6 import cn.hutool.core.util.IdUtil;
7 import cn.hutool.core.util.ObjectUtil;
8 import cn.hutool.core.util.StrUtil;
9 import cn.hutool.json.JSONArray;
10 import cn.hutool.json.JSONObject;
11 import cn.hutool.json.JSONUtil;
12 import com.galileotime.oa.business.flow.utils.camunda.constant.CamundaEnum;
13 import com.galileotime.oa.business.flow.utils.camunda.pojo.ProcessPOJO;
14 import lombok.extern.slf4j.Slf4j;
15 import org.camunda.bpm.model.bpmn.Bpmn;
16 import org.camunda.bpm.model.bpmn.BpmnModelInstance;
17 import org.camunda.bpm.model.bpmn.instance.Process;
18 import org.camunda.bpm.model.bpmn.instance.*;
19 import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnDiagram;
20 import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnEdge;
21 import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnPlane;
22 import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnShape;
23 import org.camunda.bpm.model.bpmn.instance.camunda.CamundaExecutionListener;
24 import org.camunda.bpm.model.bpmn.instance.camunda.CamundaTaskListener;
25 import org.camunda.bpm.model.bpmn.instance.dc.Bounds;
26 import org.camunda.bpm.model.bpmn.instance.di.Waypoint;
27 import org.springframework.stereotype.Component;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
33 /**
34 * @author HeZeMin
35 * @className CamundaUtils
36 * @description Camunda工作流引擎工具类
37 * @date 2022/4/8 15:50
38 */
39 @Slf4j
40 @Component
41 public class CamundaModelUtils {
42 /**
43 *
44 * @Description 创建流程定义
45 * @Return: void
46 * @Author HeZeMin
47 * @Date 2022年04月08日 15:54
48 */
49 public String createExecutableProcess(HashMap String, Object param, Long userId) {
50 ProcessPOJO processPOJO = new ProcessPOJO();
51 BeanUtil.copyProperties(param.get("process"), processPOJO);
52 log.info(JSONUtil.toJsonStr(param));
54 //1、创建一个空的 BPMN 模型实例
55 BpmnModelInstance modelInstance = Bpmn.createEmptyModel();
57 //2、创建BPMN定义元素,设置目标名称空间,并将其添加到新创建的模型实例中
58 Definitions definitions = modelInstance.newInstance(Definitions.class);
59 definitions.setTargetNamespace("http://camunda.org/examples");
60 modelInstance.setDefinitions(definitions);
62 // di-对于图,需要创建一个图和一个平面元素。平面被设置在一个图对象中,图被添加为子元素
63 BpmnDiagram bpmnDiagram = modelInstance.newInstance(BpmnDiagram.class);
64 BpmnPlane plane = modelInstance.newInstance(BpmnPlane.class);
65 bpmnDiagram.setBpmnPlane(plane);
66 definitions.addChildElement(bpmnDiagram);
68 //3、创建流程
69 String procDefKey = CamundaEnum.PROCESS.getName() + this.id();
70 Process process = createElement(definitions, procDefKey, Process.class);
71 process.setName(processPOJO.getProcessName());
72 process.setExecutable(true);//可执行的流程
74 // di-平面元素添加process
75 plane.setBpmnElement(process);
77 //---业务代码处理start
78 //保存流程定义
79 //保存流程发起人用户
80 //保存流程发起人角色
81 //---业务代码处理end
83 //4、创建开始事件
84 StartEvent startEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), StartEvent.class);
85 startEvent.setCamundaInitiator("initiator");//发起人
86 this.drawBpmnShape(modelInstance, plane, startEvent.getId());// di-平面元素添加节点
88 //5、创建申请人节点
89 UserTask userTask = this.createElement(process, CamundaEnum.ACTIVITY.getName() + this.id(), UserTask.class);
90 userTask.setName("发起人");
91 userTask.setCamundaAssignee("${initiator}");
92 // di-平面元素添加节点
93 this.drawBpmnShape(modelInstance, plane, userTask.getId());
94 // 开始事件连线到申请人节点
95 SequenceFlow sequenceFlow = this.createSequenceFlow(process, startEvent, userTask);
96 // di-平面元素添加连线
97 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
99 //6、创建结束事件
100 EndEvent endEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), EndEvent.class);
101 // 结束监听器
102 ExtensionElements extensionElements = this.createElement(endEvent, "", ExtensionElements.class);
103 CamundaExecutionListener start = this.createElement(extensionElements, "", CamundaExecutionListener.class);
104 start.setCamundaDelegateExpression("#{EndEventListener}");
105 start.setCamundaEvent("start");//startend
106 CamundaExecutionListener end = this.createElement(extensionElements, "", CamundaExecutionListener.class);
107 end.setCamundaDelegateExpression("#{EndEventListener}");
108 end.setCamundaEvent("end");//startend
109 endEvent.setExtensionElements(extensionElements);
110 this.drawBpmnShape(modelInstance, plane, endEvent.getId());// di-平面元素添加节点
112 //7、处理节点数据-[递归算法]
113 this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(param.get("processModeel")), userId);
115 //8、验证模型
116 Bpmn.validateModel(modelInstance);
118 //9、转换为xml字符串
119 String xmlString = Bpmn.convertToString(modelInstance);
120 log.info(xmlString);
121 return xmlString;
122 }
123 /**
124 *
125 * @Description 修改流程定义
126 * @Return: void
127 * @Author HeZeMin
128 * @Date 2022年04月08日 15:54
129 */
130 public String updateExecutableProcess(HashMap String, Object param, Long userId) {
131 ProcessPOJO processPOJO = new ProcessPOJO();
132 BeanUtil.copyProperties(param.get("process"), processPOJO);
133 log.info(JSONUtil.toJsonStr(param));
135 //1、创建一个空的 BPMN 模型实例
136 BpmnModelInstance modelInstance = Bpmn.createEmptyModel();
138 //2、创建BPMN定义元素,设置目标名称空间,并将其添加到新创建的模型实例中
139 Definitions definitions = modelInstance.newInstance(Definitions.class);
140 definitions.setTargetNamespace("http://camunda.org/examples");
141 modelInstance.setDefinitions(definitions);
143 // di-对于图,需要创建一个图和一个平面元素。平面被设置在一个图对象中,图被添加为子元素
144 BpmnDiagram bpmnDiagram = modelInstance.newInstance(BpmnDiagram.class);
145 BpmnPlane plane = modelInstance.newInstance(BpmnPlane.class);
146 bpmnDiagram.setBpmnPlane(plane);
147 definitions.addChildElement(bpmnDiagram);
149 //3、创建流程
150 String procDefKey = processPOJO.getProcDefKey();
151 Process process = createElement(definitions, procDefKey, Process.class);
152 process.setName(processPOJO.getProcessName());
153 process.setExecutable(true);//可执行的流程
155 // di-平面元素添加process
156 plane.setBpmnElement(process);
158 //---业务代码处理start
159 //修改流程定义
160 //流程发起人用户全部逻辑删除
161 //流程发起人角色全部逻辑删除
162 //保存流程发起人用户
163 //保存流程发起人角色
164 //流程节点定义规则全部逻辑删除
165 //流程节点定义用户规则全部逻辑删除
166 //流程网关定义规则全部逻辑删除
167 //流程网关定义条件规则全部逻辑删除
168 //---业务代码处理end
170 //4、创建开始事件
171 StartEvent startEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), StartEvent.class);
172 startEvent.setCamundaInitiator("initiator");//发起人
173 this.drawBpmnShape(modelInstance, plane, startEvent.getId());// di-平面元素添加节点
175 //5、创建申请人节点
176 UserTask userTask = this.createElement(process, CamundaEnum.ACTIVITY.getName() + this.id(), UserTask.class);
177 userTask.setName("发起人");
178 userTask.setCamundaAssignee("${initiator}");
179 // di-平面元素添加节点
180 this.drawBpmnShape(modelInstance, plane, userTask.getId());
181 // 开始事件连线到申请人节点
182 SequenceFlow sequenceFlow = this.createSequenceFlow(process, startEvent, userTask);
183 // di-平面元素添加连线
184 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
186 //6、创建结束事件
187 EndEvent endEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), EndEvent.class);
188 // 结束监听器
189 ExtensionElements extensionElements = this.createElement(endEvent, "", ExtensionElements.class);
190 CamundaExecutionListener start = this.createElement(extensionElements, "", CamundaExecutionListener.class);
191 start.setCamundaDelegateExpression("#{EndEventListener}");
192 start.setCamundaEvent("start");//startend
193 CamundaExecutionListener end = this.createElement(extensionElements, "", CamundaExecutionListener.class);
194 end.setCamundaDelegateExpression("#{EndEventListener}");
195 end.setCamundaEvent("end");//startend
196 endEvent.setExtensionElements(extensionElements);
197 this.drawBpmnShape(modelInstance, plane, endEvent.getId());// di-平面元素添加节点
199 //7、处理节点数据-递归
200 this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(param.get("processModeel")), userId);
202 //8、验证模型
203 Bpmn.validateModel(modelInstance);
205 //9、转换为xml字符串
206 String xmlString = Bpmn.convertToString(modelInstance);
207 log.info(xmlString);
208 return xmlString;
209 }
210 /**
211 *迭代器
212 * @Description 迭代器
213 * @Param process: 流程DOM对象
214 * @Param previouEvent: 上一节点DOM对象
215 * @Param endEvent: 结束事件DOM对象
216 * @Param conditionMap: 网关条件
217 * @Param jsonStr: 参数json串
218 * @Return: void
219 * @Author HeZeMin
220 * @Date 2022年04月12日 10:35
221 */
222 public void iterate(BpmnModelInstance modelInstance, BpmnPlane plane, Process process, FlowNode previouEvent, FlowNode endEvent, HashMap String, String conditionMap, String jsonStr, Long userId) {
223 JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
224 process.getId();
225 if (ObjectUtil.isNotNull(jsonObject) jsonObject.size() 0) {
226 Integer nodeType = jsonObject.get("nodeType", Integer.class);
227 if (1 == nodeType 2 == nodeType) {// 1=审批人,2=执行人
228 Integer auditType = jsonObject.get("auditType", Integer.class);
229 Integer auditMethod = jsonObject.get("auditMethod", Integer.class);
230 Integer isAdminAudit = jsonObject.get("isAdminAudit", Integer.class);
231 String dataType = jsonObject.get("dataType", String.class);
232 String nodeName = jsonObject.get("nodeName", String.class);
233 String dataValue = jsonObject.get("dataValue", String.class);
234 // 创建用户任务节点
235 String id = CamundaEnum.ACTIVITY.getName() + this.id();
236 if (2 == nodeType) {// 执行人额外增加一个属性标识,不然不知道是执行人还是审批人
237 id = CamundaEnum.ACTIVITY.getName() + "executor_" + this.id();// 执行人标识
238 }
239 UserTask userTask = this.createElement(process, id, UserTask.class);
240 if (2 == nodeType) {
241 userTask.setName(StrUtil.isBlank(nodeName) ? "执行人" : nodeName);
242 } else {
243 userTask.setName(StrUtil.isBlank(nodeName) ? "审批人" : nodeName);
244 }
245 userTask.setCamundaAssignee("${assignee}");
246 // 创建多人签实例
247 MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = this.createElement(userTask, "", MultiInstanceLoopCharacteristics.class);
248 //审批人集合参数
249 multiInstanceLoopCharacteristics.setCamundaCollection("assigneeList_" + id);
250 //迭代集合
251 multiInstanceLoopCharacteristics.setCamundaElementVariable("assignee");
252 //完成条件 已完成数等于实例数
253 CompletionCondition completionCondition = this.createElement(multiInstanceLoopCharacteristics, "", CompletionCondition.class);
254 if (0 == auditMethod 1 == auditMethod) {// 或签
255 completionCondition.setTextContent("${nrOfCompletedInstances == 1}");
256 } else if (2 == auditMethod) {// 会签
257 completionCondition.setTextContent("${nrOfActiveInstances == nrOfInstances}");
258 } else {
259 completionCondition.setTextContent("${nrOfActiveInstances == nrOfInstances}");
260 }
261 multiInstanceLoopCharacteristics.setCompletionCondition(completionCondition);
262 // 并行,为true时就是顺序签
263 if (3 == auditMethod) {
264 multiInstanceLoopCharacteristics.setSequential(true);
265 } else {
266 multiInstanceLoopCharacteristics.setSequential(false);
267 }
268 userTask.setLoopCharacteristics(multiInstanceLoopCharacteristics);
270 // 站内信和提醒 监听器
271 ExtensionElements extensionElements = this.createElement(userTask, "", ExtensionElements.class);
272 CamundaTaskListener create = this.createElement(extensionElements, "", CamundaTaskListener.class);
273 create.setCamundaDelegateExpression("#{TaskMessageListener}");
274 create.setCamundaEvent("create");
275 CamundaTaskListener complete = this.createElement(extensionElements, "", CamundaTaskListener.class);
276 complete.setCamundaDelegateExpression("#{TaskMessageListener}");
277 complete.setCamundaEvent("complete");
278 userTask.setExtensionElements(extensionElements);
280 // di-平面元素添加节点
281 this.drawBpmnShape(modelInstance, plane, userTask.getId());
283 //--相关数据存入数据库start
284 //保存节点
285 //保存节点对应的数据
286 //--相关数据存入数据库end
287 JSONArray nextNodeDataList = (JSONArray) jsonObject.get("nextNodeData");
288 if (CollUtil.isNotEmpty(nextNodeDataList)) {//有下一个节点
289 SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
290 // di-平面元素添加连线
291 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
292 this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(nextNodeDataList.get(0)), userId);
293 } else {// 没有下一个节点了,连线结束事件
294 SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
295 SequenceFlow sequenceFlow1 = this.createSequenceFlow(process, userTask, endEvent);
296 // di-平面元素添加连线
297 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
298 // di-平面元素添加连线
299 this.drawBpmnEdge(modelInstance, plane, sequenceFlow1.getId());
300 }
301 } else if (3 == nodeType) {// 3=抄送人
302 Integer auditType = jsonObject.get("auditType", Integer.class);
303 Integer auditMethod = jsonObject.get("auditMethod", Integer.class);
304 Integer isAdminAudit = jsonObject.get("isAdminAudit", Integer.class);
305 String dataType = jsonObject.get("dataType", String.class);
306 String dataValue = jsonObject.get("dataValue", String.class);
307 String nodeName = jsonObject.get("nodeName", String.class);
308 // 创建用户任务节点
309 String id = CamundaEnum.ACTIVITY.getName() + "copy_" + this.id();
310 UserTask userTask = this.createElement(process, id, UserTask.class);
311 userTask.setName(StrUtil.isBlank(nodeName) ? "抄送人" : nodeName);
313 // 抄送监听器
314 ExtensionElements extensionElements = this.createElement(userTask, "", ExtensionElements.class);
315 CamundaTaskListener create = this.createElement(extensionElements, "", CamundaTaskListener.class);
316 create.setCamundaDelegateExpression("#{CopyListener}");
317 create.setCamundaEvent("create");
318 CamundaTaskListener complete = this.createElement(extensionElements, "", CamundaTaskListener.class);
319 complete.setCamundaDelegateExpression("#{CopyListener}");
320 complete.setCamundaEvent("complete");
321 userTask.setExtensionElements(extensionElements);
323 // di-平面元素添加节点
324 this.drawBpmnShape(modelInstance, plane, userTask.getId());
326 //--相关数据存入数据库
327 //保存节点
328 //保存节点对应的数据
329 //--相关数据存入数据库
331 JSONArray nextNodeDataList = (JSONArray) jsonObject.get("nextNodeData");
332 if (CollUtil.isNotEmpty(nextNodeDataList)) {//有下一个节点
333 SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
334 // di-平面元素添加连线
335 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
336 this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(nextNodeDataList.get(0)), userId);
337 } else {// 没有下一个节点了,连线结束事件
338 SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
339 SequenceFlow sequenceFlow1 = this.createSequenceFlow(process, userTask, endEvent);
340 // di-平面元素添加连线
341 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
342 // di-平面元素添加连线
343 this.drawBpmnEdge(modelInstance, plane, sequenceFlow1.getId());
344 }
345 } else if (4 == nodeType){// 4=条件分支,只有网关才会有下一节点数据和条件判断数据同时出现的情况
346 String nodeName = jsonObject.get("nodeName", String.class);
347 // 创建网关
348 String id = CamundaEnum.GATEWAY.getName() + this.id();
349 // 专属网关,直走一个条件
350 ExclusiveGateway gateway = this.createElement(process, id, ExclusiveGateway.class);
351 // 并行网关,所有条件都走
352 // ParallelGateway gateway = createElement(process, id, ParallelGateway.class);
353 SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, gateway, conditionMap);
355 // di-平面元素添加节点
356 this.drawBpmnShape(modelInstance, plane, gateway.getId());
357 // di-平面元素添加连线
358 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
360 //--相关数据存入数据库start
361 // 保存网关节点
362 //--相关数据存入数据库end
364 // 条件判断集合
365 JSONArray conditionList = (JSONArray) jsonObject.get("conditionList");
366 Iterator Object iterator = conditionList.iterator();
367 while (iterator.hasNext()) {
368 JSONObject condition = (JSONObject) iterator.next();
370 //--相关数据存入数据库start
371 // 保存网关节点条件判断
372 //--相关数据存入数据库end
374 // 网关表达式
375 StringBuilder textContent = new StringBuilder();
376 textContent.append("${");
377 if (StrUtil.isNotBlank(condition.get("conditionKey_", String.class))) {//两个条件
378 textContent.append("(");
379 if (StrUtil.contains("区间", condition.get("operator", String.class))) {
380 textContent.append(condition.get("targetValue1", String.class) + condition.get("targetValue1Operator", String.class) + condition.get("conditionKey", String.class))
381 .append(" ")
382 .append(condition.get("conditionKey", String.class) + condition.get("targetValue2Operator", String.class) + condition.get("targetValue2", String.class));
383 } else if (StrUtil.contains("包含", condition.get("operator", String.class))) {
384 List String stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
385 for (int i = 0; i stringList.size(); i++) {
386 String targetValue = stringList.get(i);
387 if (i == 0) {
388 textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
389 } else {
390 textContent.append(" ");
391 textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
392 }
393 }
394 } else if (StrUtil.contains("不包含", condition.get("operator", String.class))) {
395 List String stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
396 for (int i = 0; i stringList.size(); i++) {
397 String targetValue = stringList.get(i);
398 if (i == 0) {
399 textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
400 } else {
401 textContent.append(" ");
402 textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
403 }
404 }
405 } else {
406 textContent.append(condition.get("conditionKey", String.class) + condition.get("operator", String.class) + condition.get("targetValue", String.class));
407 }
408 textContent.append(") (");
409 if (StrUtil.contains("区间", condition.get("operator_", String.class))) {
410 textContent.append(condition.get("targetValue1_", String.class) + condition.get("targetValue1Operator_", String.class) + condition.get("conditionKey_", String.class))
411 .append(" ")
412 .append(condition.get("conditionKey_", String.class) + condition.get("targetValue2Operator_", String.class) + condition.get("targetValue2_", String.class));
413 } else if (StrUtil.contains("包含", condition.get("operator_", String.class))) {
414 List String stringList = StrUtil.split(condition.get("targetValue_", String.class), ",");
415 for (int i = 0; i stringList.size(); i++) {
416 String targetValue = stringList.get(i);
417 if (i == 0) {
418 textContent.append(condition.get("conditionKey_", String.class) + " == " + targetValue);
419 } else {
420 textContent.append(" ");
421 textContent.append(condition.get("conditionKey_", String.class) + " == " + targetValue);
422 }
423 }
424 } else if (StrUtil.contains("不包含", condition.get("operator_", String.class))) {
425 List String stringList = StrUtil.split(condition.get("targetValue_", String.class), ",");
426 for (int i = 0; i stringList.size(); i++) {
427 String targetValue = stringList.get(i);
428 if (i == 0) {
429 textContent.append(condition.get("conditionKey_", String.class) + " != " + targetValue);
430 } else {
431 textContent.append(" ");
432 textContent.append(condition.get("conditionKey_", String.class) + " != " + targetValue);
433 }
434 }
435 } else {
436 textContent.append(condition.get("conditionKey_", String.class) + condition.get("operator_", String.class) + condition.get("targetValue_", String.class));
437 }
438 textContent.append(")");
439 } else {// 一个条件
440 if (StrUtil.contains("区间", condition.get("operator", String.class))) {
441 textContent.append(condition.get("targetValue1", String.class) + condition.get("targetValue1Operator", String.class) + condition.get("conditionKey", String.class))
442 .append(" ")
443 .append(condition.get("conditionKey", String.class) + condition.get("targetValue2Operator", String.class) + condition.get("targetValue2", String.class));
444 } else if (StrUtil.contains("包含", condition.get("operator", String.class))) {
445 List String stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
446 for (int i = 0; i stringList.size(); i++) {
447 String targetValue = stringList.get(i);
448 if (i == 0) {
449 textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
450 } else {
451 textContent.append(" ");
452 textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
453 }
454 }
455 } else if (StrUtil.contains("不包含", condition.get("operator", String.class))) {
456 List String stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
457 for (int i = 0; i stringList.size(); i++) {
458 String targetValue = stringList.get(i);
459 if (i == 0) {
460 textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
461 } else {
462 textContent.append(" ");
463 textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
464 }
465 }
466 } else {
467 textContent.append(condition.get("conditionKey", String.class) + condition.get("operator", String.class) + condition.get("targetValue", String.class));
468 }
469 }
470 textContent.append("}");
471 JSONArray nextNodeDataList = (JSONArray) condition.get("nextNodeData");
472 if (CollUtil.isNotEmpty(nextNodeDataList)) {//有下一个节点
473 String conditionName = condition.get("conditionName", String.class);
474 HashMap String, String map = new HashMap ();
475 map.put("name", StrUtil.isBlank(conditionName) ? textContent.toString() : conditionName);
476 map.put("type", "");
477 map.put("textContent", textContent.toString());
478 this.iterate(modelInstance, plane, process, gateway, endEvent, map, JSONUtil.toJsonStr(nextNodeDataList.get(0)), userId);
479 } else {
480 SequenceFlow sequenceFlow1 = this.createSequenceFlow(process, gateway, endEvent);
481 // di-平面元素添加连线
482 this.drawBpmnEdge(modelInstance, plane, sequenceFlow1.getId());
483 // 一下注释代码暂时用不到,勿删
484 // 网关的下一个节点,不是条件下的
485 // JSONArray gatewayNnextNodeDataList = (JSONArray) jsonObject.get("nextNodeData");
486 // if (CollUtil.isNotEmpty(gatewayNnextNodeDataList)) {//有下一个节点
487 // this.createSequenceFlow(process, startEvent, gateway, conditionMap);
488 // this.iterate(process, gateway, endEvent, null, JSONUtil.toJsonStr(gatewayNnextNodeDataList.get(0)));
489 // } else {// 没有下一个节点了,连线结束事件
490 // this.createSequenceFlow(process, gateway, endEvent, conditionMap);
491 // }
492 }
493 }
494 }
495 } else {
496 // 开始事件连线到结束事件
497 SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, endEvent);
498 // di-平面元素添加连线
499 this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
500 }
501 }
502 /**
503 * Description:id生成器
504 * @Author HeZeMin
505 * @Date 2022年04月21日 15:25
506 */
507 protected String id() {
508 Snowflake snowflake = IdUtil.getSnowflake(1, 1);
509 return snowflake.nextIdStr();
510 }
511 /**
512 * Description:创建元素-在父元素下创建子元素-
513 * @Author HeZeMin
514 * @Date 2022年04月21日 15:24
515 */
516 protected T extends BpmnModelElementInstance T createElement(BpmnModelElementInstance parentElement, String id, Class T elementClass) {
517 T element = parentElement.getModelInstance().newInstance(elementClass);
518 if (StrUtil.isNotBlank(id)) {
519 element.setAttributeValue("id", id, true);
520 }
521 parentElement.addChildElement(element);
522 return element;
523 }
524 /**
525 * Description:创建元素-在父元素下创建子元。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。