Camunda条件事件示例Demo(Conditional Events)

Camunda条件事件(Conditional Events):定义了一个事件,该事件在给定条件被求值为true时被触发。它可以作为事件子流程的起始事件、中间事件和边界事件。开始和边界事件可以是中断的和不中断的。在Camunda中,条件事件是在流程变量的帮助下触发的。

Camunda条件事件包括:Conditional Start Event(启动条件事件)、Intermediate Conditional Catch Event(中间捕获条件事件)、Conditional Boundary Event(边界条件事件)、Conditional Start Event for Event Sub Process(子流程条件事件)。

 

本文重点介绍Conditional Start Event(启动条件事件)和T Conditional Boundary Event(边界条件事件),其它事件请参考camunda官方文档:https://docs.camunda.org/manual/7.15/reference/bpmn20/events/

 

一、设计流程图

测试场景:通过报销流程模拟条件事件流程自动发起,如果报销金额大于10000元,将自动发起报销审批子流程,在财务审批环节,如果报销金额金额发生变化,自动触发边界条件事件,退后给审批人。

报销主流程:

 

 

报销事件节点配置:


 

代理类代码如下:

package com.example.demo1;

import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.camunda.bpm.engine.runtime.ProcessInstance;

import java.util.List;


/**
 * 触发条件事件启动子流程
 */
public class InstantiateProcessByConditionDelegate implements JavaDelegate {

    public void execute(DelegateExecution execution) {
        Integer money = (int)execution.getVariable("money");
        RuntimeService runtimeService = execution.getProcessEngineServices().getRuntimeService();
        List<ProcessInstance> instances = runtimeService
                .createConditionEvaluation()
                .setVariable("money", money)
                .evaluateStartConditions();
    }
}

BPMN流程模型文件:

<?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_1ktuxzn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.8.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">

  <bpmn:process id="Process_10z1wy2" name="报销主流程" isExecutable="true">

    <bpmn:startEvent id="StartEvent_1">

      <bpmn:outgoing>Flow_0f0u4dp</bpmn:outgoing>

    </bpmn:startEvent>

    <bpmn:sequenceFlow id="Flow_0f0u4dp" sourceRef="StartEvent_1" targetRef="Activity_02e4hhc" />

    <bpmn:sequenceFlow id="Flow_0ckn1r7" sourceRef="Activity_02e4hhc" targetRef="Activity_1lkdefp" />

    <bpmn:endEvent id="Event_1iic3x0">

      <bpmn:incoming>Flow_04z0quc</bpmn:incoming>

    </bpmn:endEvent>

    <bpmn:sequenceFlow id="Flow_04z0quc" sourceRef="Activity_1lkdefp" targetRef="Event_1iic3x0" />

    <bpmn:serviceTask id="Activity_02e4hhc" name="报销事件" camunda:class="com.example.demo1.InstantiateProcessByConditionDelegate">

      <bpmn:incoming>Flow_0f0u4dp</bpmn:incoming>

      <bpmn:outgoing>Flow_0ckn1r7</bpmn:outgoing>

    </bpmn:serviceTask>

    <bpmn:userTask id="Activity_1lkdefp" name="通知报销人" camunda:assignee="demo">

      <bpmn:incoming>Flow_0ckn1r7</bpmn:incoming>

      <bpmn:outgoing>Flow_04z0quc</bpmn:outgoing>

    </bpmn:userTask>

  </bpmn:process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_1">

    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_10z1wy2">

      <bpmndi:BPMNEdge id="Flow_0f0u4dp_di" bpmnElement="Flow_0f0u4dp">

        <di:waypoint x="215" y="117" />

        <di:waypoint x="270" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_0ckn1r7_di" bpmnElement="Flow_0ckn1r7">

        <di:waypoint x="370" y="117" />

        <di:waypoint x="430" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_04z0quc_di" bpmnElement="Flow_04z0quc">

        <di:waypoint x="530" y="117" />

        <di:waypoint x="592" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">

        <dc:Bounds x="179" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Event_1iic3x0_di" bpmnElement="Event_1iic3x0">

        <dc:Bounds x="592" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_09rzn3u_di" bpmnElement="Activity_02e4hhc">

        <dc:Bounds x="270" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_1khoz85_di" bpmnElement="Activity_1lkdefp">

        <dc:Bounds x="430" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

    </bpmndi:BPMNPlane>

  </bpmndi:BPMNDiagram>

