springboot集成Camunda审核流程(二):Camunda Modeler设计器设置BPMN流程

springboot集成Camunda

一、Camunda Modeler

​ Camunda Modeler -为流程设置器(建模工具),用来构建我们的流程模型。Camunda Modeler流程绘图工具,支持三种协议类型流程文件分别为:BPMN、DMN、Form。

​ Camunda Modeler下载地址:https://camunda.***/download/modeler/

下载完成之后解压之后,打开Camunda Modeler.exe 即可使用。

下面分别简单介绍一下 Camunda Modeler 建模工具分别支持的三种协议区别。 我文档主要是基于 BPMN协议来实现的流程相关开发,BPMN协议的使用介绍–跳转连接

打开流程设计器后,选择BPMN协议,就会出现我们的设计界面,如下图所示:

  • BPMN协议

      BPMN diagram:Business Process Management And Notation 业务流程管理和符号。
    
      由BPMI(The Business Process Management Initiative)开发了一套标准叫业务流程建模符号(BPMN - Business Process Modeling Notation),BPMN规范是由标准组织BPMI发布的BPMN 1.0规范发布于2004年5月。此规范展示了BPMI组织两年多的努力成果。BPMN的主要目标就是要提供被所有业务用户理解的一套标记语言,包括业务分析者、软件开发者以及业务管理者与监察者。BPMN还将支持生成可执行的BPEL4WS语言。所以,BPMN在业务流程设计与流程实现之间搭建了一条标准化的桥梁。
    
  • DMN协议

      DMN diagram:Decision Management And Notation 决策管理和符号。
    

    DMN倾向于决策(规则引擎),DMN是由对象管理组于2015年发布。它是用于业务决策的图形语言。
    DMN的主要目的是为分析人员提供一种工具,用于将业务决策逻辑与业务流程分离。

  • Form协议

      Form:一个简单的表单模型,可以低代码生成简单的页面。在Camunda中,表单用于在业务流程中收集和显示数据。Camunda支持两种类型的表单:生成的表单和自定义表单。生成的表单是由Camunda自动创建的,基于流程变量的类型和结构。自定义表单则允许开发人员自定义表单的外观和行为。
    

1、相关概念

  • 流程定义与流程实例:二者就像java中的类与new的对象的关系,对象是类的实例,类是对象的模板。
  • 流程定义key:标识一类流程定义,流程定义带有版本功能,而流程定义id才代表具体的流程定义。
  • 流程定义Id: 具有唯一性,同一个流程定义有不同版本,他们的流程定义Key相同,但是流程定义id不同。
  • 流程实例Id:代表具体的某条流程实例,具有唯一性。
  • 任务:任务是直接对应人的,每个节点上会有多个任务,但是每个任务只会对应一个处理人。
  • 会签:指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批,需全部同意之后,审批才可到下一审批节点。
  • 或签:指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批,只要其中任意一人审批即可到下一审批节点。

会签的分类

​ 一个流程节点可以有一个至多个任务,也称之为工作项。如果是多个任务则称这个节点为会签

  1. 串行会签:串行会签也叫顺序会签,指按照提交流程处理人的次序user1、user2、user3依次接收待办任务,并按顺序处理流程。(Camunda Modeler中用 “ 三 ” 标识)

  2. 并行会签:指user1、user2、user3同时接收到流程待办任务,并行处理。(Camunda Modeler中用III标识)

会签的通过规则介绍

  1. 全部通过:会签人全部审批通过表决后,会签通过。
  2. 按数量通过:达到一定数量的通过表决后,会签通过。
  3. 按比例通过:达到一定比例的通过表决后,会签通过。
  4. 一票通过:只要有一个表决通过的,会签通过。
  5. 一票否决:只要有一个表决时否定的,会签不通过。

2、UserTask任务参数

​ 用户结点的相关设如下图所示:

  • NAME:表示该结点名称
  • ID:该节点定义id
  • User assignment:审核人相关的设置
    • Assignee:审核人,填写方式为 ${ userOne } 的方式

