表单约等于流程变量。StartEvent 有一个Form属性,用于关联流程中涉及到的业务数据。
一:内置表单
每个节点都可以有不同的表单属性。
1.1 获取开始节点对应的表单
@Autowired
private FormService formService;
@Test
void delopyProcess() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deploy = processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("processes/LeaveProcess.bpmn")
.name("表单请假流程")
.deploy();
}
@Test
void getStartFormData() {
String processDefinitionId = "LeaveProcess:1:4";
StartFormData startFormData = formService.getStartFormData(processDefinitionId);
List<FormProperty> formProperties = startFormData.getFormProperties();
for (FormProperty formProperty : formProperties) {
System.out.println(formProperty.getId() + ":" + formProperty.getType() + " "
+ formProperty.getName() + ":" + formProperty.getValue());
}
}
1.2 启动流程实例
@Test
void startProcess() {
// 传统方式
Map<String, Object> variables = new HashMap<>();
variables.put("startTime", "2023-11-11 09:00:00");
variables.put("endTime", "2024-11-11 09:00:00");
variables.put("reason", "世界那么大,我想去看看");
runtimeService.startProcessInstanceByKey("LeaveProcess", variables);
}
@Test
void startProcess2() {
// 表单方式,都是保存到ACT_RU_VARIABLE,不同的是对于对变量的数据类型的处理。
// form表单对应的变量都是String类型,并且日期会作为long类型存储。
Map<String, String> variables = new HashMap<>();
variables.put("startTime", "2022-11-11 09:00:00");
variables.put("endTime", "2023-11-10 09:00:00");
variables.put("reason", "活着不是为了工作,工作是为了活得更有意义");
formService.submitStartFormData("LeaveProcess:1:4", variables);
}
两种启动方式在act_hi_detail中TYPE_是不一样的。
1.3 完成任务
@Autowired
private TaskService taskService;
@Test
void completeApprove() {
Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();
taskService.setAssignee(task.getId(), "huihui");
taskService.complete(task.getId());
}
1.4 获取某个任务的表单数据
每个节点都可以有自己不同的表单数据。
@Test
void getFormDataByTaskDefKey() {
Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();
TaskFormData taskFormData = formService.getTaskFormData(task.getId());
List<FormProperty> formProperties = taskFormData.getFormProperties();
for (FormProperty formProperty : formProperties) {
System.out.println(formProperty.getId() + ":" + formProperty.getType() + " " + formProperty.getName());
}
}
Form表单是属于流程定义中的属性,不会存在变量表中ACT_RU_VARIABLE而是从ACT_GE_BYTEARRAY中BYTES_去获取。
1.5 更新表单数据值
@Test
void updateFormData() {
Map<String, String> properties = new HashMap<>();
properties.put("opinion", "同意了");
Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();
formService.saveFormData(task.getId(), properties);
}
1.6 获取表单数据
@Test
void getTaskFormData() {
// 获取填写后的表单数据
Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();
TaskFormData taskFormData = formService.getTaskFormData(task.getId());
List<FormProperty> formProperties = taskFormData.getFormProperties();
for (FormProperty formProperty : formProperties) {
// opinion:org.activiti.engine.impl.form.StringFormType@691567ea 审批意见:同意了
System.out.println(formProperty.getId() + ":" + formProperty.getType() + " " + formProperty.getName() + ":" + formProperty.getValue());
}
}
1.7 继续完成审批
@Test
void completeApprove() {
Task task = taskService.createTaskQuery().processInstanceId("2501").singleResult();
taskService.setAssignee(task.getId(), "monday");
taskService.complete(task.getId());
}
1.8 查询历史审批过的节点对应的表单数据
@Autowired
private HistoryService historyService;
@Test
void getHistory() {
List<HistoricDetail> list = historyService.createHistoricDetailQuery()
.formProperties()
.taskId("5004")
.list();
for (HistoricDetail historicDetail : list) {
HistoricFormPropertyEntityImpl formPropertyEntity = (HistoricFormPropertyEntityImpl) historicDetail;
System.out.println(formPropertyEntity.getId() + ":" + formPropertyEntity.getPropertyId() + ":" + formPropertyEntity.getPropertyValue());
}
}
二:外部表单
- 内置表单需要在每个节点中去配置,当如果多个节点使用同一套表单属性就要配置多次比较麻烦,修改的时候也要修改多次,外部表单可以定义一次,然后其它节点都去引用同一个表单属性。
- 外部表单需要定义一个
.form
后缀的文件。 - 外部表单不需要在每个节点去指定From属性,而是在每个节点指定Form Key属性即可。
定义.form
FormLeaveProcess.form
{
"key":"FormLeaveProcess",
"name": "请假流程外部表单",
"fields": [
{
"id": "startTime",
"name": "请假开始时间",
"type": "date",
"required": true,
"placeholder": "empty"
},
{
"id": "endTime",
"name": "请假结束时间",
"type": "date",
"required": true,
"placeholder": "empty"
},
{
"id": "reason",
"name": "请假原因",
"type": "string",
"required": false,
"placeholder": "empty"
}
]
}
配置Form Key
部署流程和部署表单
@Autowired
private RepositoryService repositoryService;
@Autowired
private FormRepositoryService formRepositoryService;
@Test
void deployFormProcess() {
// 1.部署流程
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("processes/FormLeaveProcess.bpmn20.xml")
.name("外部表单请假流程")
.deploy();
// 2.部署表单
formRepositoryService.createDeployment()
.addClasspathResource("processes/FormLeaveProcess.form")
.name("请假流程外部表单")
.parentDeploymentId(deploy.getId())
.deploy();
}
启动流程
@Autowired
private RuntimeService runtimeService;
@Test
void startProcess() {
String processDefinitionId = "FormLeaveProcess:2:48920686-8145-11ee-b7ee-0a0a3d6982e3";
runtimeService.startProcessInstanceWithForm(processDefinitionId, "表单请假流程outcome", null, "huihui的请假流程");
}
完成表单任务
@Test
void completeFormTask() {
Map<String, Object> variables = new HashMap<>();
variables.put("startTime", "20221111");
variables.put("endTime", "20231110");
variables.put("reason", "活着不是为了工作,工作是为了活得更有意义");
String taskId = "0f273f73-8149-11ee-b15c-0a0a3d6982e3";
String formDefinitionId = "652cb868-8145-11ee-a2f0-0a0a3d6982e3";
taskService.completeTaskWithForm(taskId, formDefinitionId, "huihui", variables);
}
获取任务对应的表单数据
@Test
void getTaskFormData() {
FormInfo taskFormModel = taskService.getTaskFormModel("0f273f73-8149-11ee-b15c-0a0a3d6982e3");
System.out.println(taskFormModel.getId() + "-" + taskFormModel.getName() + "-" + taskFormModel.getKey());
SimpleFormModel simpleFormModel = (SimpleFormModel)taskFormModel.getFormModel();
List<FormField> fields = simpleFormModel.getFields();
for (FormField field : fields) {
System.out.println(field.getId() + ":" + field.getType() + ":" + field.getName() + ":" + field.getValue());
}
}