一、内嵌表单
优点:在绘制流程图的时候,就可以定义相应的填写表单,填写的字段内容也可以是动态的。
缺点:每一个任务都需要进行配置
- 在绘制流程图的时候,添加动态表单属性
2. 获取任务详情的时候,查询对应的表单,暂存或提交表单
/**
* 根据taskId获取当前任务的详情
*/
@Override
public TaskVo getCurrentTaskById(String taskId) {
TaskVo taskVo = new TaskVo();
// 获取任务信息
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
taskVo.setTaskName(task.getName());
taskVo.setTaskId(task.getId());
taskVo.setAssignee(task.getAssignee());
// 获取当前的表单
TaskFormData taskFormData = formService.getTaskFormData(taskId);
List<FormProperty> formProperties = taskFormData.getFormProperties();
taskVo.setFormProperties(formProperties);
return taskVo;
}
获取任务详情的时候,就可以将当前任务对应需要填写的表单字段获取出来一起进行响应:
获取出来的表单,在前端填写完成之后,还可以将表单的内容进行暂存或者提交。
/**
* 暂存任务
*/
@Override
public void saveFormData(Map<String, String> formData) {
String taskId = formData.get("taskId");
formService.saveFormData(taskId, formData);
}
/**
* 提交任务
*/
@Override
public void submitTaskFormData(Map<String, String> formData) {
String taskId = formData.get("taskId");
formService.submitTaskFormData(taskId, formData);
}
暂存任务,就是将填写的表单内容进行暂存的,下载查询详情的时候,对应表单字段的value就是有值的,同样可以修改。
提交任务,就是将表单的内容进行提交,同时流程进入下一个环节。
二、外置表单
集成SpringBoot的Flowable提供了.form的自动部署机制。会对保存在forms文件夹下的表单自动部署。
# flowable config
flowable:
# 关闭异步,不关闭历史数据的插入就是异步的,会在同一个事物里面,无法回滚
# 开发可开启会提高些效率,上线需要关闭
async-executor-activate: true
# 将databaseSchemaUpdate设置为true。当Flowable发现库与数据库表结构不一致时,会自动将数据库表结构升级至新版本。
database-schema-update: true
check-process-definitions: false
db-history-used: true
history-level: full
common:
app:
idm-url: http://localhost:8099/flowable-idm
idm-admin:
user: admin
password: test
form:
# 默认的表单⽂件后缀
resource-suffixes: "**.form"
# 默认的表单⽂件位置
resource-location: "classpath*:/forms/"
1. json表单
在resource目录下,可以新建forms文件夹,然后将XXX.form文件存到该文件夹下:
{
"key": "leaderApproval.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": "string",
"required": true,
"placeholder": "empty"
}
]
}
在绘制流程时候,需要使用该表单的环节上,添加上表单标识为表单文件名称即可。
这样在查询到当前任务的时候,就可以获取对应的表单字段。
/**
* 根据taskId获取当前任务的详情
*/
@Override
public TaskVo getCurrentTaskById(String taskId) {
TaskVo taskVo = new TaskVo();
// 获取任务信息
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
taskVo.setTaskName(task.getName());
taskVo.setTaskId(task.getId());
taskVo.setAssignee(task.getAssignee());
String formKey = task.getFormKey();
// 获取动态表单属性
TaskFormData taskFormData = formService.getTaskFormData(taskId);
List<FormProperty> formProperties = taskFormData.getFormProperties();
taskVo.setFormProperties(formProperties);
// 获取表单
if (StringUtils.isNoneBlank(formKey)) {
taskVo.setFormKey(formKey);
FormInfo taskFormModel = taskService.getTaskFormModel(taskId);
SimpleFormModel simpleFormModel = (SimpleFormModel) taskFormModel.getFormModel();
List<FormField> fields = simpleFormModel.getFields();
taskVo.setFields(fields);
}
return taskVo;
}
查询到任务之后,就可以填写表单内容完成当前任务。
/**
* 完成json表单数据的任务
*/
@Override
public void completeJsonFormTask(Map<String, Object> jsonFormData) {
String taskId = (String) jsonFormData.get("taskId");
FormInfo formInfo = taskService.getTaskFormModel(taskId);
taskService.completeTaskWithForm(taskId, formInfo.getId(), "批准请假", jsonFormData);
}
2. html表单
使用html表单,需要创建好表单的html文件,然后在绘制流程的时候,填写流程标识为对应的html表单名称:
部署流程的时候,需要将外置表单一起进行部署。
/**
* 部署Html表单
*/
/**
* 部署Html表单
*/
@Test
public void deployHtmlForm() {
DeploymentBuilder builder = repositoryService.createDeployment();
//外置表单的部署需要和流程图一起部署,只有一起部署,他们才会有相同的 DEPLOYMENT_ID,
//否则两者的 DEPLOYMENT_ID 不同,在后续的查找中就找不到对应的表单。
//所以我们选择将所有资源方放在resources/templaets下,手动一起部署
builder.addClasspathResource("templates/HtmlFormProcess.bpmn20.xml");
//另外,外置表单的name要和流程定义中的formkey一致
InputStream is = this.getClass().getClassLoader().getResourceAsStream("templates/qjlc.html");
builder.addInputStream("qjlc.html", is);
is = this.getClass().getClassLoader().getResourceAsStream("templates/approval.html");
builder.addInputStream("approval.html", is);
Deployment deploy = builder.deploy();
System.out.println("deployment.getId() = " + deploy.getId());
}
/**
* 获取启动表单信息
*/
@Test
public void getStartHtmlFormContent(){
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.latestVersion().processDefinitionKey("HtmlFormProcess").singleResult();
System.out.println("pd = " + pd);
String startFormKey = formService.getStartFormKey(pd.getId());
System.out.println("startFormKey = " + startFormKey);
String renderedStartForm = (String) formService.getRenderedStartForm(pd.getId());
System.out.println("renderedStartForm = " + renderedStartForm);
}
/**
* 启动Html表单流程
*/
/**
* 启动Html表单流程
*/
@Test
public void startHtmlFormFlow() {
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("HtmlFormProcess")
.singleResult();
Map<String, String> vars = new HashMap<>();
vars.put("days", "3");
vars.put("reason", "去看《深海》");
vars.put("startTime", new Date().toString());
ProcessInstance pi = formService.submitStartFormData(pd.getId(), vars);
System.out.println("pi.getId() = " + pi.getId());
}
/**
* 获取渲染后的任务表单信息
*/
@Test
public void getTaskHtmlFormContent() {
Task task = taskService.createTaskQuery().processDefinitionKey("HtmlFormProcess").singleResult();
String renderedForm = (String) formService.getRenderedTaskForm(task.getId());
System.out.println(renderedForm);
}
/**
* 完成任务
*/
@Test
public void completeHtmlFormTask() {
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("HtmlFormProcess")
.singleResult();
Task task = taskService.createTaskQuery()
.processDefinitionId(pd.getId())
.singleResult();
Map<String, String> vars = new HashMap<>();
vars.put("days", "2");
vars.put("reason", "去看《深海》吧");
vars.put("startTime", new Date().toString());
formService.submitTaskFormData(task.getId(), vars);
}
/**
* 查询历史表单信息
*/
@Test
public void getHistoryHtmlFormFields() {
HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery()
.processDefinitionKey("HtmlFormProcess")
.singleResult();
List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery()
.processInstanceId(hpi.getId()).list();
for (HistoricVariableInstance instance : list) {
System.out.println(instance.getVariableName() + " " + instance.getValue());
}
}
三、结语
关于flowable内嵌表单的用法很丰富,可以参考官方文档进行配置。