流程设置完成之后,生成的 .BPMN 文件中就会详细记录我们设置的流程图,文件中详细记录了流程定义的相关数据信息。

​ **注:**BPMN文件中的 process标签下的参数

1. id参数:对应的就是该流程的定义 KEY_ 在文件中的该id值没有改变,则重新部署流程定义之后,流程引擎会默认是版本的迭代,并取最新版本来发起新的流程实例。
2. name参数:对应的是在构建流程时,给流程设置的名称,对于数据库中的 NAME_字段。

3、会签和或签流程的创建

会签 / 或签 中的参数介绍:

  • nrOfInstances:会签中总共的实例数(实例总数)

  • nrOfActiviteInstances:当前活动的实例数量,即还没有完成的实例数量对应串行而言该值始终为1

  • loopCounter :循环计数器,办理人在列表中的索引

  • nrOf***pletedInstances:已经完成的实例数量

  • loop cardinality:循环基数。可选项。可以直接填整数,表示会签的人数。

  • Collection:集合。可选项。会签人数的集合,通常为list,和loop cardinality二选一。

  • Element variable:元素变量。选择Collection时必选,为collection集合每次遍历的元素。

  • ***pletion condition:完成条件。可选。比如设置一个人完成后会签结束,那么其他人的代办任务都会消失。

  • 或签节点的创建

​ 通过 ***pletion condition中的表达式来确定节点是否通过,从来通过表达式还设置为 会签 / 或签

4、流程设计器中的监听器

​ 流程设计器中的每个节点、节点间的连接线都可以设置监听器,同时监听器中也有多种执行方式。

4.1 监听器类型

可以分为三种类型来使用,分别是:

  • 连接线上的 Execution Listeners(take)监听器,如下图所示

  • 任务节点上的Task Listeners 执行监听器:

任务节点上的任务监听器有分多钟类型,不同类型(Event type)的任务监听器的执行时机是不相同的,所以在实际使用时要根据实际需求来使用。

  • 任务节点上的Execution Listeners 任务监听器:

任务节点上的 Execution Listeners 执行监听器有两种类型分别是 end 和 start

4.1 监听器相关参数介绍

Event type :触发时机

Listener ID:

listener type :监听器实施类型

Field Injection :该模块下可以设置监听器参数,后续能传递到后端使用,主要key要保持一致

在 实施类型 中大概有一下几种:

​ Delegate expression : 会调用java代码执行在Spring中的配置同名的Bean,参数填写 ${BeanName}

​ Java Class :参数填写目标类的全路径。 同时该类需要实现对应的接口并重写接口中对应的方法(执行体)

​ Expression:利用El表达式调用对应的 java 类。

4.3 监听器实现类
  • 后台执行监听器:ExecutionListener

在流程实例执行的过程中触发某个事件时,执行监听器允许你去执行额外的java代码或者对指定的表达式求值。

其中 Field Injection 可以用来给监听器传参,key需要与监听器实现类中的key保持一致。

在java代码中实现的方式有多种:

​ eg:通过java类实现 ExecutionListener 类,重写@Override 方法 notify()即可

package ***.zhidasifang.camundaproject.camundaListener;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.ExecutionListener;
import org.camunda.bpm.engine.delegate.Expression;

/**
 * @Description:---任务结点的监听器:映射的java类实现ExecutionListener接口,一旦出发绑定的节点则会自动触发notify方法
 * @ClassName: MyExecutionListener
 */
public class MyExecutionListener implements ExecutionListener {
    //与流程设计器中的参数name字段对应!!!---在java代码中需要定义成Expression的对象 名称和name保持一致
    private Expression ListenersParameter;
    /**
     *@Description--todo--映射的java类实现ExecutionListener接口,一旦出发绑定的节点则会自动触发notify方法
     *@Param [delegateExecution]
     *@return void
     */
    @Override
    public void notify(DelegateExecution delegateExecution) throws Exception {
        System.out.println("message.getValue(delegateExecution) = " + ListenersParameter.getValue(delegateExecution));
    }
}
  • 任务监听器:TaskListener

