OA 系统工作流引擎 Camunda 实践(1)()

  本篇文章为你整理了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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: