前提
完成了基本的要求,点击启动流程,填写表单信息提交,下一个办理人员审核时能够查询到上一个节点的数据(前提是表单的组件id是一样的)。
注意:需要清理掉之前做的动态表单属性,否则提交表单会提示保存失败,因为一些字段必填。
问题
在设计的时候,发现里面有一个自定义表单属性(国际化对应的中文描述)
疑惑
因为在某些情况下,可能是前后端分离,工作流只是提供接口。那么采用动态表单属性界面设计校验,排版都不符合。所以此时需要自定义表单,在流程启动的时候去关联设计好的表单。在这里activiti提供了接口能够去查询自定义表单的key。所以通过这些接口可以实现这个需求。
操作
api使用
// 根据流程定义id获取启动节点的formKey,也就是获取自定义表单值
formService.getStartFormKey(processDefinitionId);
// 根据任务id获取任务id的formKey,也就是获取任务节点的自定义表单值
formService.getTaskFormData(taskId).getFormKey();
service层
接口
/**
* 动态表单服务层
*/
public interface IXKFlowFormService {
// 上面保持不变 ......
/**
* 获取formKey,启动节点
*
* @param processDefinitionId 流程定义id
* @return
*/
String getStartFormKey(String processDefinitionId);
/**
* 获取任务的formKey
*
* @param taskId 任务id
* @return
*/
String getTaskFormKey(String taskId);
}
实现
@Service
public class XKFlowFormServiceImpl implements IXKFlowFormService {
//... 其余保持不变
@Transactional(readOnly = true)
@Override
public String getStartFormKey(String processDefinitionId) {
return formService.getStartFormKey(processDefinitionId);
}
@Transactional(readOnly = true)
@Override
public String getTaskFormKey(String taskId) {
TaskFormData formData = formService.getTaskFormData(taskId);
if (formData == null) {
return null;
}
return formData.getFormKey();
}
}
controller层
//... 其余保持不变
public class XKActivitiFormController {
/**
* 根据流程定义id,获取绑定的表单id
*/
@GetMapping("/getStartFormKey/{processDefinitionId}")
public APIResponse<String> getStartFormKey(@PathVariable String processDefinitionId) {
// 根据流程定义id获取自定义表单key
return new APIResponse<>(formService.getStartFormKey(processDefinitionId));
}
/**
* 根据任务id,获取绑定的表单id
*/
@GetMapping("/getTaskFormKey/{taskId}")
public APIResponse<String> getTaskFormKey(@PathVariable String taskId) {
// 根据任务id获取自定义表单key
return new APIResponse<>(formService.getTaskFormKey(taskId));
}
}
页面设计
准备了两个页面(注意这里使用的thymeleaf模版),页面地址分别是:
activiti/jbpm/leavebillForm(请假表单)
activiti/jbpm/leavebillCheckForm(审核表单)
更改流程
在流程中加入该页面的配置
启动节点
审核节点
注意点
-
在点击启动流程的时候,应该去获取该流程开始节点绑定的formKey,然后跳转到formKey指定的页面即可。
-
在点击办理任务的时候,调用获取该任务节点绑定的formKey的接口,然后跳转到返回的formKey的页面即可。
这一部分的代码仅供参考。
点击启动流程按钮的前端代码
// 根据formKey启动流程
function startProcessDefinitionByFormKey() {
// 获取grid表格id
var rows = grid.getSelecteds();
if (rows.length <= 0) {
mini.alert("请选择一条记录!");
return;
}
$.ajax({
url: "/api/base/activiti/form/getStartFormKey/"+rows[0].id,
type: "get",
contentType: "application/json",
success: function (text) {
if (null == text) {
mini.alert("提交失败,操作超时,请重试!");
} else {
var data = mini.decode(text);
console.log(data);
if (data.msgCode != 0) {
mini.alert("查询失败<br/><b>错误码为:[" + data.msgCode + "],错误信息为:" + data.msg + "</b>");
} else {
// 根据返回的formKey,跳转页面.注意将流程定义id传递
openAddTab('processTabs', rows[0].name, 'startProcess', data.msg+"&id=" + rows[0].id, 'processDefGrid');
}
}
},
error: function (jqXHR, textStatus, errorThrown) {
var data = mini.decode(jqXHR.responseText);
mini.alert("查询失败<br/><b>错误码为:[" + data.code + "],错误信息为:" + data.message + "</b>");
}
});
}
效果
点击办理任务按钮的前端代码
function doTaskByFormKey() {
// 获取grid表格id
var rows = grid.getSelecteds();
if (rows.length <= 0) {
mini.alert("请选择一条记录!");
return;
}
$.ajax({
url: "/api/base/activiti/form/getTaskFormKey/"+rows[0].id,
type: "get",
contentType: "application/json",
success: function (text) {
if (null == text) {
mini.alert("提交失败,操作超时,请重试!");
} else {
var data = mini.decode(text);
if (data.msgCode != 0) {
mini.alert("查询失败<br/><b>错误码为:[" + data.msgCode + "],错误信息为:" + data.msg + "</b>");
} else {
// 根据返回的formKey,跳转页面并将taskId带到办理页面
openAddTab('taskTabs', rows[0].name, 'addTaskTabs', data.msg+"&id=" + rows[0].id, 'taskGrid');
}
}
},
error: function (jqXHR, textStatus, errorThrown) {
var data = mini.decode(jqXHR.responseText);
mini.alert("查询失败<br/><b>错误码为:[" + data.code + "],错误信息为:" + data.message + "</b>");
}
});
}
效果
总结
自定义表单的使用很简单。但是如果使用了自定义表单,那么在表单中填写的数据该如何流转?在审核节点中可以看到无数据回显。这个问题如何解决? 似乎可以通过businesKey来解决,将业务数据存储在业务库中,与流程脱离,工作流只负责流程流转,相关数据仍保留在业务数据库中。