Camunda排他网关与并行网关

💖专栏简介

✔️本专栏将从Camunda(卡蒙达) 7中的关键概念到实现中国式工作流相关功能。

✔️文章中只包含演示核心代码及测试数据,完整代码可查看作者的开源项目snail-camunda

✔️请给snail-camunda 点颗星吧😘

💖排他网关

流程定义中需要用到排他网关时需要注意两点:

1是必须要有一条默认路线,当其他条件均不满足时走该路线。

2是条件表达式要设置正确

表单定义如下

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0lyy3jm" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.19.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
  <bpmn:process id="Process_1celx74" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>Flow_0a6p958</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:sequenceFlow id="Flow_0a6p958" sourceRef="StartEvent_1" targetRef="root" />
    <bpmn:userTask id="root" name="提交人" camunda:assignee="${initiator}">
      <bpmn:incoming>Flow_0a6p958</bpmn:incoming>
      <bpmn:outgoing>Flow_0i294hl</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:exclusiveGateway id="Gateway_1e17vip" default="Flow_19gtn2c">
      <bpmn:incoming>Flow_0i294hl</bpmn:incoming>
      <bpmn:outgoing>Flow_07vd7cq</bpmn:outgoing>
      <bpmn:outgoing>Flow_19gtn2c</bpmn:outgoing>
    </bpmn:exclusiveGateway>
    <bpmn:sequenceFlow id="Flow_0i294hl" sourceRef="root" targetRef="Gateway_1e17vip" />
    <bpmn:sequenceFlow id="Flow_07vd7cq" name="大于3天" sourceRef="Gateway_1e17vip" targetRef="Activity_1fw9lpo">
      <bpmn:extensionElements />
      <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">${day &gt; 3}</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:sequenceFlow id="Flow_19gtn2c" sourceRef="Gateway_1e17vip" targetRef="Activity_17k9da9">
      <bpmn:extensionElements />
    </bpmn:sequenceFlow>
    <bpmn:endEvent id="Event_1673c3w">
      <bpmn:incoming>Flow_1cxwd4c</bpmn:incoming>
      <bpmn:incoming>Flow_0gnj3ll</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_1cxwd4c" sourceRef="Activity_1fw9lpo" targetRef="Event_1673c3w" />
    <bpmn:sequenceFlow id="Flow_0gnj3ll" sourceRef="Activity_17k9da9" targetRef="Event_1673c3w" />
    <bpmn:userTask id="Activity_1fw9lpo" name="部长" camunda:assignee="${head}">
      <bpmn:incoming>Flow_07vd7cq</bpmn:incoming>
      <bpmn:outgoing>Flow_1cxwd4c</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:userTask id="Activity_17k9da9" name="经理" camunda:assignee="${manager}">
      <bpmn:incoming>Flow_19gtn2c</bpmn:incoming>
      <bpmn:outgoing>Flow_0gnj3ll</bpmn:outgoing>
    </bpmn:userTask>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1celx74">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="179" y="209" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_07adzvd_di" bpmnElement="root">
        <dc:Bounds x="270" y="187" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Gateway_1e17vip_di" bpmnElement="Gateway_1e17vip" isMarkerVisible="true">
        <dc:Bounds x="425" y="202" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1673c3w_di" bpmnElement="Event_1673c3w">
        <dc:Bounds x="752" y="209" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1rofeex_di" bpmnElement="Activity_1fw9lpo">
        <dc:Bounds x="520" y="80" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_01iu09y_di" bpmnElement="Activity_17k9da9">
        <dc:Bounds x="520" y="290" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Flow_0a6p958_di" bpmnElement="Flow_0a6p958">
        <di:waypoint x="215" y="227" />
        <di:waypoint x="270" y="227" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0i294hl_di" bpmnElement="Flow_0i294hl">
        <di:waypoint x="370" y="227" />
        <di:waypoint x="425" y="227" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_07vd7cq_di" bpmnElement="Flow_07vd7cq">
        <di:waypoint x="450" y="202" />
        <di:waypoint x="450" y="120" />
        <di:waypoint x="520" y="120" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="445" y="158" width="40" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_19gtn2c_di" bpmnElement="Flow_19gtn2c">
        <di:waypoint x="450" y="252" />
        <di:waypoint x="450" y="330" />
        <di:waypoint x="520" y="330" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1cxwd4c_di" bpmnElement="Flow_1cxwd4c">
        <di:waypoint x="620" y="120" />
        <di:waypoint x="700" y="120" />
        <di:waypoint x="700" y="227" />
        <di:waypoint x="752" y="227" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0gnj3ll_di" bpmnElement="Flow_0gnj3ll">
        <di:waypoint x="620" y="330" />
        <di:waypoint x="700" y="330" />
        <di:waypoint x="700" y="227" />
        <di:waypoint x="752" y="227" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

