摘要:Flowable表单,Flowable form
flowable框架中将表单单独抽取出来作为一个独立的的子模块进行运行。对应Flowable中的模块如下:flowable-form-engine、flowable-form-engine-configurator、org.flowable.form.spring、org.flowable.form.json.converter等。Flowable将表单分为表单的定义以及表单的运行实例两个阶段、这一点类似传统的流程开发流程,第一首先进行流程文档的部署、第二开始流程实例的启动;第三查询个人待办任务;第四完成个人任务;依次循环第三第四步骤进行。
现在我们结合一个流程的运转为例进行说明;流程图如下:
非常简单的一个流程,第一个任务节点是学生请假,第二个节点是班主任审批。
对于这个流程而言,当然是学生填写表单,班主任才能开始审批,表单涉及到的字段信息如下:
startTime:请假的开始时间,类型Date
endTime:请假的结束时间,类型Date
reason:请假的原因。
对于页面的展现形式我们可以不用特别关心,可以是html、可以是Jsp、也可以是其他的。这个展现层不作为我们讨论的重点,我们暂时关注后台的数据即可。
1、部署流程以及表单
1.1、定义表单
我们定义的表单名称是test.form,表单的定义如下:
{
"key": "form1",
"name": "学生请假流程",
"fields": [
{
"id": "startTime",
"name": "开始时间",
"type": "date",
"required": false,
"placeholder": "empty"
},
{
"id": "endTime",
"name": "结束时间",
"type": "date",
"required": false,
"placeholder": "empty"
},
{
"id": "reason",
"name": "请假原因",
"type": "text",
"required": false,
"placeholder": "empty"
}
]
}
1.2、流程以及表单的部署
/**
*
* 1、部署表单
*
*/
@Test
public void deployForm() {
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("com/shareniu/shareniu_network_flowable/test/form.bpmn").category("form")
.name("学生请假流程").key("form").deploy();
String resource = "com/shareniu/shareniu_network_flowable/test/test.form";
formRepositoryService.createDeployment().addClasspathResource(resource)
.parentDeploymentId(deploy.getId())
.deploy();
}
需要注意一点,我们流程文档中涉及到表单配置的节点定义如下:
<startEvent id="startevent1" name="Start" activiti:formKey="form1"></startEvent>
<userTask id="usertask1" name="学生请假" activiti:formKey="form1"></userTask>
<userTask id="usertask2" name="班主任审批" activiti:formKey="form1"></userTask>
上述代码中parentDeploymentId值为流程文档部署之后,流程部署表中的主键ID值,这个一定要设置,要不然后续的操作会出问题的。
2、启动实例并且设置表单的值
紧接着,我们需要启动实例,并设置表单的值。相关代码如下:
@Test
public void startProcessInstanceByKey() {
String processDefinitionId = "form:1:4";
String outcome = "shareniu";
Map<String, Object> formProperties = new HashMap<>();
formProperties.put("reason", "家里有事");
formProperties.put("startTime", new Date().toString());
formProperties.put("endTime", new Date().toString());
String processInstanceName = "shareniu";
runtimeService.startProcessInstanceWithForm(processDefinitionId, outcome, formProperties, processInstanceName);
}
我们调用了runtimeService类中的runtimeService.startProcessInstanceWithForm方法,该方法需要流程定义的id,
outcome:是否需要设置表单变量,这个我们随便定义一个值就ok。
formProperties:表单的值。
processInstanceName:流程实例的名称。
我们观察下数据库表数据的变化,ACT_FO_FORM_INSTANCE表的数据如下所示:
mysql> select id_,PROC_DEF_ID_,TASK_ID_ ,FORM_VALUES_ID_ from ACT_FO_FORM_INSTANCE;
+------+--------------+----------+-----------------+
| id_ | PROC_DEF_ID_ | TASK_ID_ | FORM_VALUES_ID_ |
+------+--------------+----------+-----------------+
| 2508 | form:1:4 | NULL | 2507 |
+------+--------------+----------+-----------------+
1 row in set (0.00 sec)
ACT_FO_FORM_RESOURCE表中新增了一条记录,如下:
{"values":{"reason":"家里有事","startTime":null,"endTime":null},"flowable_form_outcome":"shareniu"}
看到上面的数据,我们发现text类型的变量没问题,但是date类型的就有问题,这个我们后续再来讲解,其中
flowable_form_outcome中的值为我们传递的参数值。
3、查询表单信息
既然实例已经启动了,那我们查询个人任务的时候,该如何查询出来这些已经设置好的表单的信息呢?我们看下下面的代码:
@Test
public void getStartFormModel() {
String processInstanceId="2501";
String processDefinitionId="form:1:4";
FormModel fm = runtimeService.getStartFormModel(processDefinitionId, processInstanceId);
System.out.println(fm.getId());
System.out.println(fm.getKey());
System.out.println(fm.getName());
System.out.println(fm.getOutcomeVariableName());
System.err.println(fm.getVersion());
List<FormField> fields = fm.getFields();
for (FormField ff : fields) {
System.out.println("######################");
System.out.println(ff.getId());
System.out.println(ff.getName());
System.out.println(ff.getType());
System.out.println(ff.getPlaceholder());
System.out.println(ff.getValue());
System.out.println("######################");
}
}
流程实例的id:ru_task表中的流程实例id或者ACT_FO_FORM_INSTANCE表中的PROC_INST_ID_列的值。
我们直接使用了runtimeService类中的getStartFormModel方法。运行上述代码,程序的输出信息如下:
f8d53e05-2dc2-11e8-babf-46920083fa77
form1
学生请假流程
null
1
######################
startTime
开始时间
date
empty
null
######################
######################
endTime
结束时间
date
empty
null
######################
######################
reason
请假原因
text
empty
家里有事
确实是可以查看到表单的值的,那接下来我们看一下如何完成任务的时候再去设置表单中的字段值。
4、查询个人任务并填写表单
@Test
public void completeTaskWithForm() {
Map<String, Object> formProperties = new HashMap<>();
formProperties.put("reason", "家里有事1");
formProperties.put("startTime", "家里有事startTime");
formProperties.put("endTime", "家里有事endTime");
formProperties.put("days", "3");
String taskId="12509";
String formDefinitionId="6f0a472b-2d78-11e8-a80a-46920083fa77";
String outcome="牛哥";
taskService.completeTaskWithForm(taskId, formDefinitionId, outcome, formProperties);
}
上述的代码执行完毕之后,RESOURCE_BYTES_表新增的数据如下:
{"values":{"reason":"家里有事1","startTime":null,"endTime":null},"flowable_form_outcome":"牛哥"}
ACT_FO_FORM_INSTANCE表新增的数据如下:
mysql> select * from ACT_FO_FORM_INSTANCE;
+------+--------------------------------------+----------+---------------+--------------+---------------------+---------------+-----------------+------------+-----------+-------------+----------------------+
| ID_ | FORM_DEFINITION_ID_ | TASK_ID_ | PROC_INST_ID_ | PROC_DEF_ID_ | SUBMITTED_DATE_ | SUBMITTED_BY_ | FORM_VALUES_ID_ | TENANT_ID_ | SCOPE_ID_ | SCOPE_TYPE_ | SCOPE_DEFINITION_ID_ |
+------+--------------------------------------+----------+---------------+--------------+---------------------+---------------+-----------------+------------+-----------+-------------+----------------------+
| 2508 | f8d53e05-2dc2-11e8-babf-46920083fa77 | NULL | 2501 | form:1:4 | 2018-03-22 19:29:37 | NULL | 2507 | | NULL | NULL | NULL |
| 5002 | f8d53e05-2dc2-11e8-babf-46920083fa77 | 2511 | 2501 | form:1:4 | 2018-03-22 20:09:21 | NULL | 5001 | | NULL | NULL | NULL |
+------+--------------------------------------+----------+---------------+--------------+---------------------+---------------+-----------------+------------+-----------+-------------+----------------------+
2 rows in set (0.00 sec)
通过上面的表数据,我们可以得出一个结论,完成任务并设置表单中的字段值,ACT_FO_FORM_INSTANCE以及
RESOURCE_BYTES_表会新增数据。
5、总结
对于表单支持的类型,我们还没有深入讲解,后续再来说。
对于表单模板的部署以及实例的启动,我们已经有所了解。
上述的模板定义中,我们定义了formkey,这个key对应ACT_FO_FORM_DEFINITION中的KEY_列。
由于Flowable将表单单独抽取了一个表单引擎。因此在实际项目开发中,我们完全可以将表单单独成一个服务进行调用。
这样表单服务就可以控制所有流程文档中所使用的表单以及表单字段的可读、可写等操作。
分享牛老师再出新作,倾力打造Flowable精品课程系列,以最短的时间高效完成学习目标,入门进阶与实战案例并重,是0基础的新手从入门到精通的必备课程。
《Flowable实战课程》------从零入门进阶的最佳课程------【点此查看详情】
转载请注明:分享牛 » flowable表单下