与 ExecutionListener 大体一致,不同的是 TaskListener 的java实现类是 TaskListener 接口

属性值有:create【创建任务时触发】、assignment【任务指定负责人触发】、***plete:【任务完成后触发】、delete:【任务删除前触发】

package ***.zhidasifang.camundaproject.camundaListener;
import org.camunda.bpm.engine.delegate.DelegateTask;
import org.camunda.bpm.engine.delegate.Expression;
import org.camunda.bpm.engine.delegate.TaskListener;
/**
 * @Description:--TaskListener可以监听流程创建销毁等等与业务无关的操作java代码与ExepressionListener大体一致,
 * 不同的是TaskListener的java类实现的是TaskListener接口
 * @ClassName: MyTaskListener
 */
public class MyTaskListener implements TaskListener {
    private Expression message;
    /**
    *@Description--监听到任务,会自动执行notify方法!!
    *@Param [delegateTask]
    *@return void
    */
    @Override
    public void notify(DelegateTask delegateTask) {
    }
}
4.4 Listeners监听器触发时机

​ 根据上面介绍的Listenners相关的设置方式,通过创建一个节点,并实现它的所有监听器(Task Listeners 和 Execution Listeners )包括连接线上的监听器。启动该流程测试各个监听器的执行时机顺序。

  • 节点上设置的监听器示意图
  • UserTask 用户任务节点的连线上设置的Listeners

​ 在后台的Java代码中我们对应的都要实现这几个监听器。当然这些监听器也可以重复的指向同一个java实现类,后台的监听器类:

/**
 * @Description: 测试任务监听器执行时机
 * 用于[Listeners触发时机测试流程] 的任务监听器测试
 * @ClassName: FlowTaskListeners
 */
@***ponent
@RequiredArgsConstructor
@Slf4j
public class FlowTaskListeners implements TaskListener {

    /**
     * 1、在create事件之前不会触发其他与任务相关的事件
     * 2、当分配人、所有者等属性发生变更时会触发update事件,任务的初始化是不会触发update事件的。
     * 3、在流程定义中显式定义了具有受让人的任务被创建时,assignment事件会在create事件之后触发。
     * 更改任务assignee属性,assignment事件会在update事件之后触发。
     * 4、当任务成功完成时,触发***plete事件。
     * 5、delete事件发生在任务从运行时数据中删除之前。
     * 6、***plete事件和delete事件是互斥的。
     */
    @Override
    public void notify(DelegateTask delegateTask) {
        String eventName = delegateTask.getEventName();
        log.info("【TaskListener 执行】=========="+eventName);
    }
}

-------------------分割线-----------------
    
/**
 * @Description: 执行监听器测试流程
 * 用于[Listeners触发时机测试流程]的执行监听器
 * @ClassName: FlowExecutionListeners
 */
@***ponent
@Slf4j
@RequiredArgsConstructor
public class FlowExecutionListeners implements ExecutionListener {

    @Override
    public void notify(DelegateExecution execution) throws Exception {
        String eventName = execution.getEventName();
        log.info("【ExecutionListener 执行】=========="+eventName);
        /**
         * 设置受理人Assignee
         * execution.getVariable("type");
         * execution.setVariable("key","value");
         * */
    }
}

通过启用流程、节点审核等操作之后,可以得到流程中监听器的执行时机顺序。如下所示:

<!--
1.开始节点ExecutionListener
【ExecutionListener 执行】==========start
【ExecutionListener 执行】==========end

2.连线ExecutionListener
【ExecutionListener 执行】==========take