发起实例的接口,参数类和之前文章中提到的都一样,不重复贴了

    /**
     * 根据流程定义key发起流程实例
     *
     * @param requestParam 请求参数
     * @return 流程实例id
     */
    @PostMapping("/startProcessInstanceByKey")
    public String startProcessInstanceByKey(@RequestBody StartProcessRequest requestParam) {
        Map<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("initiator", requestParam.getInitiator());
        paramMap.put("day", 4);
        paramMap.put("manager","10087");
        paramMap.put("head", "10088");
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(requestParam.getProcessDefinitionKey(), requestParam.getBusinessKey(), paramMap);
        return processInstance.getProcessInstanceId();
    }

发起后,满足预期来到【部长】节点

💖统一表达式语言

Camunda支持统一表达式语言,使用开源的JUEL来实现的。需要掌握更多可访问如下链接

Unified Expression Language

💖并行网关

在之前的《认识BPMN2.0》中我们知道并行网关的功能是基于传入和传出序列流:

  • Fork:所有传出序列流并行执行,为每个序列流创建一个并发执行。
  • Join:到达并行网关的所有并发执行在网关等待,直到每个传入序列流的执行到达为止。

流程定义设计如下:

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_0x5ifr3" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.19.0" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">
  <bpmn:process id="Process_17ri3bi" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>Flow_0woj0jt</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:sequenceFlow id="Flow_0woj0jt" sourceRef="StartEvent_1" targetRef="root" />
    <bpmn:userTask id="root" name="发起人" camunda:assignee="${initiator}">
      <bpmn:incoming>Flow_0woj0jt</bpmn:incoming>
      <bpmn:outgoing>Flow_0istezk</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:sequenceFlow id="Flow_0istezk" sourceRef="root" targetRef="Gateway_0j97tkc" />
    <bpmn:parallelGateway id="Gateway_0j97tkc">
      <bpmn:incoming>Flow_0istezk</bpmn:incoming>
      <bpmn:outgoing>Flow_1ucnqdb</bpmn:outgoing>
      <bpmn:outgoing>Flow_0nvwxww</bpmn:outgoing>
      <bpmn:outgoing>Flow_06j90pb</bpmn:outgoing>
    </bpmn:parallelGateway>
    <bpmn:sequenceFlow id="Flow_1ucnqdb" sourceRef="Gateway_0j97tkc" targetRef="Activity_16bwr8x" />
    <bpmn:sequenceFlow id="Flow_0nvwxww" sourceRef="Gateway_0j97tkc" targetRef="Activity_0qtaspo" />
    <bpmn:userTask id="Activity_16bwr8x" name="审批人1号" camunda:assignee="${userOne}">
      <bpmn:incoming>Flow_1ucnqdb</bpmn:incoming>
      <bpmn:outgoing>Flow_11upvwe</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:userTask id="Activity_0qtaspo" name="审批人3号" camunda:assignee="${userThree}">
      <bpmn:incoming>Flow_0nvwxww</bpmn:incoming>
      <bpmn:outgoing>Flow_1qfv4jz</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:endEvent id="Event_01ck26r">
      <bpmn:incoming>Flow_0rzniwk</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_06j90pb" sourceRef="Gateway_0j97tkc" targetRef="Activity_0bczswl" />
    <bpmn:userTask id="Activity_0bczswl" name="审批人2号" camunda:assignee="${userTwo}">
      <bpmn:incoming>Flow_06j90pb</bpmn:incoming>
      <bpmn:outgoing>Flow_1mymqa7</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:parallelGateway id="Gateway_1gholo6">
      <bpmn:incoming>Flow_1mymqa7</bpmn:incoming>
      <bpmn:incoming>Flow_11upvwe</bpmn:incoming>
      <bpmn:outgoing>Flow_0luwvad</bpmn:outgoing>
    </bpmn:parallelGateway>
    <bpmn:sequenceFlow id="Flow_1mymqa7" sourceRef="Activity_0bczswl" targetRef="Gateway_1gholo6" />
    <bpmn:sequenceFlow id="Flow_0luwvad" sourceRef="Gateway_1gholo6" targetRef="Activity_10re8z2" />
    <bpmn:userTask id="Activity_10re8z2" name="审批人4号" camunda:assignee="${userFour}">
      <bpmn:incoming>Flow_0luwvad</bpmn:incoming>
      <bpmn:outgoing>Flow_05npw3q</bpmn:outgoing>
    </bpmn:userTask>
    <bpmn:sequenceFlow id="Flow_05npw3q" sourceRef="Activity_10re8z2" targetRef="Gateway_1u3oe8c" />
    <bpmn:parallelGateway id="Gateway_1u3oe8c">
      <bpmn:incoming>Flow_05npw3q</bpmn:incoming>
      <bpmn:incoming>Flow_1qfv4jz</bpmn:incoming>
      <bpmn:outgoing>Flow_0rzniwk</bpmn:outgoing>
    </bpmn:parallelGateway>
    <bpmn:sequenceFlow id="Flow_0rzniwk" sourceRef="Gateway_1u3oe8c" targetRef="Event_01ck26r" />
    <bpmn:sequenceFlow id="Flow_1qfv4jz" sourceRef="Activity_0qtaspo" targetRef="Gateway_1u3oe8c" />
    <bpmn:sequenceFlow id="Flow_11upvwe" sourceRef="Activity_16bwr8x" targetRef="Gateway_1gholo6" />
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_17ri3bi">
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="179" y="159" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_04cwdxu_di" bpmnElement="root">
        <dc:Bounds x="270" y="137" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Gateway_0wqcqy3_di" bpmnElement="Gateway_0j97tkc">
        <dc:Bounds x="425" y="152" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1978o8o_di" bpmnElement="Activity_16bwr8x">
        <dc:Bounds x="520" y="60" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1jr9acr_di" bpmnElement="Activity_0bczswl">
        <dc:Bounds x="520" y="200" width="100" height="80" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1opqr0v_di" bpmnElement="Activity_0qtaspo">
        <dc:Bounds x="510" y="360" width="100" height="80" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Gateway_1iutlje_di" bpmnElement="Gateway_1gholo6">
        <dc:Bounds x="675" y="115" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_1ne89o0_di" bpmnElement="Activity_10re8z2">
        <dc:Bounds x="770" y="100" width="100" height="80" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Gateway_0an4f7j_di" bpmnElement="Gateway_1u3oe8c">
        <dc:Bounds x="915" y="215" width="50" height="50" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_01ck26r_di" bpmnElement="Event_01ck26r">
        <dc:Bounds x="1042" y="222" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="Flow_0woj0jt_di" bpmnElement="Flow_0woj0jt">
        <di:waypoint x="215" y="177" />
        <di:waypoint x="270" y="177" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0istezk_di" bpmnElement="Flow_0istezk">
        <di:waypoint x="370" y="177" />
        <di:waypoint x="425" y="177" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1ucnqdb_di" bpmnElement="Flow_1ucnqdb">
        <di:waypoint x="450" y="152" />
        <di:waypoint x="450" y="100" />
        <di:waypoint x="520" y="100" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0nvwxww_di" bpmnElement="Flow_0nvwxww">
        <di:waypoint x="450" y="202" />
        <di:waypoint x="450" y="400" />
        <di:waypoint x="510" y="400" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_06j90pb_di" bpmnElement="Flow_06j90pb">
        <di:waypoint x="450" y="202" />
        <di:waypoint x="450" y="240" />
        <di:waypoint x="520" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1mymqa7_di" bpmnElement="Flow_1mymqa7">
        <di:waypoint x="620" y="240" />
        <di:waypoint x="700" y="240" />
        <di:waypoint x="700" y="165" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0luwvad_di" bpmnElement="Flow_0luwvad">
        <di:waypoint x="725" y="140" />
        <di:waypoint x="770" y="140" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_05npw3q_di" bpmnElement="Flow_05npw3q">
        <di:waypoint x="870" y="140" />
        <di:waypoint x="940" y="140" />
        <di:waypoint x="940" y="215" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0rzniwk_di" bpmnElement="Flow_0rzniwk">
        <di:waypoint x="965" y="240" />
        <di:waypoint x="1042" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_1qfv4jz_di" bpmnElement="Flow_1qfv4jz">
        <di:waypoint x="610" y="400" />
        <di:waypoint x="940" y="400" />
        <di:waypoint x="940" y="265" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_11upvwe_di" bpmnElement="Flow_11upvwe">
        <di:waypoint x="620" y="100" />
        <di:waypoint x="648" y="100" />
        <di:waypoint x="648" y="140" />
        <di:waypoint x="675" y="140" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>

发起实例接口:

    /**
     * 根据流程定义key发起流程实例
     *
     * @param requestParam 请求参数
     * @return 流程实例id
     */
    @PostMapping("/startProcessInstanceByKey")
    public String startProcessInstanceByKey(@RequestBody StartProcessRequest requestParam) {
        Map<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("initiator", requestParam.getInitiator());
        paramMap.put("userOne","10087");
        paramMap.put("userTwo","10088");
        paramMap.put("userThree","10089");
        paramMap.put("userFour","10090");
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(requestParam.getProcessDefinitionKey(), requestParam.getBusinessKey(), paramMap);
        return processInstance.getProcessInstanceId();
    }

从下图可见,经过第一个并行网关后三个节点的审批人会同时收到待办任务。

所以3号完成后执行会在最后的并行网关等待

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LoneWalker、

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值