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

本文分享了作者在公司中使用Camunda作为工作流引擎的实践经验,包括Camunda与Activiti的关系、Camunda的特点及官网资源。文章指出,由于业务需求,流程模型和表单都是后端自动生成,实现了常见功能如发起、审批、驳回等,并提供了部分代码示例和截图。
摘要由CSDN通过智能技术生成

审核人员看清楚再审核,我是把自己公司的案例分析一下,  这哪是广告???

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工具类

package com.oa.business.flow.utils.camunda;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.galileotime.oa.business.flow.utils.camunda.constant.CamundaEnum;
import com.galileotime.oa.business.flow.utils.camunda.pojo.ProcessPOJO;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.bpmn.instance.Process;
import org.camunda.bpm.model.bpmn.instance.*;
import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnDiagram;
import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnEdge;
import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnPlane;
import org.camunda.bpm.model.bpmn.instance.bpmndi.BpmnShape;
import org.camunda.bpm.model.bpmn.instance.camunda.CamundaExecutionListener;
import org.camunda.bpm.model.bpmn.instance.camunda.CamundaTaskListener;
import org.camunda.bpm.model.bpmn.instance.dc.Bounds;
import org.camunda.bpm.model.bpmn.instance.di.Waypoint;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * @author HeZeMin
 * @className CamundaUtils
 * @description Camunda工作流引擎工具类
 * @date 2022/4/8 15:50
 */