</bpmn:definitions>

报销审批子流程:

 

 

Conditional Start Event(启动条件事件)节点配置:

 

 

${money>=10000} 表示报销金额大于等于1万元,流程自动启动。

 

Conditional Boundary Event(边界条件事件)节点配置:

 

 

${money>=20000}表示报销金额大于等于2万元,自动触发边界条件事件。

 

BPMN流程模型文件:

<?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_1n4m8dk" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.8.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.15.0">

  <bpmn:process id="Process_0uf5zc5" name="条件事件流程" isExecutable="true">

    <bpmn:sequenceFlow id="Flow_1f7cdrv" sourceRef="StartEvent_1" targetRef="Activity_15fulz2" />

    <bpmn:sequenceFlow id="Flow_0p7c5lt" sourceRef="Activity_15fulz2" targetRef="Activity_0xikne3" />

    <bpmn:endEvent id="Event_152527w">

      <bpmn:incoming>Flow_1l03vwj</bpmn:incoming>

    </bpmn:endEvent>

    <bpmn:sequenceFlow id="Flow_1l03vwj" sourceRef="Activity_0xikne3" targetRef="Event_152527w" />

    <bpmn:startEvent id="StartEvent_1">

      <bpmn:outgoing>Flow_1f7cdrv</bpmn:outgoing>

      <bpmn:conditionalEventDefinition id="ConditionalEventDefinition_0lzdf7y" camunda:variableName="money">

        <bpmn:condition xsi:type="bpmn:tFormalExpression">${money&gt;=10000}</bpmn:condition>

      </bpmn:conditionalEventDefinition>

    </bpmn:startEvent>

    <bpmn:userTask id="Activity_15fulz2" name="经理审批" camunda:assignee="demo">

      <bpmn:incoming>Flow_1f7cdrv</bpmn:incoming>

      <bpmn:incoming>Flow_08he9tn</bpmn:incoming>

      <bpmn:outgoing>Flow_0p7c5lt</bpmn:outgoing>

    </bpmn:userTask>

    <bpmn:userTask id="Activity_0xikne3" name="财务审批" camunda:assignee="demo">

      <bpmn:incoming>Flow_0p7c5lt</bpmn:incoming>

      <bpmn:outgoing>Flow_1l03vwj</bpmn:outgoing>

    </bpmn:userTask>

    <bpmn:boundaryEvent id="Event_0mnbhru" name="报销费修改事件" attachedToRef="Activity_0xikne3">

      <bpmn:outgoing>Flow_08he9tn</bpmn:outgoing>

      <bpmn:conditionalEventDefinition id="ConditionalEventDefinition_19eu007" camunda:variableName="money">

        <bpmn:condition xsi:type="bpmn:tFormalExpression">${money&gt;=20000}</bpmn:condition>

      </bpmn:conditionalEventDefinition>

    </bpmn:boundaryEvent>

    <bpmn:sequenceFlow id="Flow_08he9tn" sourceRef="Event_0mnbhru" targetRef="Activity_15fulz2" />

  </bpmn:process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_1">

    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0uf5zc5">

      <bpmndi:BPMNEdge id="Flow_1f7cdrv_di" bpmnElement="Flow_1f7cdrv">

        <di:waypoint x="215" y="117" />

        <di:waypoint x="270" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_0p7c5lt_di" bpmnElement="Flow_0p7c5lt">

        <di:waypoint x="370" y="117" />

        <di:waypoint x="500" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_1l03vwj_di" bpmnElement="Flow_1l03vwj">

        <di:waypoint x="600" y="117" />

        <di:waypoint x="662" y="117" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Flow_08he9tn_di" bpmnElement="Flow_08he9tn">

        <di:waypoint x="550" y="175" />

        <di:waypoint x="550" y="195" />

        <di:waypoint x="320" y="195" />

        <di:waypoint x="320" y="157" />

      </bpmndi:BPMNEdge>

      <bpmndi:BPMNShape id="Event_1d290h0_di" bpmnElement="StartEvent_1">

        <dc:Bounds x="179" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_1hwmimx_di" bpmnElement="Activity_15fulz2">

        <dc:Bounds x="270" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Event_152527w_di" bpmnElement="Event_152527w">

        <dc:Bounds x="662" y="99" width="36" height="36" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Activity_10pf0x5_di" bpmnElement="Activity_0xikne3">

        <dc:Bounds x="500" y="77" width="100" height="80" />

      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Event_0bjat0x_di" bpmnElement="Event_0mnbhru">

        <dc:Bounds x="532" y="139" width="36" height="36" />

        <bpmndi:BPMNLabel>

          <dc:Bounds x="451" y="166" width="77" height="14" />

        </bpmndi:BPMNLabel>

      </bpmndi:BPMNShape>

    </bpmndi:BPMNPlane>

  </bpmndi:BPMNDiagram>

