Flowable实战(五)表单和流程变量
⼀、流程变量
流程实例按步骤执⾏时,需要保存并使⽤⼀些数据,在Flowable中,这些数据称为变量(variable)。
流程实例可以持有变量,称作流程变量(process variables)。
为了使⽤效率,Flowable将变量分为两种:运⾏时变量、历史变量。
1.1 运⾏时变量
流程实例运⾏时的变量,存⼊act_ru_variable表中。在流程实例运⾏结束时,此实例的变量在表中删除。
在流程实例创建及启动时,可设置流程变量。所有的startProcessInstanceXXX⽅法都有⼀个可选参数⽤于设置变量。例如,
在RuntimeService中:
ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);
也可以在流程执⾏中加⼊变量。例如,(RuntimeService):
mvc实例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(历史变量实例),并以变量名排序。
.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(String processDefinitionId)
或
TaskFormData(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(String processDefinitionId)
TaskFormData(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 获取及提交表单数据
获取指定流程实例的表单数据的⽅法:
StartFormModel(String processDefinitionId, String processInstanceId);
提交表单数据的⽅法:
// 附带表单数据启动流程实例
ProcessInstance RuntimeService.startProcessInstanceWithForm(String processDefinitionId, String outcome, Map<String,Object> properties, String taskName); // 附带表单数据完成任务
void TaskServicepleteTaskWithForm(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提供的表单字段类型并不能完全满⾜需求,往往我们需要⾃定义表单字段类型。
所有⾃定义字段类型需要继承⼀个表达类型抽象类“ine.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⽀持⾃定义表单引擎以适应各种场景。只需要实现接⼝ine.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);
使⽤⽅法:
RenderedStartForm(String processDefinitionId, "myFormEngine");
RenderedTaskForm(String taskId);
三、⼩结
通过本篇,我们了解到了表单和流程变量的具体使⽤,同样的,在实际业务使⽤中,还需要不少优化。⽐如,我们可以在formKey中保存通⽤的key,通过算法或转换得到实际需要使⽤的表单模板,在普通屏幕尺⼨的Web应⽤中显⽰⼀个表单,在⼿机等⼩屏幕中显⽰另⼀个
表单。还有下⼀篇将讲到的“集成JPA”,进⼀步对表单和流程变量的使⽤做出优化。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论