Activiti实战

《Activiti实战》笔记java

1、 概览

1.1 结构图

Activiti结构图

1.2 Service

RepositoryService 管理流程定义
RuntimeService 执行管理,包括启动、推动、删除流程实例等操做
TaskService 任务管理
HistoryService 历史管理(执行完的数据的管理)
IdentityService 组织机构管理
FormService 一个可选服务,任务表单管理
ManagerService

1.3 数据库表格

表前缀 类型 含义
ACT_RE_* repository 包含了流程定义和流程静态资源 (图片,规则,等等)
ACT_RU_* runtime 运行时的表,包含流程实例,任务,变量,异步任务等运行中的数据,只在流程实例执行过程当中保存数据,在流程结束时删除记录, 这样运行时表能够一直很小速度很快。
ACT_ID_* identity 包含身份信息,好比用户,组等
ACT_HI_* history 包含历史数据,好比历史流程实例, 变量,任务等
ACT_GE_* general 用于不一样场景下,如存放资源文件

1.4 Activiti数据表清单

表分类 表名 解释
通常数据 ACT_GE_BYTEARRAY 通用的流程定义和流程资源
通常数据 ACT_GE_PROPERTY 系统相关属性
流程历史记录 ACT_HI_ACTINST 历史的流程实例
流程历史记录 ACT_HI_ATTACHMENT 历史的流程附件
流程历史记录 ACT_HI_COMMENT 历史的说明性信息
流程历史记录 ACT_HI_DETAIL 历史的流程运行中的细节信息
流程历史记录 ACT_HI_IDENTITYLINK 历史的流程运行过程当中用户关系
流程历史记录 ACT_HI_PROCINST 历史的流程实例
流程历史记录 ACT_HI_TASKINST 历史的任务实例
流程历史记录 ACT_HI_VARINST 历史的流程运行中的变量信息
用户用户组表 ACT_ID_GROUP 身份信息-组信息
用户用户组表 ACT_ID_INFO 身份信息-组信息
用户用户组表 ACT_ID_MEMBERSHIP 身份信息-用户和组关系的中间表
用户用户组表 ACT_ID_USER 身份信息-用户信息
流程定义表 ACT_RE_DEPLOYMENT 部署单元信息
流程定义表 ACT_RE_MODEL 模型信息
流程定义表 ACT_RE_PROCDEF 已部署的流程定义
运行实例表 ACT_RU_EVENT_SUBSCR 运行时事件
运行实例表 ACT_RU_EXECUTION 运行时流程执行实例
运行实例表 ACT_RU_IDENTITYLINK 运行时用户关系信息
运行实例表 ACT_RU_JOB 运行时做业
运行实例表 ACT_RU_TASK 运行时任务
运行实例表 ACT_RU_VARIABLE 运行时变量表

1.5 核心API

1.5.1 ProcessInstance

表明流程定义的执行实例。流程实例就表示一个流程从开始到结束的最大的流程分支,即一个流程中流程实例只有一个。数据库

1.5.2 Execution

执行对象Execution,流程按照流程定义的规则执行一次的过程;缓存

  1. 并发执行的流程, 总线路表明ProcessInstance,而分线路中每一个活动表明Execution
  2. 一个流程中,执行对象并发执行的流程, 总线路表明ProcessInstance,而分线路中每一个活动表明Execution
  3. 能够存在多个,可是流程实例ProcessInstance只能有一个

2、 Method & table

2.1 DeploymentBuilder.deploy()

Deployment deployment = processEngine.getRepositoryService()//
    .createDeployment()
    .addClasspathResource("diagrams/LeaveBill.bpmn")
    .addClasspathResource("diagrams/LeaveBill.png")
    .deploy();
复制代码