@Slf4j
@Component
public class CamundaModelUtils {
    /**
     *
     * @Description 创建流程定义
     * @Return: void
     * @Author HeZeMin
     * @Date 2022年04月08日 15:54
     */
    public String createExecutableProcess(HashMap<String, Object> param, Long userId) {
        ProcessPOJO processPOJO = new ProcessPOJO();
        BeanUtil.copyProperties(param.get("process"), processPOJO);
        log.info(JSONUtil.toJsonStr(param));

        //1、创建一个空的 BPMN 模型实例
        BpmnModelInstance modelInstance = Bpmn.createEmptyModel();

        //2、创建BPMN定义元素,设置目标名称空间,并将其添加到新创建的模型实例中
        Definitions definitions = modelInstance.newInstance(Definitions.class);
        definitions.setTargetNamespace("http://camunda.org/examples");
        modelInstance.setDefinitions(definitions);

        // di-对于图,需要创建一个图和一个平面元素。平面被设置在一个图对象中,图被添加为子元素
        BpmnDiagram bpmnDiagram = modelInstance.newInstance(BpmnDiagram.class);
        BpmnPlane plane = modelInstance.newInstance(BpmnPlane.class);
        bpmnDiagram.setBpmnPlane(plane);
        definitions.addChildElement(bpmnDiagram);

        //3、创建流程
        String procDefKey = CamundaEnum.PROCESS.getName() + this.id();
        Process process = createElement(definitions, procDefKey, Process.class);
        process.setName(processPOJO.getProcessName());
        process.setExecutable(true);//可执行的流程

        // di-平面元素添加process
        plane.setBpmnElement(process);

        //---业务代码处理start
        //保存流程定义
        //保存流程发起人用户
        //保存流程发起人角色
        //---业务代码处理end

        //4、创建开始事件
        StartEvent startEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), StartEvent.class);
        startEvent.setCamundaInitiator("initiator");//发起人
        this.drawBpmnShape(modelInstance, plane, startEvent.getId());// di-平面元素添加节点

        //5、创建申请人节点
        UserTask userTask = this.createElement(process, CamundaEnum.ACTIVITY.getName() + this.id(), UserTask.class);
        userTask.setName("发起人");
        userTask.setCamundaAssignee("${initiator}");
        // di-平面元素添加节点
        this.drawBpmnShape(modelInstance, plane, userTask.getId());
        // 开始事件连线到申请人节点
        SequenceFlow sequenceFlow = this.createSequenceFlow(process, startEvent, userTask);
        // di-平面元素添加连线
        this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());

        //6、创建结束事件
        EndEvent endEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), EndEvent.class);
        // 结束监听器
        ExtensionElements extensionElements = this.createElement(endEvent, "", ExtensionElements.class);
        CamundaExecutionListener start = this.createElement(extensionElements, "", CamundaExecutionListener.class);
        start.setCamundaDelegateExpression("#{EndEventListener}");
        start.setCamundaEvent("start");//start||end
        CamundaExecutionListener end = this.createElement(extensionElements, "", CamundaExecutionListener.class);
        end.setCamundaDelegateExpression("#{EndEventListener}");
        end.setCamundaEvent("end");//start||end
        endEvent.setExtensionElements(extensionElements);
        this.drawBpmnShape(modelInstance, plane, endEvent.getId());// di-平面元素添加节点

        //7、处理节点数据-[递归算法]
        this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(param.get("processModeel")), userId);

        //8、验证模型
        Bpmn.validateModel(modelInstance);

        //9、转换为xml字符串
        String xmlString = Bpmn.convertToString(modelInstance);
        log.info(xmlString);
        return xmlString;
    }
    /**
     *
     * @Description 修改流程定义
     * @Return: void
     * @Author HeZeMin
     * @Date 2022年04月08日 15:54
     */
    public String updateExecutableProcess(HashMap<String, Object> param, Long userId) {
        ProcessPOJO processPOJO = new ProcessPOJO();
        BeanUtil.copyProperties(param.get("process"), processPOJO);
        log.info(JSONUtil.toJsonStr(param));

        //1、创建一个空的 BPMN 模型实例
        BpmnModelInstance modelInstance = Bpmn.createEmptyModel();

        //2、创建BPMN定义元素,设置目标名称空间,并将其添加到新创建的模型实例中
        Definitions definitions = modelInstance.newInstance(Definitions.class);
        definitions.setTargetNamespace("http://camunda.org/examples");
        modelInstance.setDefinitions(definitions);

        // di-对于图,需要创建一个图和一个平面元素。平面被设置在一个图对象中,图被添加为子元素
        BpmnDiagram bpmnDiagram = modelInstance.newInstance(BpmnDiagram.class);
        BpmnPlane plane = modelInstance.newInstance(BpmnPlane.class);
        bpmnDiagram.setBpmnPlane(plane);
        definitions.addChildElement(bpmnDiagram);

        //3、创建流程
        String procDefKey = processPOJO.getProcDefKey();
        Process process = createElement(definitions, procDefKey, Process.class);
        process.setName(processPOJO.getProcessName());
        process.setExecutable(true);//可执行的流程

        // di-平面元素添加process
        plane.setBpmnElement(process);

        //---业务代码处理start
        //修改流程定义
        //流程发起人用户全部逻辑删除
        //流程发起人角色全部逻辑删除
        //保存流程发起人用户
        //保存流程发起人角色
        //流程节点定义规则全部逻辑删除
        //流程节点定义用户规则全部逻辑删除
        //流程网关定义规则全部逻辑删除
        //流程网关定义条件规则全部逻辑删除
        //---业务代码处理end

        //4、创建开始事件
        StartEvent startEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), StartEvent.class);
        startEvent.setCamundaInitiator("initiator");//发起人
        this.drawBpmnShape(modelInstance, plane, startEvent.getId());// di-平面元素添加节点

        //5、创建申请人节点
        UserTask userTask = this.createElement(process, CamundaEnum.ACTIVITY.getName() + this.id(), UserTask.class);
        userTask.setName("发起人");
        userTask.setCamundaAssignee("${initiator}");
        // di-平面元素添加节点
        this.drawBpmnShape(modelInstance, plane, userTask.getId());
        // 开始事件连线到申请人节点
        SequenceFlow sequenceFlow = this.createSequenceFlow(process, startEvent, userTask);
        // di-平面元素添加连线
        this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());

        //6、创建结束事件
        EndEvent endEvent = this.createElement(process, CamundaEnum.EVENT.getName() + this.id(), EndEvent.class);
        // 结束监听器
        ExtensionElements extensionElements = this.createElement(endEvent, "", ExtensionElements.class);
        CamundaExecutionListener start = this.createElement(extensionElements, "", CamundaExecutionListener.class);
        start.setCamundaDelegateExpression("#{EndEventListener}");
        start.setCamundaEvent("start");//start||end
        CamundaExecutionListener end = this.createElement(extensionElements, "", CamundaExecutionListener.class);
        end.setCamundaDelegateExpression("#{EndEventListener}");
        end.setCamundaEvent("end");//start||end
        endEvent.setExtensionElements(extensionElements);
        this.drawBpmnShape(modelInstance, plane, endEvent.getId());// di-平面元素添加节点

        //7、处理节点数据-递归
        this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(param.get("processModeel")), userId);

        //8、验证模型
        Bpmn.validateModel(modelInstance);

        //9、转换为xml字符串
        String xmlString = Bpmn.convertToString(modelInstance);
        log.info(xmlString);
        return xmlString;
    }
    /**
     *迭代器
     * @Description 迭代器
     * @Param process: 流程DOM对象
     * @Param previouEvent: 上一节点DOM对象
     * @Param endEvent: 结束事件DOM对象
     * @Param conditionMap: 网关条件
     * @Param jsonStr: 参数json串
     * @Return: void
     * @Author HeZeMin
     * @Date 2022年04月12日 10:35
     */
    public void iterate(BpmnModelInstance modelInstance, BpmnPlane plane, Process process, FlowNode previouEvent, FlowNode endEvent, HashMap<String, String> conditionMap, String jsonStr, Long userId) {
        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        process.getId();
        if (ObjectUtil.isNotNull(jsonObject) && jsonObject.size() > 0) {
            Integer nodeType = jsonObject.get("nodeType", Integer.class);
            if (1 == nodeType || 2  == nodeType) {// 1=审批人,2=执行人
                Integer auditType = jsonObject.get("auditType", Integer.class);
                Integer auditMethod = jsonObject.get("auditMethod", Integer.class);
                Integer isAdminAudit = jsonObject.get("isAdminAudit", Integer.class);
                String dataType = jsonObject.get("dataType", String.class);
                String nodeName = jsonObject.get("nodeName", String.class);
                String dataValue = jsonObject.get("dataValue", String.class);
                // 创建用户任务节点
                String id = CamundaEnum.ACTIVITY.getName() + this.id();
                if (2  == nodeType) {// 执行人额外增加一个属性标识,不然不知道是执行人还是审批人
                    id = CamundaEnum.ACTIVITY.getName() + "executor_" + this.id();// 执行人标识
                }
                UserTask userTask = this.createElement(process, id, UserTask.class);
                if (2  == nodeType) {
                    userTask.setName(StrUtil.isBlank(nodeName) ? "执行人" : nodeName);
                } else {
                    userTask.setName(StrUtil.isBlank(nodeName) ? "审批人" : nodeName);
                }
                userTask.setCamundaAssignee("${assignee}");
                // 创建多人签实例
                MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = this.createElement(userTask, "", MultiInstanceLoopCharacteristics.class);
                //审批人集合参数
                multiInstanceLoopCharacteristics.setCamundaCollection("assigneeList_" + id);
                //迭代集合
                multiInstanceLoopCharacteristics.setCamundaElementVariable("assignee");
                //完成条件 已完成数等于实例数
                CompletionCondition completionCondition = this.createElement(multiInstanceLoopCharacteristics, "", CompletionCondition.class);
                if (0 == auditMethod || 1 == auditMethod) {// 或签
                    completionCondition.setTextContent("${nrOfCompletedInstances == 1}");
                } else if (2 == auditMethod) {// 会签
                    completionCondition.setTextContent("${nrOfActiveInstances == nrOfInstances}");
                } else {
                    completionCondition.setTextContent("${nrOfActiveInstances == nrOfInstances}");
                }
                multiInstanceLoopCharacteristics.setCompletionCondition(completionCondition);
                // 并行,为true时就是顺序签
                if (3 == auditMethod) {
                    multiInstanceLoopCharacteristics.setSequential(true);
                } else {
                    multiInstanceLoopCharacteristics.setSequential(false);
                }
                userTask.setLoopCharacteristics(multiInstanceLoopCharacteristics);

                // 站内信和提醒 监听器
                ExtensionElements extensionElements = this.createElement(userTask, "", ExtensionElements.class);
                CamundaTaskListener create = this.createElement(extensionElements, "", CamundaTaskListener.class);
                create.setCamundaDelegateExpression("#{TaskMessageListener}");
                create.setCamundaEvent("create");
                CamundaTaskListener complete = this.createElement(extensionElements, "", CamundaTaskListener.class);
                complete.setCamundaDelegateExpression("#{TaskMessageListener}");
                complete.setCamundaEvent("complete");
                userTask.setExtensionElements(extensionElements);

                // di-平面元素添加节点
                this.drawBpmnShape(modelInstance, plane, userTask.getId());

                //--相关数据存入数据库start
                //保存节点
                //保存节点对应的数据
                //--相关数据存入数据库end
                JSONArray nextNodeDataList = (JSONArray) jsonObject.get("nextNodeData");
                if (CollUtil.isNotEmpty(nextNodeDataList)) {//有下一个节点
                    SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
                    // di-平面元素添加连线
                    this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
                    this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(nextNodeDataList.get(0)), userId);
                } else {// 没有下一个节点了,连线结束事件
                    SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
                    SequenceFlow sequenceFlow1 = this.createSequenceFlow(process, userTask, endEvent);
                    // di-平面元素添加连线
                    this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
                    // di-平面元素添加连线
                    this.drawBpmnEdge(modelInstance, plane, sequenceFlow1.getId());
                }
            } else if (3 == nodeType) {// 3=抄送人
                Integer auditType = jsonObject.get("auditType", Integer.class);
                Integer auditMethod = jsonObject.get("auditMethod", Integer.class);
                Integer isAdminAudit = jsonObject.get("isAdminAudit", Integer.class);
                String dataType = jsonObject.get("dataType", String.class);
                String dataValue = jsonObject.get("dataValue", String.class);
                String nodeName = jsonObject.get("nodeName", String.class);
                // 创建用户任务节点
                String id = CamundaEnum.ACTIVITY.getName() + "copy_" + this.id();
                UserTask userTask = this.createElement(process, id, UserTask.class);
                userTask.setName(StrUtil.isBlank(nodeName) ? "抄送人" : nodeName);

                // 抄送监听器
                ExtensionElements extensionElements = this.createElement(userTask, "", ExtensionElements.class);
                CamundaTaskListener create = this.createElement(extensionElements, "", CamundaTaskListener.class);
                create.setCamundaDelegateExpression("#{CopyListener}");
                create.setCamundaEvent("create");
                CamundaTaskListener complete = this.createElement(extensionElements, "", CamundaTaskListener.class);
                complete.setCamundaDelegateExpression("#{CopyListener}");
                complete.setCamundaEvent("complete");
                userTask.setExtensionElements(extensionElements);

                // di-平面元素添加节点
                this.drawBpmnShape(modelInstance, plane, userTask.getId());

                //--相关数据存入数据库
                //保存节点
                //保存节点对应的数据
                //--相关数据存入数据库

                JSONArray nextNodeDataList = (JSONArray) jsonObject.get("nextNodeData");
                if (CollUtil.isNotEmpty(nextNodeDataList)) {//有下一个节点
                    SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
                    // di-平面元素添加连线
                    this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
                    this.iterate(modelInstance, plane, process, userTask, endEvent, null, JSONUtil.toJsonStr(nextNodeDataList.get(0)), userId);
                } else {// 没有下一个节点了,连线结束事件
                    SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, userTask, conditionMap);
                    SequenceFlow sequenceFlow1 = this.createSequenceFlow(process, userTask, endEvent);
                    // di-平面元素添加连线
                    this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
                    // di-平面元素添加连线
                    this.drawBpmnEdge(modelInstance, plane, sequenceFlow1.getId());
                }
            } else if (4 == nodeType){// 4=条件分支,只有网关才会有下一节点数据和条件判断数据同时出现的情况
                String nodeName = jsonObject.get("nodeName", String.class);
                // 创建网关
                String id = CamundaEnum.GATEWAY.getName() + this.id();
                // 专属网关,直走一个条件
                ExclusiveGateway gateway = this.createElement(process, id, ExclusiveGateway.class);
                // 并行网关,所有条件都走
//                ParallelGateway gateway = createElement(process, id, ParallelGateway.class);
                SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, gateway, conditionMap);

                // di-平面元素添加节点
                this.drawBpmnShape(modelInstance, plane, gateway.getId());
                // di-平面元素添加连线
                this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());

                //--相关数据存入数据库start
                // 保存网关节点
                //--相关数据存入数据库end

                // 条件判断集合
                JSONArray conditionList = (JSONArray) jsonObject.get("conditionList");
                Iterator<Object> iterator = conditionList.iterator();
                while (iterator.hasNext()) {
                    JSONObject condition = (JSONObject) iterator.next();
                    
                    //--相关数据存入数据库start
                    // 保存网关节点条件判断
                    //--相关数据存入数据库end

                    // 网关表达式
                    StringBuilder textContent = new StringBuilder();
                    textContent.append("${");
                    if (StrUtil.isNotBlank(condition.get("conditionKey_", String.class))) {//两个条件
                        textContent.append("(");
                        if (StrUtil.contains("区间", condition.get("operator", String.class))) {
                            textContent.append(condition.get("targetValue1", String.class) + condition.get("targetValue1Operator", String.class) + condition.get("conditionKey", String.class))
                                    .append(" && ")
                                    .append(condition.get("conditionKey", String.class) + condition.get("targetValue2Operator", String.class) + condition.get("targetValue2", String.class));
                        } else if (StrUtil.contains("包含", condition.get("operator", String.class))) {
                            List<String> stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
                            for (int i = 0; i < stringList.size(); i++) {
                                String targetValue = stringList.get(i);
                                if (i == 0) {
                                    textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
                                } else {
                                    textContent.append(" || ");
                                    textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
                                }
                            }
                        } else if (StrUtil.contains("不包含", condition.get("operator", String.class))) {
                            List<String> stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
                            for (int i = 0; i < stringList.size(); i++) {
                                String targetValue = stringList.get(i);
                                if (i == 0) {
                                    textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
                                } else {
                                    textContent.append(" && ");
                                    textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
                                }
                            }
                        } else {
                            textContent.append(condition.get("conditionKey", String.class) + condition.get("operator", String.class) + condition.get("targetValue", String.class));
                        }
                        textContent.append(") && (");
                        if (StrUtil.contains("区间", condition.get("operator_", String.class))) {
                            textContent.append(condition.get("targetValue1_", String.class) + condition.get("targetValue1Operator_", String.class) + condition.get("conditionKey_", String.class))
                                    .append(" && ")
                                    .append(condition.get("conditionKey_", String.class) + condition.get("targetValue2Operator_", String.class) + condition.get("targetValue2_", String.class));
                        } else if (StrUtil.contains("包含", condition.get("operator_", String.class))) {
                            List<String> stringList = StrUtil.split(condition.get("targetValue_", String.class), ",");
                            for (int i = 0; i < stringList.size(); i++) {
                                String targetValue = stringList.get(i);
                                if (i == 0) {
                                    textContent.append(condition.get("conditionKey_", String.class) + " == " + targetValue);
                                } else {
                                    textContent.append(" || ");
                                    textContent.append(condition.get("conditionKey_", String.class) + " == " + targetValue);
                                }
                            }
                        } else if (StrUtil.contains("不包含", condition.get("operator_", String.class))) {
                            List<String> stringList = StrUtil.split(condition.get("targetValue_", String.class), ",");
                            for (int i = 0; i < stringList.size(); i++) {
                                String targetValue = stringList.get(i);
                                if (i == 0) {
                                    textContent.append(condition.get("conditionKey_", String.class) + " != " + targetValue);
                                } else {
                                    textContent.append(" && ");
                                    textContent.append(condition.get("conditionKey_", String.class) + " != " + targetValue);
                                }
                            }
                        } else {
                            textContent.append(condition.get("conditionKey_", String.class) + condition.get("operator_", String.class) + condition.get("targetValue_", String.class));
                        }
                        textContent.append(")");
                    } else {// 一个条件
                        if (StrUtil.contains("区间", condition.get("operator", String.class))) {
                            textContent.append(condition.get("targetValue1", String.class) + condition.get("targetValue1Operator", String.class) + condition.get("conditionKey", String.class))
                                    .append(" && ")
                                    .append(condition.get("conditionKey", String.class) + condition.get("targetValue2Operator", String.class) + condition.get("targetValue2", String.class));
                        } else if (StrUtil.contains("包含", condition.get("operator", String.class))) {
                            List<String> stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
                            for (int i = 0; i < stringList.size(); i++) {
                                String targetValue = stringList.get(i);
                                if (i == 0) {
                                    textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
                                } else {
                                    textContent.append(" || ");
                                    textContent.append(condition.get("conditionKey", String.class) + " == " + targetValue);
                                }
                            }
                        } else if (StrUtil.contains("不包含", condition.get("operator", String.class))) {
                            List<String> stringList = StrUtil.split(condition.get("targetValue", String.class), ",");
                            for (int i = 0; i < stringList.size(); i++) {
                                String targetValue = stringList.get(i);
                                if (i == 0) {
                                    textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
                                } else {
                                    textContent.append(" && ");
                                    textContent.append(condition.get("conditionKey", String.class) + " != " + targetValue);
                                }
                            }
                        } else {
                            textContent.append(condition.get("conditionKey", String.class) + condition.get("operator", String.class) + condition.get("targetValue", String.class));
                        }
                    }
                    textContent.append("}");
                    JSONArray nextNodeDataList = (JSONArray) condition.get("nextNodeData");
                    if (CollUtil.isNotEmpty(nextNodeDataList)) {//有下一个节点
                        String conditionName = condition.get("conditionName", String.class);
                        HashMap<String, String> map = new HashMap<>();
                        map.put("name", StrUtil.isBlank(conditionName) ? textContent.toString() : conditionName);
                        map.put("type", "");
                        map.put("textContent", textContent.toString());
                        this.iterate(modelInstance, plane, process, gateway, endEvent, map, JSONUtil.toJsonStr(nextNodeDataList.get(0)), userId);
                    } else {
                        SequenceFlow sequenceFlow1 = this.createSequenceFlow(process, gateway, endEvent);
                        // di-平面元素添加连线
                        this.drawBpmnEdge(modelInstance, plane, sequenceFlow1.getId());
                        // 一下注释代码暂时用不到,勿删
                        // 网关的下一个节点,不是条件下的
//                        JSONArray gatewayNnextNodeDataList = (JSONArray) jsonObject.get("nextNodeData");
//                        if (CollUtil.isNotEmpty(gatewayNnextNodeDataList)) {//有下一个节点
//                            this.createSequenceFlow(process, startEvent, gateway, conditionMap);
//                            this.iterate(process, gateway, endEvent, null, JSONUtil.toJsonStr(gatewayNnextNodeDataList.get(0)));
//                        } else {// 没有下一个节点了,连线结束事件
//                            this.createSequenceFlow(process, gateway, endEvent, conditionMap);
//                        }
                    }
                }
            }
        } else {
            // 开始事件连线到结束事件
            SequenceFlow sequenceFlow = this.createSequenceFlow(process, previouEvent, endEvent);
            // di-平面元素添加连线
            this.drawBpmnEdge(modelInstance, plane, sequenceFlow.getId());
        }
    }
    /**
     * Description:id生成器
     * @Author HeZeMin
     * @Date
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值