松哥最近正在录制 TienChin 项目视频~采用 Spring Boot Vue3 技术栈,里边会涉及到各种好玩的技术,小伙伴们来和松哥一起做一个完成率超 90% 的项目,戳戳戳这里-->TienChin 项目配套视频来啦。
在前面的案例中,我们定义的表单使用了 HTML,实际上这个表单不仅可以使用 HTML,也可以使用 JSON 来定义表单,可能也有不少小伙伴在网上已经看到过一些使用 JSON 来定义表单的案例,今天这篇文章松哥就来和大家分享一下如何使用 JSON 来定义 Flowable 表单。
1. 默认规则
使用 JSON 来定义 Flowable 表单,我们刚好可以利用 Spring Boot 中的默认机制,即将表单文件置于 classpath:forms 目录下,那么在系统启动的时候,表单文件就会被自动部署。并且默认情况下,表单文件的后缀是 .form
。
不过对于默认的表单文件位置和表单文件后缀,我们也可以通过在 application.properties 配置文件中添加如下内容进行修改:
代码语言:javascript复制# 默认的表单文件后缀
flowable.form.resource-suffixes=**.form
# 默认的表单文件位置
flowable.form.resource-location=classpath*:/forms/
2. 创建表单
还是以我们的请假请求为例,我来创建一个表单文件,文件名为 application_form.form
,如下:
{
"key": "application_form.form",
"name": "经理审批表单",
"fields": [
{
"id": "days",
"name": "请假天数",
"type": "string",
"required": true,
"placeholder": "empty"
},
{
"id": "reason",
"name": "请假原因",
"type": "string",
"required": true,
"placeholder": "empty"
},
{
"id": "startTime",
"name": "开始时间",
"type": "date",
"required": true,
"placeholder": "empty"
},
{
"id": "endTime",
"name": "结束时间",
"type": "date",
"required": true,
"placeholder": "empty"
}
]
}
这个 key 就是表单的唯一标识符,当有多个表单的时候,这个该值不可以重复,name 是表单是名称,fields 则定义了具体的字段,这里一共有四个。
在每一个 filed 的定义中,id 表示字段名,name 则是字段的中文名称,type 表示字段的类型,require 则表示这个字段是否是必填字段,placeholder 不用多说,跟我们日常使用的 input 标签中的 placeholder 的含义一致。
OK,这样,我们的表单现在就创建好了。
由于
.form
文件,在IDEA
中,默认会被当成 Swing 里边的 form 去处理,所以需要小伙伴提前先用其他的编辑器写好.form
文件,然后再拷贝到 IDEA 中即可。
3. 创建流程
接下来我们来创建一个流程图,流程中中引用这个表单。流程图如下:
在流程图的三个 UserTask 中,分别通过如下方式去配置表单的标识:
关于流程图的其他细节我这里就不多说了,前面和大家介绍了很多了。
最后我们下载这个流程图,将之放在 Spring Boot 项目的 classpath:/processes/ 目录下,这样当项目启动的时候,这个流程图会被自动部署。
4. 测试
接下来,我们启动 Spring Boot 项目,启动之后,流程和表单都会被自动部署好,我们执行如下代码启动一个流程实例:
代码语言:javascript复制@Test
void contextLoads() {
runtimeService.startProcessInstanceByKey("askforleave");
}
流程启动成功之后,进入到 提交请假申请
环节,该环节有一个表单需要填写,我们可以先通过如下代码来查看需要填写的表单内容:
@Test
void test01() {
Task task = taskService.createTaskQuery().singleResult();
FormInfo formInfo = taskService.getTaskFormModel(task.getId());
SimpleFormModel formModel = (SimpleFormModel) formInfo.getFormModel();
System.out.println("formInfo.getId() = " formInfo.getId());
System.out.println("formInfo.getName() = " formInfo.getName());
System.out.println("formInfo.getKey() = " formInfo.getKey());
List<FormField> fields = formModel.getFields();
for (FormField field : fields) {
System.out.println("field.getId() = " field.getId());
System.out.println("field.getName() = " field.getName());
System.out.println("field.getValue() = " field.getValue());
System.out.println("field.getType() = " field.getType());
System.out.println("===============");
}
}
最终打印出来的内容如下:
代码语言:javascript复制formInfo.getId() = a5b1306a-5ab0-11ed-b35b-acde48001122
formInfo.getName() = 经理审批表单
formInfo.getKey() = application_form.form
field.getId() = days
field.getName() = 请假天数
field.getValue() = null
field.getType() = text
===============
field.getId() = reason
field.getName() = 请假原因
field.getValue() = null
field.getType() = text
===============
field.getId() = startTime
field.getName() = 开始时间
field.getValue() = null
field.getType() = date
===============
field.getId() = endTime
field.getName() = 结束时间
field.getValue() = null
field.getType() = date
小伙伴们看到,打印出来的 value 都是 null,这是因为我们还没有填写表单。
接下来我们先来完成 提交请假申请
这一任务:
@Test
void test02() {
Task task = taskService.createTaskQuery().singleResult();
Map<String, Object> vars = new HashMap<>();
vars.put("days", 10);
vars.put("reason", "玩一下");
vars.put("startTime", "2022-10-10");
vars.put("endTime", "2022-11-10");
taskService.complete(task.getId(),vars);
}
完成之后,此时任务进入到 组长审批
这一环节,现在我们再去执行 test01 方法,此时查询的就是 组长审批
这个任务的表单信息,最终打印出来日志如下:
formInfo.getId() = a5b1306a-5ab0-11ed-b35b-acde48001122
formInfo.getName() = 经理审批表单
formInfo.getKey() = application_form.form
field.getId() = days
field.getName() = 请假天数
field.getValue() = 10
field.getType() = text
===============
field.getId() = reason
field.getName() = 请假原因
field.getValue() = 玩一下
field.getType() = text
===============
field.getId() = startTime
field.getName() = 开始时间
field.getValue() = 2022-10-10
field.getType() = date
===============
field.getId() = endTime
field.getName() = 结束时间
field.getValue() = 2022-11-10
field.getType() = date
可以看到,此时都有对应的 value 了。
后续的流程就不需要我多说了吧,小伙伴们可以自行尝试下~
松哥最近正在录制 TienChin 项目视频~采用 Spring Boot Vue3 技术栈,里边会涉及到各种好玩的技术,小伙伴们来和松哥一起做一个完成率超 90% 的项目,戳戳戳这里-->TienChin 项目配套视频来啦。