在前面的案例中,我們定義的表單使用了 HTML,實際上這個表單不僅可以使用 HTML,也可以使用 JSON 來定義表單,可能也有不少小伙伴在網(wǎng)上已經(jīng)看到過一些使用 JSON 來定義表單的案例,今天這篇文章松哥就來和大家分享一下如何使用 JSON 來定義 Flowable 表單。
1. 默認規(guī)則
使用 JSON 來定義 Flowable 表單,我們剛好可以利用 Spring Boot 中的默認機制,即將表單文件置于 classpath:forms 目錄下,那么在系統(tǒng)啟動的時候,表單文件就會被自動部署。并且默認情況下,表單文件的后綴是 .form。
不過對于默認的表單文件位置和表單文件后綴,我們也可以通過在 application.properties 配置文件中添加如下內(nèi)容進行修改:
# 默認的表單文件后綴
flowable.form.resource-suffixes=**.form
# 默認的表單文件位置
flowable.form.resource-location=classpath*:/forms/
2. 創(chuàng)建表單
還是以我們的請假請求為例,我來創(chuàng)建一個表單文件,文件名為 application_form.form,如下:
{
"key": "application_form.form",
"name": "經(jīng)理審批表單",
"fields": [
{
"id": "days",
"name": "請假天數(shù)",
"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": "結(jié)束時間",
"type": "date",
"required": true,
"placeholder": "empty"
}
]
}
這個 key 就是表單的唯一標(biāo)識符,當(dāng)有多個表單的時候,這個該值不可以重復(fù),name 是表單是名稱,fields 則定義了具體的字段,這里一共有四個。
在每一個 filed 的定義中,id 表示字段名,name 則是字段的中文名稱,type 表示字段的類型,require 則表示這個字段是否是必填字段,placeholder 不用多說,跟我們?nèi)粘J褂玫?input 標(biāo)簽中的 placeholder 的含義一致。
OK,這樣,我們的表單現(xiàn)在就創(chuàng)建好了。
由于 .form 文件,在 IDEA 中,默認會被當(dāng)成 Swing 里邊的 form 去處理,所以需要小伙伴提前先用其他的編輯器寫好 .form 文件,然后再拷貝到 IDEA 中即可。
3. 創(chuàng)建流程
接下來我們來創(chuàng)建一個流程圖,流程中中引用這個表單。流程圖如下:

在流程圖的三個 UserTask 中,分別通過如下方式去配置表單的標(biāo)識:

關(guān)于流程圖的其他細節(jié)我這里就不多說了,前面和大家介紹了很多了。
最后我們下載這個流程圖,將之放在 Spring Boot 項目的 classpath:/processes/ 目錄下,這樣當(dāng)項目啟動的時候,這個流程圖會被自動部署。
4. 測試
接下來,我們啟動 Spring Boot 項目,啟動之后,流程和表單都會被自動部署好,我們執(zhí)行如下代碼啟動一個流程實例:
@Test
void contextLoads(){
runtimeService.startProcessInstanceByKey("askforleave");
}
流程啟動成功之后,進入到 提交請假申請 環(huán)節(jié),該環(huán)節(jié)有一個表單需要填寫,我們可以先通過如下代碼來查看需要填寫的表單內(nèi)容:
@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("===============");
}
}
最終打印出來的內(nèi)容如下:
formInfo.getId() = a5b1306a-5ab0-11ed-b35b-acde48001122
formInfo.getName() = 經(jīng)理審批表單
formInfo.getKey() = application_form.form
field.getId() = days
field.getName() = 請假天數(shù)
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() = 結(jié)束時間
field.getValue() = null
field.getType() = date
小伙伴們看到,打印出來的 value 都是 null,這是因為我們還沒有填寫表單。
接下來我們先來完成 提交請假申請 這一任務(wù):
@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);
}
完成之后,此時任務(wù)進入到 組長審批 這一環(huán)節(jié),現(xiàn)在我們再去執(zhí)行 test01 方法,此時查詢的就是 組長審批 這個任務(wù)的表單信息,最終打印出來日志如下:
formInfo.getId() = a5b1306a-5ab0-11ed-b35b-acde48001122
formInfo.getName() = 經(jīng)理審批表單
formInfo.getKey() = application_form.form
field.getId() = days
field.getName() = 請假天數(shù)
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() = 結(jié)束時間
field.getValue() = 2022-11-10
field.getType() = date
可以看到,此時都有對應(yīng)的 value 了。
后續(xù)的流程就不需要我多說了吧,小伙伴們可以自行嘗試下~