Flowable实战(五)表单和流程变量
一、流程变量
流程实例按步骤执行时,需要保存并使用一些数据,在Flowable中,这些数据称为变量(variable)。
流程实例可以持有变量,称作流程变量(process variables)。
为了使用效率,Flowable将变量分为两种:运行时变量、历史变量。
1.1 运行时变量
流程实例运行时的变量,存入act_ru_variable表中。在流程实例运行结束时,此实例的变量在表中删除。
在流程实例创建及启动时,可设置流程变量。所有的startProcessInstanceXXX方法都有一个可选参数用于设置变量。例如,在RuntimeService中:
ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);
也可以在流程执行中加入变量。例如,(RuntimeService):
void setVariable(String executionId, String variableName, Object value);
void setVariableLocal(String executionId, String variableName, Object value);
void setVariables(String executionId, Map<String, ? extends Object> variables);
void setVariablesLocal(String executionId, Map<String, ? extends Object> variables);
读取变量方法(请注意TaskService中有类似的方法。这意味着任务与执行一样,可以持有局部变量,其生存期为任务持续的时间。)
Map<String, Object> getVariables(String executionId);
Map<String, Object> getVariablesLocal(String executionId);
Map<String, Object> getVariables(String executionId, Collection<String> variableNames);
Map<String, Object> getVariablesLocal(String executionId, Collection<String> variableNames);
Object getVariable(String executionId, String variableName);
<T> T getVariable(String executionId, String variableName, Class<T> variableClass);
注意:由于流程实例结束时,对应在运行时表的数据跟着被删除。所以,查询一个已经完结流程实例的变量,只能在历史变量表中查找。
1.2 历史变量
历史变量,存入act_hi_varinst表中。在流程启动时,流程变量会同时存入历史变量表中;在流程结束时,历史表中的变量仍然存在。可理解为“永久代”的流程变量。
获取已完成的、id为’XXX’的流程实例中,所有的HistoricVariableInstances(历史变量实例),并以变量名排序。
historyService.createHistoricVariableInstanceQuery()
.processInstanceId("XXX")
.orderByVariableName.desc()
.list();
二、表单
在实际业务中,流程伴随着各种各样的表单,Flowable引擎将表单数据统一作为流程变量存入变量表中。所以,对于Flowable引擎,可以完全独立于表单运行,因为可以用流程变量替代表单数据。
但一般的,我们需要结构化的数据,表单仍然是我们推荐的用法。
表单定义有两种方法,内置表单和外部表单。
2.1 内置表单
以请假为例,XML内容:
<process id="leave" name="请假流程-内置表单">
<startEvent id="start">
<extensionElements>
<flowable:formProperty id="startDate" name="请假开始事件" type="date"
datePattern="dd-MMM-yyyy" required="true" readable="true" writeable="true"/>
<flowable:formProperty id="endDate" name="请假结束事件" type="date"
datePattern="dd-MMM-yyyy" required="true" readable="true" writeable="true"/>
<flowable:formProperty id="reason" name="请假原因" type="string"
required="true" readable="true" writeable="true"/>
<flowable:formProperty id="leaveType" type="enum" name="请假类型">
<flowable:value id="personalLeave" name="事假" />
<flowable:value id="annualLeave" name="年假" />
</flowable:formProperty>
</extensionElements>
</startEvent>
</process>
使用方法:
StartFormData FormService.getStartFormData(String processDefinitionId)
或
TaskFormData FormService.getTaskFormData(String taskId)
内置表单了解即可,实际应用更多的是使用外部表单。
2.2 外部表单
根据表单文件自行渲染的任务表单,称为外部表单。
2.2.1 XML内容
<process id="leave" name="请假流程-内置表单">
<startEvent id="start" flowable:formKey="form1"></startEvent>
</process>
注意:flowable:formKey="form1"中的"form1"对应表单定义文件的"key"值。
2.2.2 表单定义
- 表单定义文件的后缀为.form。
- 表单的JSON定义以key、name和description开头。
- 表单引擎通过属性key来辨别表单在整个表单引擎中的唯一身份。对于来源相同的同一个表单定义的版本系统也是基于属性key运作的。
- 第二部分是一个数组类型fields,表单定义的字段在这里阐明。
- 第三部分是可选的,用来定义表单的结果outcomes。示例如下:
{
"key": "form1",
"name": "My first form",
"fields": [
{
"id": "input1",
"name": "Input1",
"type": "text",
"required": false,
"placeholder": "empty"
}
],
"outcomes": [
{
"id": "null",
"name": "Accept"
},
{
"id": "null",
"name": "Reject"
}
]
}
2.2.3 部署表单
在springboot环境下,resources/forms目录下任何.form后缀的表单定义文件都会被自动部署。
例如,将2.2.2表单定义内容保存为leave.form文件,放入resources/forms目录下。
注意:实际应用中,应当让前端流程设计器生成指定格式的表单定义文件,通过与前文提到的接口方式,更新部署流程定义及表单定义资源。
2.2.4 获取及提交表单参数
实际上,渲染表单所需的所有数据都组装在下面两个方法:
StartFormData FormService.getStartFormData(String processDefinitionId)
TaskFormdata FormService.getTaskFormData(String taskId)
可以通过下面两个方法提交表单参数:
ProcessInstance FormService.submitStartFormData(String processDefinitionId, Map<String,String> properties)
void FormService.submitTaskFormData(String taskId, Map<String,String> properties)
表单参数FormProperty的具体信息:
public interface FormProperty {
/**
* 在{@link FormService#submitStartFormData(String, java.util.Map)}
* 或{@link FormService#submitTaskFormData(String, java.util.Map)}
* 中提交参数时使用的key
*/
String getId();
/** 显示标签 */
String getName();
/** 在本接口中定义的类型,例如{@link #TYPE_STRING} */
FormType getType();
/** 可选。这个参数需要显示的值 */
String getValue();
/** 这个参数是否可以读取:在表单中显示,并可通过
* {@link FormService#getStartFormData(String)}
* 与{@link FormService#getTaskFormData(String)}
* 方法访问。
*/
boolean isReadable();
/** 用户提交表单时是否可以包含这个参数? */
boolean isWritable();
/** 输入框中是否必填这个参数 */
boolean isRequired();
}
2.2.5 获取及提交表单数据
获取指定流程实例的表单数据的方法:
FormModel RuntimeService.getStartFormModel(String processDefinitionId, String processInstanceId);
提交表单数据的方法:
// 附带表单数据启动流程实例
ProcessInstance RuntimeService.startProcessInstanceWithForm(String processDefinitionId, String outcome, Map<String,Object> properties, String taskName);
// 附带表单数据完成任务
void TaskService.completeTaskWithForm(String taskId, String formDefinitionId, String outcome, Map<String,Object> properties);
表单数据实际存放在流程变量表,所以,用流程变量的方法同样可以获取及提交表单数据。
2.3 表单类型字段
表单支持以下类型字段
- text: 文本字段
- multi-line-text: 多行文本字段
- integer: 文本字段,但是只允许数字类型的值
- boolean: 复选框字段
- date: 日期字段
- dropdown: 选择框字段,定义字段时可以设置选项的值
- radio-buttons: 单选字段,定义字段时可以设置选项的值
- people: 选择框字段,可以选中用户表里的一个用户
- functional-group: 选择框字段,可以选中分组表里的一个组
- upload: 上传文件字段
- expression: 一个标签,在标签文本中你可以运用JUEL表达式操作变量或其他动态的值
2.4 自定义表单字段类型
在实际应用中,Flowable提供的表单字段类型并不能完全满足需求,往往我们需要自定义表单字段类型。
所有自定义字段类型需要继承一个表达类型抽象类“org.flowable.engine.form.AbstractFormType”。
比如,定义一个"卡片"自定义类型:
public class CardFormType extends AbstractFormType {
// 定义表单类型的标识符
@Override
public String getName() {
return "card";
}
// 把表单中的值转换为实际的对象(实际处理逻辑根据具体业务而定)
@Override
public Object convertFormValueToModelValue(String propertyValue) {
return propertyValue;
}
// 把实际对象的值转换为表单中的值(实际处理逻辑根据具体业务而定)
@Override
public String convertModelValueToFormValue(Object modelValue) {
return (String) modelValue;
}
}
新建配置类,注册自定义字段类型解析类
@Configuration
public class ApplicationConfig extends WebMvcConfigurerAdapter {
@Bean
public BeanPostProcessor activitiConfigurer() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof SpringProcessEngineConfiguration) {
List<AbstractFormType> customFormTypes = Arrays.<AbstractFormType>asList(new CardFormType());
((SpringProcessEngineConfiguration)bean).setCustomFormTypes(customFormTypes);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
};
}
}
2.5 自定义表单引擎
Flowable支持自定义表单引擎以适应各种场景。只需要实现接口org.flowable.engine.impl.form.FormEngine,然后在引擎中注册自定义的表单引擎实现类即可。
public class MyFormEngine implements FormEngine {
// 表单引擎的名称
@Override
public String getName() {
return "MyFormEngine";
}
// 实际处理逻辑根据具体业务而定
@Override
public Object renderStartForm(StartFormData startFormData) {
return "MyStartData";
}
// 实际处理逻辑根据具体业务而定
@Override
public Object renderTaskForm(TaskFormData taskFormData) {
return "MyTaskData";
}
}
注册方法与自定义表单字段类型相似,在配置类中加入以下语句:
List<FormEngine> customFormEngines = Arrays.<FormEngine>asList(new MyFormEngine());
((SpringProcessEngineConfiguration)bean).setCustomFormEngines(customFormEngines);
使用方法:
Object FormService.getRenderedStartForm(String processDefinitionId, "myFormEngine");
Object FormService.getRenderedTaskForm(String taskId);
三、小结
通过本篇,我们了解到了表单和流程变量的具体使用,同样的,在实际业务使用中,还需要不少优化。比如,我们可以在formKey中保存通用的key,通过算法或转换得到实际需要使用的表单模板,在普通屏幕尺寸的Web应用中显示一个表单,在手机等小屏幕中显示另一个表单。还有下一篇将讲到的“集成JPA”,进一步对表单和流程变量的使用做出优化。
Flowable实战(五)表单和流程变量的更多相关文章
- jQuery框架学习第十一天:实战jQuery表单验证及jQuery自动完成提示插件
jQuery框架学习第一天:开始认识jQueryjQuery框架学习第二天:jQuery中万能的选择器jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQuer ...
- asp.net 微信企业号办公系统-表单及流程设计配置实例
在环境搭建好之后,我们就来学习一下怎样快速创建一个流程,并执行和流转该流程(我们这里讲的只是入门,不涉及到具体流程参数设置). 创建一个流程步骤为:在数据库在创建表-->设计表单-->设置 ...
- activiti自定义流程之整合(四):整合自定义表单部署流程定义
综合前几篇博文内容,我想在整合这一部分中应该会有很多模块会跳过不讲,就如自定义表单的表单列表那一块,因为这些模块在整合的过程中都几乎没有什么改动,再多讲也是重复无用功. 正因为如此,在创建了流程模型之 ...
- activiti自己定义流程之整合(四):整合自己定义表单部署流程定义
综合前几篇博文内容.我想在整合这一部分中应该会有非常多模块会跳过不讲,就如自己定义表单的表单列表那一块,由于这些模块在整合的过程中都差点儿没有什么修改,再多讲也是反复无用功. 正由于如此,在创建了流程 ...
- FSBPM流程引擎(002)之表单+自定义流程挂载到引擎
本章节介绍如何将实际业务的表单和自定义流程挂载到FSBPM流程引擎上. 首先进入引擎交互界面: 点击创建:->出差申请 然后根据实际的业务输入对应的数据项即可,比如[姓名,部门,开始时间,结束时 ...
- activiti实战系列之动态表单 formService 自定义变量类型
目前Activiti默认支持的类型有String,long,enum,date,boolean,collection 要自定义字段类型,首先需要表单类型解析类 /** * @Author:LJ * @ ...
- FlowPortal-BPM——创建新组织架构、表单、流程
一.创建新组织架构 (1)管理流程→组织管理→组织架构添加需要的组织架构→新建新成员或角色 (2)设置成员信息 二.创建新数据源(如果在已有的数据库中操作,只需要添加需要的表) (1)添加新数据库并添 ...
- CSS3实战开发 表单发光特效实战开发
首先,我们先准备好html代码: <!doctype html> <html> <head> <meta charset="utf-8"& ...
- PHP表单-PHP $_POST 变量
PHP $_POST 变量 在 PHP 中,预定义的 $_POST 变量用于收集来自 method="post" 的表单中的值. $_POST 变量 预定义的 $_POST 变量用 ...
随机推荐
- 资源分配(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 资源设置好以后,不能光摆着看,分配到各任务中去才是正道. 分配资源就需要回到与任务相关的视图了,比如[任务工作表]视图或者 ...
- 显示大纲数字(Project)
<Project2016 企业项目管理实践>张会斌 董方好 编著 话说摘要任务,给人的感觉,就像Word里的大纲级别,可我也知道,好多同学不习惯用大纲级别,而是偏爱用编号级别,最常见的也就 ...
- 论文翻译:2021_MetricGAN+: An Improved Version of MetricGAN for Speech Enhancement
论文地址:MetricGAN+:用于语音增强的 MetricGAN 的改进版本 论文代码:https://github.com/JasonSWFu/MetricGAN 引用格式:Fu S W, Yu ...
- CF1036A Function Height 题解
Content 给定一个坐标系,在它的 \(x\) 轴上有 \(2n+1\) 个点 \(P_0,P_1,P_2,...,P_{2n}\),其中对于 \(0\leqslant i\leqslant 2n ...
- Coder 投稿 | mPaaS 的多版本接入(Android)
本文作者:mPaaS 用户「Q-Coder」 同时欢迎更多的开发者向 mPaaS 投稿 原文:blog.csdn.net/yqq577/article/details/116801705 前言 对于 ...
- 雨课堂自动切换PPT代码
浏览器运行js步骤 原仓库 Podium = {}; Podium.keydown = function(k) { var oEvent = document.createEvent('Keyboar ...
- Tomcat配置使用域名访问项目
找到tomcat下的conf文件夹,打开server.xml文件 在操作之前要把域名映射到服务器上.测试办法就是,打开cmd 输入ping 域名,能够显示对应的ip即可 首先把访问端口改为80访问. ...
- Visiual Studio之c++项目瘦身(删除中间项)
欢迎指正 本文主要涉及 Visiual Studio(简称VS) 创建的c++项目 和 windows下批处理相关点. 1.中间项 A.VS创建的c++项目,生成后,会有许多中间项,包括项目生成的中间 ...
- 【九度OJ】题目1018:统计同成绩学生人数 解题报告
[九度OJ]题目1018:统计同成绩学生人数 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1018 题目描述: ...
- 【LeetCode】836. Rectangle Overlap 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/rectangle ...