这一步在数据库中将操做三张表:并发

  1. act_re_deployment(部署对象表)
    存放流程定义的显示名和部署时间,每部署一次增长一条记录
  2. act_re_procdef(流程定义表)
    存放流程定义的属性信息,部署每一个新的流程定义都会在这张表中增长一条记录。

    注意:当流程定义的key相同的状况下,使用的是版本升级框架

  3. act_ge_bytearray(资源文件表)
    存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增长两条记录,一条是关于bpmn规则文件的,一条是图片的(若是部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都是以二进制形式存储在数据库中。
  • ACT_RE_PROCDEF
    流程解析表,解析成功了,在该表保存一条记录。业务流程定义数据表 ACT_RE_PROCDEF(act_re_procdef)异步

    NAME 字段名 字段描述
    ID_ 流程ID {processDefinitionKey}:{processDefinitionVersion}:{generated-id}
    REV_ 版本号
    CATEGORY_ 流程命名空间 流程定义的Namespace就是类别
    NAME_ 流程名称 该编号就是流程文件process元素的name属性值
    KEY_ 流程定义ID 该编号就是流程文件process元素的id属性值
    VERSION_ 流程版本号 由程序控制,新增即为1,修改后依次加1来完成的
    DEPLOYMENT_ID_ 部署编号 部署表ID
    RESOURCE_NAME_ 流程bpmn文件名称
    DGRM_RESOURCE_NAME_ png流程图片名称
    DESCRIPTION_ 描述信息 描述
    HAS_START_FORM_KEY_ start节点是否存在formKey 0否 1是
    SUSPENSION_STATE_ 是否挂起 1激活 2挂起

    此表和ACT_RE_DEPLOYMENT是多对一的关系,即一个部署的bar包里可能包含多个流程定义文件,每一个流程定义文件都会有一条记录在ACT_RE_PROCDEF表内,每一个流程定义的数据,都会对于ACT_GE_BYTEARRAY表内的一个资源文件和PNG图片文件。和ACT_GE_BYTEARRAY的关联是经过程序用ACT_GE_BYTEARRAY.NAME与ACT_RE_PROCDEF.NAME_完成的, 在数据库表结构中没有体现ide

  • ACT_RE_DEPLOYMENT
    用来存储部署时须要持久化保存下来的信息ui

    是否主键 字段名 字段描述
    ID_ 部署编号,自增加
    NAME_ 部署包的名称
    CATEGORY_ 类型 VARCHAR(255)
    DEPLOY_TIME_ 部署时间 TIMESTAMP
  • ACT_GE_BYTEARRAY
    保存全部二进制数据 LeaveBill.bpmn和LeaveBill.png都是ResourceEntity,被添加入表中
    ACT_GE_BYTEARRAY(act_ge_bytearray)spa

    Name 字段名 字段描述
    ID_  ID_ 主键ID,资源文件编号,自增加
    REV_ 版本号 INT(11)
    NAME_ 部署的文件名称,
    DEPLOYMENT_ID_ 来自于父表ACT_RE_DEPLOYMENT的主键
    BYTES_ 大文本类型,存储文本字节流 LONGBLOB
    GENERATED_ 是不是引擎生成 0为用户生成,1为Activiti生成

2.2 RuntimeService().startProcessInstanceByKey()

当流程到达一个节点时,会在ACT_RU_EXECUTION表中产生1条数据,若是当前节点是用户任务节点,这是会在ACT_RU_TASK表中添加一条记录设计

  1. ACT_RU_TASK(运行时任务数据表)
    (执行中实时任务)代办任务查询表
    ACT_RU_TASK(act_ru_task)

    是否主键 字段名 字段描述
    ID_
    REV_ 版本号 INT(11)
    EXECUTION_ID_ 实例id(外键EXECUTION_ID_) 执行实例ID
    ** PROC_INST_ID_** 流程实例ID(外键PROC_INST_ID_) VARCHAR(64)
    PROC_DEF_ID_ 流程定义ID VARCHAR(64)
    NAME_ 任务名称 节点定义名称
    PARENT_TASK_ID_ 父节任务ID 父节点实例ID
    DESCRIPTION_ 任务描述 节点定义描述
    TASK_DEF_KEY_ 任务定义key 任务定义的ID
    OWNER_ 所属人(老版) 拥有者(通常状况下为空,只有在委托时才有值)
    ASSIGNEE_ 代理人员(受让人) 签收人或委托人
    DELEGATION_ 代理团 委托类型,DelegationState分为两种:PENDING,RESOLVED。如无委托则为空VARCHAR(64)
    PRIORITY_ 优先权 INT(11)
    CREATE_TIME_ 建立时间 TIMESTAMP
    DUE_DATE_ 执行时间 耗时
    SUSPENSION_STATE_ 暂停状态 1表明激活 2表明挂起
  2. ACT_RU_EXECUTION(运行时流程执行实例)
    核心,个人待办任务查询表
    ACT_RU_EXECUTION(act_ru_execution)

    是否主键 字段名 字段描述
    ID_ ID_
    REV_ 版本号 INT(11)
    PROC_INST_ID_ 流程实例编号 VARCHAR(64)
    BUSINESS_KEY_ 业务主键ID VARCHAR(255)
    PARENT_ID_ 父执行流程 父节点实例ID
    PROC_DEF_ID_ 流程定义Id VARCHAR(64)
    SUPER_EXEC_ VARCHAR(64) 64
    ACT_ID_ 实例id 节点实例ID即ACT_HI_ACTINST中ID
    IS_ACTIVE_ 激活状态 是否存活
    IS_CONCURRENT_ 并发状态 是否为并行(true/false)
    IS_SCOPE_ TINYINT(4)
    IS_EVENT_SCOPE_ TINYINT(4)
    SUSPENSION_STATE_ 暂停状态_ 挂起状态 1激活 2挂起
    CACHED_ENT_STATE_ 缓存结束状态_ INT(11)
  3. ACT_RU_IDENTITYLINK(身份联系)
    主要存储当前节点参与者的信息,任务参与者数据表。
    ACT_RU_IDENTITYLINK(act_ru_identitylink)

    是否主键 字段名 字段描述
    ID_ ID_
    REV_ 版本号 INT(11)
    GROUP_ID_ 用户组ID VARCHAR(255)
    TYPE_ 用户组类型 主要分为如下几种:assignee、candidate、owner、starter、participant。即:受让人,候选人,全部者、起动器、参与者
    USER_ID_ 用户ID VARCHAR(255)
    TASK_ID_ 任务Id VARCHAR(64)
    PROC_INST_ID_ 流程实例ID VARCHAR(64)
    PROC_DEF_ID_ 流程定义Id VARCHAR(64)
  4. ACT_HI_ACTINST(历史节点表)
    历史活动信息。这里记录流程流转过的全部节点,与HI_TASKINST不一样的是,taskinst只记录usertask内容

    ACT_HI_ACTINST(act_hi_actinst)

    是否主键 字段名 字段描述
    ID_ ID_
    PROC_DEF_ID_ 流程定义ID VARCHAR(64)
    PROC_INST_ID_ 流程实例ID VARCHAR(64)
    EXECUTION_ID_ 流程执行ID VARCHAR(64)
    ACT_ID_ 活动ID 节点定义ID
    TASK_ID_ 任务ID 任务实例ID 其余节点类型实例ID在这里为空
    CALL_PROC_INST_ID_ 请求流程实例ID 调用外部流程的流程实例ID'
    ACT_NAME_ 活动名称 节点定义名称
    ACT_TYPE_ 活动类型 如startEvent、userTask
    ASSIGNEE_ 代理人员 节点签收人
    START_TIME_ 开始时间 DATETIME
    END_TIME_ 结束时间 DATETIME
    DURATION_ 时长,耗时 毫秒值

3、 教程

3.1 setVariable和setVariableLocal的区别

  • setVariable
    设置流程变量的时候,流程变量名称相同的时候,后一次的值替换前一次的值,且TASK_ID的字段不会存听任务ID的值
  • setVariableLocal
    设置流程变量的时候,针对当前活动的节点设置流程变量,若是一个流程中存在2个活动节点(分支),对每一个活动节点都设置流程变量,即便流程变量的名称相同,后一次的版本的值也不会替换前一次版本的值,它会使用不一样的任务ID做为标识,存放2个流程变量值,并且能够看到TASK_ID的字段会存听任务ID的值

3.2 排他网关

只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索若是发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。
使用流程变量,设置连线的条件,并按照连线的条件执行工做流,若是没有条件符合的条件,则以默认的连线离开.须要设置流程变量,不设置时抛异常,不会走,默认网关

3.3 并行网关

若是同一个并行网关有多个进入和多个外出顺序流, 它就同时具备分支和汇聚功能。 这时,网关会先汇聚全部进入的顺序流,而后再切分红多个并行分支。
并行网关不会解析条件, 即便顺序流中定义了条件,也会被忽略

3.4 接收活动receiveTask

在任务建立后,意味着流程会进入等待状态, 直到引擎接收了一个特定的消息, 这会触发流程穿过接收任务继续执行.
ReceiceTask任务,机器自动完成的任务,只会在act_ru_execution表中产生一条数据

3.5 我的任务

设置任务办理人

3.5.1 使用流程变量

使用流程变量设置我的任务

3.5.2 使用类

使用类设置我的任务1
使用类设置我的任务2
使用类设置我的任务代码
经过 processEngine.getTaskService().setAssignee(taskId, userId);将我的任务从一我的分配给另外一我的,会覆盖监听器设置的代办人

3.6 组任务

  1. 直接指定办理人
    直接指定办理人
    查询组任务成员列表
List<IdentityLink> list = processEngine.getTaskService().getIdentityLinksForTask(taskId)
复制代码

act_ru_identitylink:存听任务的办理人,包括我的任务和组任务,表示正在执行的任务
act_hi_identitylink:存听任务的办理人,包括我的任务和组任务,表示历史任务
区别在于:
若是是我的任务TYPE的类型表示participant(参与者)
若是是组任务TYPE的类型表示candidate(候选者)和participant(参与者)

  1. 使用流程变量

    使用流程变量-组任务

  2. 使用类-组任务1
    使用类-组任务2
    使用类-组任务code
    经过processEngine.getTaskService().claim (taskId, userId);将组任务分配给我的任务,也叫认领任务,即指定某我的去办理这个任务.此时不会校验userId是否在候选人中,若是不在,则将userId加入到候选人列表,对应IdentityLink表格
    领任务的时候,能够是组任务成员中的人,也能够不是组任务成员的人,此时经过Type的类型为participant来指定任务的办理人

3.7 角色组

act_id_group:角色组表
act_id_user:用户表
act_id_membership:用户角色表
在部署流程定义和启动流程实例的中间,设置组任务的办理人,向Activiti表中存放组和用户的信息

角色组code

4、 Activiti实战

4.1 任务

4.1.1 用户任务

任务监听
Create 建立任务,assignment分配任务,complete完成任务
Expression,delegateExpression,Alfresco script
activity:initiator=”xxx”:能够把启动流程实例的操做人以变量名称”xxx”保存到数据库中,须要配合identityService.setAuthenticatedUserId(authenticatedUserId)使用

4.1.2 脚本任务

能够运行脚本语言
复制代码

4.1.3 Service 任务

Service 任务

4.1.4 业务规则任务

能够和drools整合

业务规则任务

4.1.5 邮件任务

在serviceTask的基础上由activiti扩展而来,能够发邮件

4.1.6 Camel

在serviceTask的基础上由activiti扩展而来,是用来解决消息路由的框架

4.1.7 Manual task

不作任何处理,流程引擎无需关系如何处理它,activiti把手动任务当作一个空任务来处理,当到达此任务时由引擎自动完成并转向下一个任务

4.1.8 Receive task

在任务建立后开始等待消息的到来,直到被触发才会完成任务,能够经过RuntimeService接口的signal()方法发送信号触发接收任务

4.1.9 多实例

容许一个任务甚至子流程能够重复执行屡次如一个申请由多人审批,能够选择顺序执行和并行执行 能够设置重复执行,设置完成条件

4.2 网关gateway

4.2.1 排他网关

若是多个线路的计算结果为true,则会执行第一个值为true的网关,若线路都没有true,则抛出异常

4.2.2 并行网关

并行网关聚集处,只有当全部进入的流程都进来了,才能往下走流程

4.2.3 包容网关inclusivegateway

融合了排他网关和并行网关的特性,既能够同时执行多条线路,又容许在网关上设置条件

4.2.4 事件网关

事件网关是专门为中间捕获事件设置,容许设置多个输出流指向多个不一样的中间捕获事件(最少两个).在流程执行到事件网关后,流程处于”等待”状态,中间捕获事件须要依赖中间抛出事件触发才能更改等待状态为活动状态

4.3 子流程与调用活动

4.3.1 子流程

子流程能够包含流程规范的大部分模型
最经常使用的是把最通用的流程独立成子流程,嵌入到各个流程当中

  • 约束
  1. 只能且仅能包含一个空启动事件
  2. 至少要有一个结束事件
  3. 在子流程中顺序流不能直接设置输出流到子流程以外的活动上,能够经过边界事件代替

4.3.2 调用活动 call activiti

和子流程做用一致,但表现方式不一样,可使用一个调用活动取代嵌入子流程的活动,经过建立一个调用活动模型并制定外部流程的id方式做为主流程的一个子活动

调用活动

4.3.3 事件子流程

和子流程相似,不一样的是事件子流程不能直接启动,而是被动地由其余的事件触发启动 能够由异常事件,信号事件,消息事件,定时器事件,补偿事件等触发

4.3.4 事务子流程

该子流程拥有事务性,ACID,回滚

4.4 边界与中间事件

边界事件是绑定在活动上的”捕获型”事件,一旦触发边界事件,当前活动会被中断而后按照边界事件以后的输出流执行
一个活动只能绑定一个边界事件
部分边界事件中能够设置cancelActivity属性值,以控制是否取消执行输出流指定的活动

4.4.1 定时器边界事件

定时启动事件:用于在指定的时间启动一个新的流程 定时器边界事件:附属在一个非自动任务,调用活动,子流程上,在上游任务执行完成以后开始倒计时准备触发事件

4.4.2 异常边界事件

用来捕获嵌入子流程或调用活动抛出的异常 异常抛出以后被主流程的异常边界事件捕获,同时嵌入子流程或调用活动中的活动也被中断执行 异常边界事件能够直接在流程定义图

<sequenceFlow id="flow-treasurerAudit" name="财务不一样意" sourceRef="exclusivegateway-treasurerAudit" targetRef="errorendevent2">
复制代码

也能够直接抛出异常

异常边界事件

4.4.3 信号边界事件

信号边界事件能够捕获流程执行中抛出的信号,能够附加在各类活动和子流程上
信号抛出事件是全局的:信号边界事件不只能够捕获本流程的信号,还能够捕获到其余流程的信号事件,若是定义了多个信号边界事件并监听同一个信号,则会同时触发多个边界事件

4.4.4 取消边界事件

专门针对事务子流程所设计的,用来捕获子流程中抛出的取消事件,不能附加到其余活动上

  1. 一个事务主流程只容许附加一个取消边界事件
  2. 若是事务子流程中嵌套了子流程,仅仅触发已经完成了的子流程补偿事件?
  3. 对于多实例的事务子流程,若其中一个实例触发取消事件,则所有实例都会被触发取消边界事件

4.4.5 补偿边界事件

用于事务子流程中针对事务失败后的业务逻辑进行补偿 若补偿边界事件附加的活动室多实例的,当抛出补偿事件时,每个实例都会触发补偿边界事件

4.4.6 中间捕获事件

根据事件不一样的类型须要使用不一样的方式才能继续执行后续的输出流的活动 中间捕获事件必须链接一个输入流和输出流

  1. 定时器中间捕获事件
    定时器中间捕获事件
  2. 信号中间捕获事件 用来捕获抛出的信号事件,信号id一致便可捕获
    广播式传播
  3. 消息中间捕获事件
    定向一对一传播,一次只能把一个消息发给一个指定的流程实例

4.4.7 中间抛出事件

中间抛出事件须要有对应的捕获事件接收才有意义
中间抛出事件通常用在一个任务完成后须要发送通知或执行其余系统任务的场景,工做流引擎会对抛出的事件进行传播

  1. 空中间抛出事件 不执行流程功能,能够借助activiti对大多数活动/事件添加的扩展功能使其更有意义,能够做为中间状态/结果的处理器
  2. 信号中间抛出事件 能够同步也能够异步
    同步时信号发出后等待信号被捕获处理完成后才能继续往下执行流程,中间出错则回滚 异步时发出信号后当即执行下一流程, 不会回滚

4.5 监听器

4.5.1 执行监听器

容许在执行流程中执行java代码
监听类型:start,end,take
能够捕获的事件:

  1. 流程实例启动,结束
  2. 输出流捕获
  3. 活动启动,结束
  4. 路由开始,结束
  5. 中间事件开始,结束
  6. 触发开始事件,触发结束事件

3种监听器执行类型

  1. Class:实现接口
  2. Expression:表达式,相似EL
  3. DelegateExpression:能够以参数形式设置实现的的接口类

4.5.2 任务监听器

只能应用于用户任务
监听类型

  1. Assignment:在任务被分配给某个办理人以后触发,在create以前
  2. Create:须要逐一处理任务的办理人,候选人,候选组属性
  3. complete:任务完成,运行时运行数据被删除以前 顺序: assignment-> create->complete

4.6 任务表单

表单属性

表单属性
流程变量是整个流程实例公用的,即便是表单上要求必填的属性,在流程中已有值时就能够不填

5、 定时做业

引擎在部署流程以后,引擎对部署的流程定义作一些初始化的工做,其中就包含对定时做业的注册和对消息事件的注册
ACT_RU_JOB表的主要字段说明

ACT_RU_JOB表
定时启动事件能够按照预设时间启动是由于引擎不断刷新数据库表ACT_RU_JOB的记录,根据时间匹配做业,命中以后就执行做业.

6、 消息启动事件

部署流程以后引擎会在初始化中处理消息事件,把消息的类型注册到数据act_ru_event_subscr中
在流程执行过程当中遇到了消息类型事件或经过API触发消息事件触发该表读取数据,而且根据消息的属性调用消息处理器

消息启动事件
在调用代码 processInstance = runtimeService.startProcessInstanceByMessage("启动XXX流程"); 流程会找到act_ru_event_subscr表中的EVENT_NAME匹配消息名称,找到就启动

7、 结束事件

终止结束事件:终止整个流程
空结束事件:只结束一条输出流的执行
在历史任务实例中HistoricActivityInstance,有个HistoricActivityInstance.getDeleteReason(),对应act_hi_taskinst表的DELETE_REASON_字段
若是一个任务正常完成(经过complete方法),则DELETE_REASON_值为completed,若是任务是被删除的,则删除缘由为deleted
好比在空结束事件没有complete,而主流程就completed了,则子流程的记录就为deleted

8、 消息边界事件

消息边界事件,信号边界事件与异常边界事件会多出一个cancelActivity属性,可取值为:
True:在边界事件触发后取消已注册的消息事件
False:在边界事件触发后仍然保留已注册的事件,能够再次触发

消息边界事件
消息边界事件配置

runtimeService.messageEventReceived(messageName, executionId);	//触发消息边界事件
复制代码

同理,触发信号事件runtimeService.signalEventReceived(signalName, executionId);
若是一个任务有附加的消息边界事件,当任务执行完成且边界事件没有被触发时,那么已经注册的事件将在任务完成时被删除

9、 任务

9.1 任务委托人与任务办理人

委托人:owner_
办理人:assignee_

//参与人:
taskService.addUserIdentityLink(taskId, userId, identityLinkType);
taskService.getIdentityLinksForTask(taskId);
//签收
processEngine.getTaskService().claim(task.getId(), " user "); // 数据库字段owner_为user
//委派
processEngine.getTaskService().delegateTask(task.getId(), "henryyan"); // //数据库字段assignee _为henryyan
//被委派人完成任务
taskService.resolveTask(task.getId());
复制代码

最终Assignee:user1,owen:user1
owner是任务全部者只能是一个,assignee是任务肯定的接收者,也只能是一个,candidate是可领取任务的人,那么就会有不少,因此candidate单独放在identitylink表中关联task,而前两个就直接在task表中标明便可
当调用taskService.getIdentityLinksForTask("task102");时,这三种状况(两个表)都要统计进去。

任务委派原理

9.2 签收与反签收

签收: taskService.claim(taskId, userId);
反签收: taskService.claim(taskId, null); // 把已签收的任务办理人置空

9.3 候选人与候选人组

taskService.addUserIdentityLink(taskId, userId, identityLinkType)
identityLinkType有分红几类人

角色分类

设置认证用户有什么用?

9.4 子任务

一个任务能够拆分出多个任务交给不一样的人处理
当主任务complete时,子任务也会默认完成,从ru表删除进入hi表

Task task2 = taskService.newTask();
    task2.setParentTaskId(task.getId());
    task2.setAssignee("sub task");
    taskService.saveTask(task2); //记录到数据库中
复制代码

杂记

  1. 经过父流程查看子流程
List<Execution> processInstances = processEngine.getRuntimeService().createExecutionQuery().processInstanceId("13201").list();
复制代码
相关文章
相关标签/搜索