flowable,199boge,进阶

本文深入探讨Flowable BPMN引擎的实战应用,涵盖了事件处理,如定时事件、消息事件、错误事件和信号事件,以及如何处理回退、撤销和动态表单。详细阐述了不同类型的启动事件、中间事件和边界事件,以及在流程中的应用。此外,还讲解了动态表单在流程审批过程中的作用,包括内置表单和外围表单的创建与使用。

Flowable BPMN 用户手册 (v 6.3.0)

idea的Flowable BPMN visualizer插件

一 多人会签

  1. 使用场景
    1. 同一个任务Task,可能需要有3个都要去做审批。
    2. 这3个人可能是并行、串行地去做审批。
    3. 这3个人中,可能要3个人都通过才结束、2个人通过就可结束、甚至1个人通过也可结束。
  2. 案例演示:
    1. 第一步:ui,绘制流程图
      1. 第1步:空启动事件
      2. 第2步:用户任务
        1. 第a步:多人、并行与串行、结束规则,Multi instance(多实例):
          1. sequential:是否串行,true:是,false:否(并行)。
          2. loop cardinality:循环的次数。比如,有3个人就写3,表示此任务由3个人单循环完成。
          3. Collection:集合(候选人集合)。如可以填写persons(List<Pserson>),然后for循环persons。
          4. Element varialbe:元素实例。pseron,即上面for循环(List<Pserson> persons)的单个实例。
          5. Completion condition:完成的条件。如:填写EL表达式${ multilnstanceCompleteTask.completeTask(execution)},此表达式的作用是从spring容器中获取相关的对象,并且调用相应的方法。
        2. 第b步:给task执行时,创建监听器,监听器通过行为触发。比如,在创建时触发:
          1. Event:监听的行为(事件)
          2. Type:
            1. java class:java类
            2. expression:表达式,如${}
            3. delegate expression:
          3. Expression:
      3. 第3步:空结束事件
    2. 第二步:idea编程
      1. 第1步:定义多从会签的规则MulitiInstanceCompleteTask.java,控制多实例完成的规则:
        @Component("mulitiInstanceCompleteTask")
        public class MulitiInstanceCompleteTask implements Serializable {
            /**
             * 完成任务是需要触发的方法
             * @param execution
             * @return
             *     false 表示会签任务还没有结束
             
             *     true 表示会签任务结束了
             */
            public boolean completeTask(DelegateExecution execution) {
                System.out.println("总的会签任务数量:" + execution.getVariable("nrOfInstances")
                        + "当前获取的会签任务数量:" + execution.getVariable("nrOfActiveInstances")
                        + " - " + "已经完成的会签任务数量:" + execution.getVariable("nrOfCompletedInstances"));
                //有一个人同意就通过
                Boolean flag = (Boolean) execution.getVariable("flag");
                System.out.println("当前意见:"+flag);
                return flag;
            }
        }
        1. flowable默认帮我们提供的流程实例的变量:
          1. nrOfInstances:总的会签任务数量。如上面设置的3。
          2. nrOfActiveInstances:当前获取的会签任务数量,即还没有完成的
          3. nrOfCompletedInstances:已经完成的会签任务数量。
        2. flag:我们自定义的。
        3. return flag:控制当前会签是否结束的。
      2. 第2步:编写监听器(供上面使用)
        @Component("mulitiInstanceTaskListener")
        public class MulitiInstanceTaskListener implements Serializable {
            
            public void completeListener(DelegateExecution execution){
                System.out.println("任务:"+execution.getId());
                System.out.println("persons:" + execution.getVariable("persons"));
                System.out.println("person" + execution.getVariable("person"));
            }
        }
        1. 作用:监听在任务Task的创建,在监听器里可以获取流程实例以及任务Task的相关信息。
      3. 第3步:部署流程实例
      4. 第4步:创建(启动)流程实例: @Test
            void startFlow() throws Exception{
                Map<String,Object> map = new HashMap<>();
                // 设置多人会签的数据
                map.put("persons", Arrays.asList("张三","李四","王五","赵六"));
                ProcessInstance processInstance = runtimeService
                        .startProcessInstanceById("myProcess:1:ba1518fc-b22d-11ec-9313-c03c59ad2248",map);
            }
        1. 注意:这里会签人数我们设置为3,但实际给的人数是4个人,这里会不会有问题呢?不会。多人会签的规则,会签人数大于或等于配置人数即可。
      5. 第5步:验证1

        1. 效果:MulitiInstanceTaskListener.completeListener()被执行3次。因为会签从数设置为3,所以循环创建任务Task为3次,所以监听器走了3次。每次创建任务,就从person列表中获取一个候选人绑定给了任务task。如下,控制台打印:
        2. act_ru_task:有3条任务被创建
          注意:但任务的分配人ASSIGNEE_没有值?这是因为我们没有去绑定它,需要我们去做动态绑定。比如,我们可以在监听器MulitiInstanceTaskListener.completeListener()进行绑定,即任务Task创建的时候进行动态绑定(指派)处理人。
      6. 第6步:通过任务id,去完成任务(查看多人会签任务时,有1个人去完成任务的效果是怎么样的) 
           @Test
            void completeTask1(){
                Map<String,Object> map = new HashMap<>();
                map.put("flag",false); //设置为true,结束多人会签
                taskService.complete("71337501-b22e-11ec-a534-c03c59ad2248",map);
                System.out.println("complete ....");
            }
         
        1. map.put("flag",false); 
          1. 去完成任务task时,绑定一个流程变量flag=false。
        2. 其中taskService.complete("71337501-b22e-11ec-a534-c03c59ad2248",map);:
          1. 71337501-b22e-11ec-a534-c03c59ad2248:为任务Task的id(act_ru_task表中查找)。
          2. 因为ASSIGNEE_没有值,表明没有指派此任务的具体候选人,所以这里使用的是包含任务id参数的处理方法,去完成(处理)任务。而不是使用包含处理人参数的处理方法。
             
      7. 第7步:验证2
        1.  MulitiInstanceCompleteTask.completeTask()被执行1次,控制台有如下打印。:

          1. 当前意见:false,表示当前会签任务没有结束,继续会签直到遇到true为止。

        2. act_ru_task:还有2条任务(删除一条任务了)

      8. 第8步:再次通过任务id,去完成任务(查看多人会签任务时,有2个人去完成任务的效果是怎么样的) 

        1. map.put("flag",true); //设置为true,结束多人会签

      9. 第9步:验证3

        1.  MulitiInstanceCompleteTask.completeTask()又被执行1次,控制台有如下打印。:

          当前意见:true,表示当前会签结束了,即“用户任务”这个节点完成了,流转空结束事件。

        2. act_ru_task:3条任务都删除了,甚至连没有去完成的那1条任务也被删除了。

