全网最全面工作流引擎Flowable完整教程之多实例会签

本文详细介绍了如何使用BladeX工作流设计器创建并行多实例会签流程,包括任务配置、部署、测试及实例操作,涉及部署流程定义、任务查询和流程跟踪关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

以下内容皆是本人原创,创作不易,感谢帮忙点赞、转发,我是爱写代码的成成呀
首先要理解什么是会签?比如一个任务需要多人审批,比如需要5个人审批,都审批通过就算通过,一人反对则不通过;再比如多人审批,只要经理审批通过或者其他成员9成审批通过,就算通过,这就是会签。
提示:以下是本篇文章正文内容,下面案例可供参考

1、BladeX流程设计器

1.1、BladeX工作流设计

在这里插入图片描述
配置多实例类型:sequential 串行 parallel 并行 ,这里我们先研究parallel 。

1.2、parallel多实例流程设计

在这里插入图片描述
从流程图中我们可以看到,这个流程有四个节点,分别是开始节点、多实例任务节点、普通的用户节点以及结束节点.。

<!--上述流程Bpmn文件:多实例会签.bpmn20.xml 文件内容-->
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
  <process id="Multi-instanceCountersigning" name="多实例会签" isExecutable="true">
    <documentation>勿删除</documentation>
    <startEvent id="startEvent1"></startEvent>
    <userTask id="sid-1F4BB62E-5C2B-46C3-AA67-7067FC1F752C" name="多实例任务UserTask">
      <extensionElements>
        <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><[CDATA[false]]></modeler:initiator-can-complete>
      </extensionElements>
      <multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">
        <loopCardinality>5</loopCardinality>
        <completionCondition>${nrOfCompletedInstances/nrOfInstances &gt;= 0.50}</completionCondition>
      </multiInstanceLoopCharacteristics>
    </userTask>
    <sequenceFlow id="sid-436F11E8-B070-4857-B5A6-A3CB94D4F138" sourceRef="startEvent1" targetRef="sid-1F4BB62E-5C2B-46C3-AA67-7067FC1F752C"></sequenceFlow>
    <userTask id="sid-E1E11E67-991E-40E5-950A-86A4C94F1C36" name="普通UserTask"></userTask>
    <sequenceFlow id="sid-8F6E3D87-82DA-487E-8C71-53E983BD255A" sourceRef="sid-1F4BB62E-5C2B-46C3-AA67-7067FC1F752C" targetRef="sid-E1E11E67-991E-40E5-950A-86A4C94F1C36"></sequenceFlow>
    <endEvent id="sid-613CA134-8467-4145-A6B3-3995AD7332A3"></endEvent>
    <sequenceFlow id="sid-7AD7B298-FAEC-40AA-B5E8-CFB919A72B92" sourceRef="sid-E1E11E67-991E-40E5-950A-86A4C94F1C36" targetRef="sid-613CA134-8467-4145-A6B3-3995AD7332A3"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_Multi-instanceCountersigning">
    <bpmndi:BPMNPlane bpmnElement="Multi-instanceCountersigning" id="BPMNPlane_Multi-instanceCountersigning">
      <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
        <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-1F4BB62E-5C2B-46C3-AA67-7067FC1F752C" id="BPMNShape_sid-1F4BB62E-5C2B-46C3-AA67-7067FC1F752C">
        <omgdc:Bounds height="80.0" width="99.99999999999997" x="205.04945732883417" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-E1E11E67-991E-40E5-950A-86A4C94F1C36" id="BPMNShape_sid-E1E11E67-991E-40E5-950A-86A4C94F1C36">
        <omgdc:Bounds height="80.0" width="100.0" x="441.6449850159505" y="138.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-613CA134-8467-4145-A6B3-3995AD7332A3" id="BPMNShape_sid-613CA134-8467-4145-A6B3-3995AD7332A3">
        <omgdc:Bounds height="28.0" width="28.0" x="630.9214071656436" y="164.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-436F11E8-B070-4857-B5A6-A3CB94D4F138" id="BPMNEdge_sid-436F11E8-B070-4857-B5A6-A3CB94D4F138">
        <omgdi:waypoint x="129.94999906825288" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="205.04945732883417" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-7AD7B298-FAEC-40AA-B5E8-CFB919A72B92" id="BPMNEdge_sid-7AD7B298-FAEC-40AA-B5E8-CFB919A72B92">
        <omgdi:waypoint x="541.5949850158808" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="630.9214071656436" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-8F6E3D87-82DA-487E-8C71-53E983BD255A" id="BPMNEdge_sid-8F6E3D87-82DA-487E-8C71-53E983BD255A">
        <omgdi:waypoint x="304.99945732876284" y="178.0"></omgdi:waypoint>
        <omgdi:waypoint x="441.6449850159505" y="178.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

会签的场景是多人参与的场景,意味着这是一个多实例任务,什么是多实例任务?就是这个任务会产生多少实例,可以理解成Java类和对象的关系。这里实例指的是执行实例,你想要多少的执行实例,可以通过配置参数,来决定执行任务时会产生多少个一样任务的实例,然后给每个指定的人执行,再把结果汇总,最后会根据汇总的结果来根据条件判断是否通过。

<!--通过loopCardinality决定产生多少实例-->
<loopCardinality>5</loopCardinality>
<!--该属性表示将任务分配给谁,这里用的是EL表达式
,而且我们可能把5个任务分给5个不同的人,这里是不可预见的,是运行时确定-->
flowable:assignee="${assignee}"

<!--false 表示并行 true 表示串行-->
<!--并行就是上面5个任务可以同时执行,并行就是5个任务一个个轮着轮着执行-->
isSequential="false" 