3.Task任务节点上设置的Listeners
Active任务节点:ExecutionListener(start节点开始)
【ExecutionListener 执行】==========start
Active任务节点:TaskListener(create ~~> assignment ~~> ***plete)
【TaskListener 执行】==========create
【TaskListener 执行】==========assignment
【TaskListener 执行】==========***plete
Active任务节点:ExecutionListener(end节点结束)
【ExecutionListener 执行】==========end

4.连线ExecutionListener
【ExecutionListener 执行】==========take

5.结束节点ExecutionListener
【ExecutionListener 执行】==========start
【ExecutionListener 执行】==========end
-->

5、 SendTask 抄送任务节点设置

​ Send task 是流程中的一种任务节点,我们可以通过该节点设置自定义活动,实现流程异步执行任务流程中所设计到的其他相关操作(eg:发送邮件等操作) 。

​ 抄送任务的事项方式与监听器的实现方式类型,其中的 type 字段中可选择Send Task 节点的实现方式,这里我们选择的是通过java代码来实现,所以就需要后天有与之对应的SendTask 任务节点的实现类,当流程执行到该位置后,会自动调用后台该实现类。

  • 后台实现代码
package ***.zhidasifang.camundaproject.camundaTaskOtherMethods;

import ***.zhidasifang.camundaproject.utils.LogUtils;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.***ponent;

/**
 * @Description: SendTask抄送环节任务 委托实现类
 * @ClassName: MySendMessageTask
 *
 * Camunda的Send Task用于向外部系统或服务发送消息。消息可以是同步或异步的,可以发送到队列、主题或其他类型的消息中间件。
 * Send Task通常用于将消息发送到外部系统,而无需等待响应或结果。相反,它只是向外部系统发出信号,通知其执行某些操作或启动某个过程。
 *
 */
@***ponent
public class MySendMessageTask implements JavaDelegate {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Override
    public void execute(DelegateExecution delegateExecution) throws Exception {
        System.out.println("执行消息推送接口成功!!");
        LogUtils.writeLogger(logger,"!!!!!!!!!!","SendTask任务触发成功!!");
    }
}

6、流程节点参数传递方式

​ 在BPMN流程设计图中,我们可以在流程中设置各种参数,使得在我们的Java代码中可以获取到设置的相关参数,这一步主要是为了在流程设计后,在审核中,我们可以通过获取对应的参数。从而在后台中通过各种Listeners 来动态的设置下一节点的审核人。实现流程节点的审核人实现动态设置!

​ 流程中设置参数的方式主要是有两中方式去设置参数,然后通过java代码中获取,分别如下:

6.1 在监听器中设置参数

​ 该方式就是通过task任务节点的监听器中设置参数,然后后台在对应的监听器中获取到设置的对应参数。

  • BPMN流程中设置的参数

如上图所示,在Listeners监听器中设置了两个参数,其中 name表示参数名称,该名称必须要与后台监听器实现类获取参数时的名称保持一致,否则会获取不到传递的参数数据。

  • 后代java代码获取监听器中设置的参数方式:
package ***.zhidasifang.camundaproject.camundaListeners.tasklisteners;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.***ponent;
import java.util.ArrayList;

/**
 * @Description:节点开始前的监听器,通过input中的参数设置对应的审核人信息!---动态地为任务分配办理人,而不是在流程定义中静态地指定。
 * @ClassName: StartListennersSetAssignee
 */