​​​​​二 回退、驳回、撤消

  1. 概念
    1. 回退和驳回区别不大,其实可以把它们看成是同一个概念。
    2. 撤消与回退、驳回是有一点区别的。
      1. 撤消举例:流程流转到用户2之后,想撤回到用户1。这时用户2的历史任务就没有了。
  2. 串行的回退
    1. 应用场景

      1. 用户任务4回退到用户任务3,或者从用户任务4回退到用户任务1。

    2. 案例演示
      1. 第一步:ui,绘制流程图
        1. 用户任务1,user1
        2. 用户任务2,user2
        3. 用户任务3,user3
        4. 用户任务4,user4
      2. 第二步:idea编程
        1. 第1步:部署流程
        2. 第2步:创建(启动)流程实例
        3. 第3步:user1完成用户任务1,流转到用户任务2(user2),act_ru_task验证
        4. 第4步:user2完成用户任务2,流转到用户任务3(user3)
        5. 第5步:user3完成用户任务3,流转到用户任务4(user4)
        6. 第6步:从用户任务4(user4)回退到用户任务3(user3)
              /**
               * moveActivityIdTo(),可以从当前的流程跳转到任意的节点
               */
              @Test
              public void rollbackTask(){
                  ProcessEngine processEngine = configuration.buildProcessEngine();
                  RuntimeService runtimeService = processEngine.getRuntimeService();
                  runtimeService.createChangeActivityStateBuilder()
                          .processInstanceId("67501")
                          .moveActivityIdTo("usertask4","usertask3")//方法1:可以从当前活动的节点(Id),跳转指定的新的节点(Id)
                          //.moveActivityIdsToSingleActivityId(currentActivityIds,newActivityId)
                          .changeState();//改变状态
              }
        7. 第7步:验证
          1. act_hi_actinst:操作后我们可以在对应的历史表中看到相关的信息:
        8. 第8步:user3完成用户任务3,流转到用户任务4(user4)
        9. 第9步:从用户任务4(user4)回退到用户任务1(user1)
             @Test
              public void rollbackTask1(){
                  ProcessEngine processEngine = configuration.buildProcessEngine();
                  RuntimeService runtimeService = processEngine.getRuntimeService();
                  List<String> newActivityIds = new ArrayList<String>();
                  newActivityIds.add("usertask1");
                  runtimeService.createChangeActivityStateBuilder()
                          .processInstanceId("67501")
                          //方法1:可以从当前活动的节点(Id),跳转指定的新的节点(Id)
                          //.moveActivityIdTo("usertask4","usertask3")
                          //方法2:从当前活动的节点(id),跳转到List<String> ids集合(多个节点)。
                          .moveSingleActivityIdToActivityIds("usertask4",newActivityIds)
                          .changeState();//改变状态
              }
        10. 第10步:验证
          1. act_hi_actinst:操作后我们可以在对应的历史表中看到相关的信息:
        11. 第11步:用户任务1 》用户任务2 》用户任务3 》用户任务4
        12. 第12步:从用户任务4(user4)回退到用户任务3(user3)
             @Test
              public void rollbackTask1(){
                  ProcessEngine processEngine = configuration.buildProcessEngine();
                  RuntimeService runtimeService = processEngine.getRuntimeService();
                  List<String> newActivityIds = new ArrayList<String>();
                  newActivityIds.add("usertask1");
                  runtimeService.createChangeActivityStateBuilder()
                          .processInstanceId("67501")
                          //方法1:可以从当前活动的节点(Id),跳转指定的新的节点(Id)
                          //.moveActivityIdTo("usertask4","usertask3")
                          //方法2:从当前活动的节点(id),跳转到List<String> ids集合(多个节点)。
                          //.moveSingleActivityIdToActivityIds("usertask4",newActivityIds)
                          //方法3:不管当前节点是哪个了,就是要从当前执行实例跳到哪个节点。参数1:执行id,参数2:目标id。
                          .moveExecutionToActivityId("77501","usertask3")
                          .changeState();//改变状态
              }
    3. 注意事项
      1. 如果上面的流程图中,包含了一个排他网关,那也算是串行的。
      2. 如果上面的流程图中,包含了一个多用户实例,那也算是串行的。
      3. 可以看到任务又回到了user1处。也就是在串行的流程中,我们可以回退到任意的用户节点,当然这个串行也包括多人会签和排他网关节点。当然在回退的时候我们还可以使用moveActivityIdTo(String currentActivityId,String newActivityId)这个方法来处理。
  3. 并行的回退
    1. 应用场景

      1. 业务副总肯定是不能回退到行政副总。即使你可以强行跳过来,但这种逻辑是不合理的。

      2. 从业务副总回退到业务负责人,这是串行的,和上面的操作一样。

      3. 关注1:从并行节点回退到串行节点。并行审批流转到业务副总(没处理),同时流转到行政副总(没处理)。编码要实现,业务副总(没处理)回退到用户审批01(起始节点)。自动地,行政副总要自动回退到用户审批01(起始节点)。

      4. 关注2:并行审批流转到业

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值