流程事件
在实际业务需求中往往需要写一些代码用来控制流程运行,或根据流程的运行结果同步业务数据,更有甚者通过代码实现一些流程原本不支持的特性。而写这些代码的切入点就是事件。
流程事件可以在流程上定义,也可以在环节上定义。它们的触发顺序是先触发流程上的事件,后触发环节上的事件。
流程事件中支持调用服务、回写数据、绑定子流程、执行表达式、自动流转、自动终止和自动暂停。
作用范围
定义在流程上的事件,称为流程级事件。流程级事件在流程的任意环节中执行对应流程动作都会触发。在此事件中一般写一些公共的处理。
定义在环节上的事件,称为环节级事件。环节级事件只有基于当前环节执行对应流程动作时才会触发。在环节的事件中一般写一些私有的处理。
定义在全局流程事件文件(s.process.trait)中的事件,称为应用级事件,作用于当前应用的每个流程,参考本文下面的“全局流程事件”一节
定义在全局流程事件文件(g.process.trait)中的事件,称为租户级事件,作用于租户内每个应用的每个流程,参考本文下面的“全局流程事件”一节
添加事件
选中流程环节或者流程实例,点击右侧属性面板中的“高级设置-流程事件”
打开事件设置对话框,新增事件,选择“触发事件的操作、事件触发时机、事件处理方式和设置”
触发事件的动作
执行流程动作触发相应的流程事件
事件名 | 流程动作 | 流程级事件 | 环节级事件 |
---|---|---|---|
启动 | startProcessAction | 1 | |
结束 | finishProcessAction | 1 | |
暂停查询 | suspendProcessQueryAction | 1 | |
暂停 | suspendProcessAction | 1 | |
终止查询 | abortProcessQueryAction | 1 | |
终止 | abortProcessAction | 1 | |
唤醒 | resumeProcessAction | 1 | |
回收 | withdrawTaskAction | 1 | |
重启查询 | restartProcessQueryAction | 1 | |
重启 | restartProcessAction | 1 | |
删除 | deletePIAction | 1 | |
流转查询 | advanceProcessQueryAction | 1 | 1 |
流转 | advanceProcessAction | 1 | 1 |
回退查询 | backProcessQueryAction | 1 | 1 |
回退 | backProcessAction | 1 | 1 |
转发查询 | transferTaskQueryAction | 1 | 1 |
转发 | transferTaskAction | 1 | 1 |
加签 | addSignUserAction | 1 | 1 |
超期自动流转 | autoAdvanceProcessAction | 1 | 1 |
超期自动回退 | autoBackProcessAction | 1 | 1 |
超期自动终止 | autoAbortProcessAction | 1 | 1 |
事件触发时机
每个流程动作触发两次流程事件,分别是流程动作执行前和执行后
生效条件
默认 true,可以指定一个布尔表达式,返回 true 触发事件,反之不触发事件
流程结束时不执行流转后事件
在流程上设置流转后和结束相关的事件,在最后一个环节做流转的时候,默认流转后和结束事件都会执行,如果要控制只执行结束相关的事件,不执行流程后事件,最简单的方案就是设置生效条件
平台提供的有判断是否流转到结束的函数 isFlowToEnd()
通过这个函数控制不执行流转后事件,将函数取反 not(isFlowToEnd()),设置为流转后事件的生效条件。如下图所示
事件处理方式
调用服务
- 只支持调用请求方式为 POST 的服务
- 支持调用租户内应用的服务,url 以“/应用名”开头,服务 url 不必手写,支持选择,方法如下图所示
- 支持调用外部服务,url 以 http 或 https 开头
流程事件调用的服务无需定义参数,流程事件调用服务时,会将任务信息传入,使用下面的代码获取任务信息,主要是获取业务数据的主键
import javax.servlet.http.HttpServletRequest;
import com.justep.util.SpringWebUtil;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import com.alibaba.fastjson.*;
//获取 request
HttpServletRequest request = SpringWebUtil.getRequest();
//获取 POST 数据
InputStream is = request.getInputStream();
//转换为 String
String taskInfo = IOUtils.toString(is, "utf-8");
//转换为 JSON
JSONObject task = JSON.parseObject(taskInfo);
//获取流程动作
String action = task.getString("action");
//获取流程变量
JSONObject vars = task.getJSONObject("vars");
//String tableName = vars.getString("tableName");
//获取主表 ID
String sData1 = vars.getString("sData1");
回写数据
如果只是回写数据,无需调用服务,使用回写数据即可
点击“设置”后三个点按钮,打开表单回写设置页面,在此页面中点击新建按钮,增加回写字段,并设置回写字段值。
如果流程表单的数据是主从的,也可以对从数据集中的字段进行回写,在回写表中选择对应的表即可,每次只能选择一个表。如果要同时对主从表的数据进行回写,需要添加多次流程事件设置回写数据,而且在对从表数据回写时,是对当前主数据的所有从表数据回写的,不会针对某条从数据回写。
点击字段值后三个点按钮,打开字段值表达式编辑器,在此支持自定义设置,也可使用系统提供的函数,如图将审批处理时间表单字段的回写数据设置为:当前日期时间,即流程流转后,将会把当前日期时间回写到表单字段上。
绑定子流程
给主流程绑定子流程,用于流程结转,参考《子流程》中的流程结转
执行表达式
能被执行的表达式,目前系统只提供了更新处理意见函数,如下图所示,
服务请求
调用服务只支持 POST 的服务,使用服务请求,支持调用任意请求方法的服务。在“工作流管理-服务定义管理”中添加服务,如下图所示
服务内容的写法,参考《requests 详细说明》,在流程中调用服务可用变量包含:
- dataUrl:流程关联数据的 dbrest 地址
- sData1、sData2、sData3、sData4:业务数据
- operatorID、operatorCode、operatorName:当前操作者
- process、procesLable、activity、activityLabel、action:当前流程,环节,动作
- pi:流程实例标识
- task:当前任务标识
- postscript:当前审批意见
- 流程上定义的自定义变量
自定义流程变量请参考《流程变量》
选择服务列出服务定义管理中定义的服务
选择一个服务后,如果定义了参数,则配置参数值
配置后,显示服务内容
运行时,系统执行服务内容
关于服务调用,最简单的调用案例如下:
内容定义:其中sData1参数会从流程中获取变量
[{ "method": "GET", "url": "https://testlzsdev6-lzsdev-ide.trunk.xcaas.net/main/ceshifw/wftest?sData1=${sData1}" }]
参数格式:没有需要的配置参数可直接使用"{}"
自动流转
如果有A、B、C 3个环节,在 A 环节的流转后事件中,设置自动流转,可以实现从 A 环节流转到 C 环节的效果
自动终止
同上
自动暂停
同上
全局流程事件
定义全局流程事件,作用于每个流程,不必在每个流程中重复定义
定义全局流程事件文件,在其中指定流程动作,及处理方法
定义全局流程事件
全局流程事件文件的后缀为: g.process.trait。例如:在 service/main 目录下添加一个 xxx.g.process.trait 文件,定义全局流程事件为:在流程回退前执行数据备份。代码如下:
{
"listeners": [{
"action": "backProcessQueryAction",
"event": "before",
"handler": "invokeHttpProcedure",
"params": {
"template": [{
"method": "POST",
"url": "${dataUrl}/backup",
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"body": {
"condition": {
"key": ["${sData1}"]
},
"option":{
"cascade":true
}
}
}]
}
}]
}
文件内容说明
- listeners:事件监听
- action:触发事件的动作,参考流程动作
- event:事件触发时机
- before:在流程执行动作前执行
- after:在流程执行动作后执行
- handler:处理方法,目前均使用 invokeHttpProcedure 方法
- params:处理方法的参数
- template:参数模板,可定义多个,顺序执行
- url:处理方法的 url,例如数据备份的 url 为:${dataUrl}/backup
- template:参数模板,可定义多个,顺序执行
处理方法 invokeHttpProcedure 中可用的变量
- dataUrl:流程关联数据的 dbrest 地址
- sData1、sData2、sData3、sData4:业务数据
- operatorID、operatorCode、operatorName:当前操作者
- process、procesLable、activity、activityLabel、action:当前流程,环节,动作
- pi:流程实例标识
- task:当前任务标识
- postscript:当前审批意见
- 流程上定义的自定义变量
触发全局流程事件
发布应用,让 process.trait 起作用,发布后调试运行和正式运行都可以使用(后续会提供界面编辑 process.trait 文件,以及支持在开发时立即生效)
调试运行或正式运行时执行相应的流程动作时,会触发全局流程事件
g.process.trait 是所有应用都起作用的,如果只要定义全局事件的应用服务起作用,把名字改为 s.process.trait
超时自动流转设置处理意见
流程环节上提供的有超时设置,可以设置超时自动流转、自动回退或者自动终止。超时自动处理时后端处理的没有前端流转页面不能通过页面填写处理意见,要设置超时处理的意见可以如下操作:
流程事件(环节级和流程级上都可以)中选择相关的超时处理操作
在事件触发前,选择执行表达式,选择更新处理意见,在函数中输入要填写的处理意见即可
流程事件事务控制
流程事件同一个事件的前或后是可以添加多个,多个前或后之间是按添加的从上到下的顺序执行的,如下:
默认的多个之间是开启分布式事务的,即操作数据时是在同一个事务内提交的,一个失败就都回滚。如果不需要分布式事务可以通过流程变量控制,具体如下: 平台默认提供了“WF_DISABLE_GLOBAL_TRANSACTION”流程变量,此流程变量的值为true是禁用分布式事务,即多个事件不在同一个事务中,其中后面的执行失败了前面执行过的不会进行回滚;此流程变量的值为false或者不设置默认是启用分布式事务的。 租户管理员登录在“应用/服务管理”功能列表中找到“企业工作流”应用
在“企业工作流”应用的配置中提供的有“环境变量”
“环境变量”的“用户自定义”中设置参数
在变量名中填写:WF_DISABLE_GLOBAL_TRANSACTION,在变量值中填写:true,然后点击“确定”后要重启“企业工作流”应用即可禁用分布式事务