@***ponent
@Slf4j
@RequiredArgsConstructor
public class TestTempListeners implements TaskListener{
//这里定义的Expression  字段名称必须要和流程中 Field Injection 名称一致
    private Expression listenerField1;
    private Expression listenerField2;
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
    *@Description---任务监听器实现类
    *@Param [delegateTask]
    *@return void
    */
    @Override
    public void notify(DelegateTask delegateTask) {
        //LogUtils.writeLogger(LoggerFactory.getLogger(this.getClass()),delegateTask,"节点创建监听器-CreateListener执行!");
        //LogUtils.writeLogger(logger,delegateTask,"节点创建监听器-CreateListener执行!");
        logger.info("监听器Listeners执行成功!。。。。。。。。。。。。");

        /**
        * 获取Listeners Field injection 参数。 监听器中注入的参数获取方式!
        * */
        String value = (String) listenerField1.getValue(delegateTask);
        String value2 = (String) listenerField2.getValue(delegateTask);
        System.out.println("监听器Listeners中注入的参数为   listenerField1="+value+"    listenerField2="+value2);

        /**
         * 获取监听器类型
         * */
        String eventName = delegateTask.getEventName();
        System.out.println("eventName = " + eventName);

        /**
         * 获取camunda中的各种服务Service
         * delegateTask.getProcessEngine() //基础引擎获取其他各类Service
         * */

        /**
         * 获取生成流程时就已经存在的参数variable [可以获取原有设置的参数值!!]
         * */
        String initiator = (String) delegateTask.getVariable("initiator");
        System.out.println("initiator = " + initiator);

        delegateTask.setAssignee(type1);
        // TODO: 正常情况下会去数据库获取对应上级userId  setAssignee
    }
}
6.2 在Inputs标签中设置参数

​ 在Inputs中设置的惨参数本质上也是类似与通过 setVariable() 的方式设置了对应的数据在流程中。同样,我们的流程也可以通过该方式来实现动态设置受理人,通过Inputs标签的方式设置的流程节点参数,同样能通过我们 的监听器去执行时通过调用getVariable(Stirng key) ,来获取设置的参数。

  • BPMN-Inputs标签中设置参数。

​ 如同所示我们在对应节点上设置参数数据,同时我们需要给节点设置一个Listeners监听器(Execution Listeners 、Task Listeners 两种监听器均可),当节点的监听器触发时,在对应的监听器中我们就能获取到设置的Inputs参数!

  • 后台Java实现代码
@***ponent
@Slf4j
@RequiredArgsConstructor
public class TestTempListeners implements TaskListener{
//这里定义的Expression  字段名称必须要和流程中 Field Injection 名称一致
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
    *@Description---任务监听器实现类
    *@Param [delegateTask]
    *@return void
    */
    @Override
    public void notify(DelegateTask delegateTask) {
        /**
         * 获取监听器类型
         * */
        String eventName = delegateTask.getEventName();
        System.out.println("eventName = " + eventName);

        /**
         * 获取camunda中的各种服务Service
         * delegateTask.getProcessEngine() //基础引擎获取其他各类Service
         * */

        /**
         * 监听器中,获取inputs中注入的参数数据:
         * */
        //方式1:
        String  type1 = (String) delegateTask.getVariable("type");
        System.out.println("type1 = " + type1);
        //方式2:
        String type2 =(String) delegateTask.getProcessEngine().getRuntimeService().getVariables(delegateTask.getExecutionId()).get("type");
        System.out.println("type2 = " + type2);

        /**
         * 获取生成流程时就已经存在的参数variable [可以获取原有设置的参数值!!]
         * */
        String initiator = (String) delegateTask.getVariable("initiator");
        System.out.println("initiator = " + initiator);

        delegateTask.setAssignee(type1);
        // TODO: 正常情况下会去数据库获取对应上级userId  setAssignee
    }

**注:**在动态设置节点审核人时,普通的User Task 用户审核节点,可以通过task任务节点上的Listeners监听器来获取参数根据实际场景来设置受理人(通过setAssignee)。

​ 但是会签节点则不能通过task任务节点上的监听器来动态设置审核人,因为在执行到会签节点时,由于会签节点中含有 ${assignee} 等表达式,需要在执行到该节点之前要对这些变量赋值(通过setVariable),所有在存在会签节点时,我们必须在会签节点之前将对应的变量赋值,这时就需要在会签节点的连接线上通过Listeners来对这些表达式中的Variable数据进行赋值处理!

转载请说明出处内容投诉
CSS教程_站长资源网 » springboot集成Camunda审核流程(二):Camunda Modeler设计器设置BPMN流程

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买