<!--这里是一个运行时的变量的名字
,举个例子我们运行时变量里面必须有个变量名字叫assigneeList-->
flowable:collection="assigneeList" 

<!--这里的assignee对应于上面的assigneeList, 如果 assigneeList是一个集合类型,
那么assignee就对应于集合中的一个单元,然后上面的EL表达式${assignee} 对应的就是这些单元。
类似于Mybatis中的foreach标签-->
flowable:elementVariable="assignee"
<multiInstanceLoopCharacteristics isSequential="false" flowable:collection="assigneeList" flowable:elementVariable="assignee">

  <!--配置5个任务实例-->
  <!--loopCardinality 代表该属性循环的基数是多少,这个任务就是多实例任务,
  这个属性就是设置有多少实例的地方!-->
  <!--为什么叫循环基数?如果我们需要3个实例通过的,那可能3个实例就满足条件,到下一环节了-->
  <loopCardinality>5</loopCardinality>
  
  <!-- nr代表 number 这里指 完成的实例数量/全部实例数 >= 0.50 即可-->
  <!-- 这里的变量nrOfCompletedInstances和nrOfInstances是系统自动生成的,
       要是你需要设置自己的变量吗,可以自己控制。-->
  <!-- 当然也可以设置别的条件,通过EL表达式进行设置-->
  <completionCondition>${nrOfCompletedInstances/nrOfInstances &gt;= 0.50}</completionCondition>
</multiInstanceLoopCharacteristics>

1.3、 BladeX多实例任务节点参数设置

对应bpmn文件,配置如下
在这里插入图片描述

2、部署测试

2.1、部署流程定义

部署成功,流程定义ID=Multi-instanceCountersigning:1:387494
在这里插入图片描述

2.2、测试流程定义是否部署成功

 @Test
public void testDeployQuery() {
    ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
    ProcessDefinition processDefinition = processDefinitionQuery.deploymentId("387491").singleResult();
    System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());
    System.out.println("processDefinition.getName() = " + processDefinition.getName());
    System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());
    System.out.println("processDefinition.getId() = " + processDefinition.getId());
    }

控制台打印结果如下,说明部署成功。
在这里插入图片描述

2.3、启动流程实例

/**
 * 启动流程实例
 */
@Test
public void testRunProcess() {
    ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();

    // 我们需要runtimeService来启动流程实例
    RuntimeService runtimeService = processEngine.getRuntimeService();

    // 构建流程变量
    Map<String, Object> varivales = new HashMap<>();
    ArrayList<String> assigneeList = new ArrayList<>();
    assigneeList.add("u1");
    assigneeList.add("u2");
    assigneeList.add("u3");
    assigneeList.add("u4");
    assigneeList.add("u5");
    varivales.put("assigneeList", assigneeList);

    // 启动流程实例
    ProcessInstance holidayRequest = runtimeService.startProcessInstanceByKey("Multi-instanceCountersigning", varivales);
    System.out.println("Multi-instanceCountersigning.getProcessDefinitionId() = " + holidayRequest.getProcessDefinitionId());
    System.out.println("Multi-instanceCountersigning.getName() = " + holidayRequest.getName());
    System.out.println("Multi-instanceCountersigning.getActivityId() = " + holidayRequest.getActivityId());
    System.out.println("Multi-instanceCountersigning.getId() = " + holidayRequest.getId());
}

启动流程实例,控制台输入如下,流程实例Id:542501
在这里插入图片描述
进入到多实例任务节点之后,根据实例ID,我们看一下ACT_RU_TASK数据库表的数据变化。
在这里插入图片描述
我们可以看到上面自动生成了5个任务实例,assignee也是我们代码中传入的数据。
再看下工作流流程变量表 ACT_RU_VARIABLE
在这里插入图片描述
发现除了我们自己传入的assigneeList、assignee,还会自动生成一些属性。

2.4、完成任务

我们设置的多实例任务的判断条件是,完成人数大于50%到下一节点,也就是说,5人通过3人即可。

2.5、任务查询

/**
 * 测试任务查询
 */
@Test
public void testQueryTask() {
    ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    List<Task> list = taskService.createTaskQuery()

            // 指定查询的流程key
            .processDefinitionKey("Multi-instanceCountersigning")

            // 查询这个任务的处理人
            .taskAssignee("u1")
            .list();
    for (Task task : list) {
        System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());
        System.out.println("task.getAssignee() = " + task.getAssignee());
        System.out.println("task.getName() = " + task.getName());
        System.out.println("task.getDescription() = " + task.getDescription());
    }
}

// 控制台打印结果如下
/**
task.getProcessDefinitionId() = Multi-instanceCountersigning:3:540004
task.getAssignee() = u1
task.getName() = 多实例任务UserTask
task.getDescription() = null
*/

接下来执行任务。

@Test
public void testCompleteTask() {
    ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    Task task = taskService.createTaskQuery()

            // 指定查询的任务key = task.getName()
            .processDefinitionKey("多实例任务UserTask")
            .taskAssignee("u1")
            .singleResult();

    // 创建流程变量
    Map<String, Object> map = new HashMap<>();
    map.put("approved", true);

    // 完成任务
    taskService.complete(task.getId(), map);
}

u1用户已经完成这个任务,我们再看下数据库。
在这里插入图片描述
u1数据消失了,再看下ACT_RU_VARIABLE数据库表,nrOfCompletedInstances属性=1了。
在这里插入图片描述
接着提交两个实例,任务结束,ACT_RU_TASK多实例任务节点数据全部清空。
在这里插入图片描述

2.6 流程跟踪

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

颓了呀

收到你温暖的礼物,超开心,感激

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

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

打赏作者

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

抵扣说明:

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

余额充值