</bpmn:definitions>

 

二、部署流程并测试验证

 

流程部署后,查看数据库流程订阅事件表act_ru_event_subscr,发现Conditional Start Event(条件启动事件)已持久化到数据库中。


 

通过demo用户登录camunda平台http://localhost:8080/camunda/app/tasklist/default/#/login,启动主流程模拟测试。


 

由于报销金额满足条件,所以子流程被自动触发启动:

 

 

 

手动子流程提交到下一节点:


 

此时,流程流转到了Conditional Boundary Event(边界条件事件)节点上,查看数据库表记录:

 

 

为了模拟触发Conditional Boundary Event,在camunda后台修改money变量值:

 

由于流程变量money变成了20000,满足了Conditional Boundary Event触发条件,所以流程自动流程到对应节点。

 

 

三、条件事件使用说明

  1. Conditional Start Event(启动条件事件)

条件启动事件(Conditional Start Event)可以通过计算某些条件来启动流程。一个流程可以有一个或多个条件启动事件。

如果满足了多个条件,则会触发相应数量的进程。

部署带有条件启动事件的流程定义时,需要考虑以下事项:

在给定的流程定义中,条件启动事件的条件必须是唯一的,也就是说,流程定义不能有多个条件相同的条件启动事件。如果两个或多个条件启动事件包含相同的条件,则引擎会在部署流程定义时抛出异常。

流程版本控制:在部署流程定义的新版本时,将取消前一个版本的条件订阅。新版本中没有出现的条件事件也是如此。

当启动一个流程实例时,可以在RuntimeService上使用以下方法触发一个条件启动事件:

List<ProcessInstance> instances = runtimeService

    .createConditionEvaluation()

    .setVariable("temperature", 24)

    .evaluateStartConditions();

// or

List<ProcessInstance> instances = runtimeService

    .createConditionEvaluation()

    .setVariables(variableMap)

.evaluateStartConditions();

所提供的变量用于计算条件。它们还将作为变量传递给新创建的流程实例。条件启动事件的XML表示是带有conditionalEventDefinition子元素的普通启动事件声明。

可选:将variableName属性添加到conditionalEventDefinition允许指定一个变量名,在该变量名上,条件事件的条件应专门计算。

<startEvent id="conditionalStartEvent">

  <conditionalEventDefinition camunda:variableName="temperature">

    <condition type="tFormalExpression">${temperature > 20}</condition>

  </conditionalEventDefinition>

</startEvent>

 

2、Conditional Boundary Event(边界条件事件)

条件边界事件(Conditional Boundary Event)就像一个观察者,如果满足一个特定的条件,它就会被触发。中断条件事件和非中断条件事件是有区别的。缺省情况下为中断事件。非中断事件导致原始活动未被中断,实例仍处于活动状态。相反,创建了一个额外的执行路径,采用事件的传出转换。一个不中断的条件事件可以被触发多次,只要它所附加的活动是活动的。

在非中断条件事件的XML表示中,cancelActivity属性被设置为false:

<boundaryEvent id="conditionalEvent" attachedToRef="taskWithCondition" cancelActivity="false">

  <conditionalEventDefinition>

    <condition type="tFormalExpression">${var1 == 1}</condition>

  </conditionalEventDefinition>

</boundaryEvent>

 

参考:

https://docs.camunda.org/manual/7.15/reference/bpmn20/events/conditional-events/

posted @ 2022-06-13 14:35  大龄码农有梦想  阅读(497)  评论(0编辑  收藏  举报