上一篇我们了解了表单以及表单的数据存储。意义上表单就是一个页面,用户自定义的一个表单,其中重要的就是元素key,用户输入的值就是value,在流程启动的时候会存储至act_ru_variable表中。不仅仅是表单的值会存储,流程中设计的条件表达式也会存储至其中等等。
以下就是一个表单
用户根据可自定义填写数据发起流程。
流程启动后我们可以查看到历史表单的数据。
1.数据回显
图中标红部分是我用流程监听器(监听器在之前的文章中写到过)做的一些业务数据。
通过接口我们可以看到表单的数据是存储在widgetFormList集合中的
图中箭头所指的就是表单的值,该值可以在表单元素中设置,如果用户没有填写值,则取表单的默认值。此处用户填写了所以就是用户的数据。
之所以用户填写后就会取用户值,是因为我之前多次提到过表单就是一个Map集合,map的特性就是无序、不可重复、没有下标。由于不可重复,所以用户填写后去查询数据库,有值就直接覆盖其value。
2.接口Vo对象
该接口的返回值对象
@Data public class WfDetailVo { /** * 任务表单信息 */ private FormConf taskFormData; /** * 历史流程节点信息 */ private List<WfProcNodeVo> historyProcNodeList; /** * 流程表单列表 */ private List<FormConf> processFormList; private List<ReactFromConf> reactFromConfList; private ReactFromConf taskReactFromConf; /** * 流程XML */ private String bpmnXml; private WfViewerVo flowViewer; /** * 是否存在任务表单信息 * @return true:存在;false:不存在 */ public Boolean isExistTaskForm() { return ObjectUtil.isNotEmpty(this.taskFormData); } }
其中的ReactFromConf就是这个表单对象
@Getter @Setter @AllArgsConstructor @NoArgsConstructor public class ReactFromConf { /** * 标题 */ private String title; /** * 表单值 */ private List<Map<String, Object>> widgetFormList; private Map<String,Object> selectWidgetItem; private Map<Object, Object> globalConfig; private Map<String, Object> formConfig; }
想必你们肯定会疑惑为什么要这样设计表单对象。接下来我们看一看表单生成的json就可以看出来了。
我复制至文本中查看
收缩后发现这就是一个json对象,该json对象就是一个表单的各种属性,其中的widgetFormList就是表单元素值。
图中红色框是表单元素名称,绿色框是元素的默认值。
3.获取历史节点表单信息
// 查询任务节点参数,并转换成Map variables = historyService.createHistoricVariableInstanceQuery() .processInstanceId(historicProcIns.getId()) .taskId(activityInstance.getTaskId()) .list() .stream() .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue));
获取到历史节点信息就是从act_hi_varinst中根据流程业务实例Id(PROC_INST_ID_)获取到该流程存储的所有变量值。
Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue)
此处就是将变量转化为Map<VariableName,VariableValue>。我们看一下表就是看出来了
根据表,我们可以很清晰的看到我们是根据PROC_INST_ID_来获取NAME_和TEXT_的值
接下来就是遍历当前表单元素并且将获取的历史节点的值塞进其中
4.数据回显
【请详细看注释】
/** * 填充表单项内容 * * @param reactFromConf React的表单配置信息 * @param data 表单内容,也就是上文中我们获取的历史流程map集合 * @param flag 该布尔值是为了区分获取的是当前流程表单还是历史流程表单 */ public static void fillFormData(ReactFromConf reactFromConf, Map<String, Object> data,boolean flag) { for (Map<String, Object> field : reactFromConf.getWidgetFormList()) { recursiveFillField(field, data,flag); } }
该方法中的field就是一个个的表单元素,请注意看key
/** * 赋值 * * @param field * @param data */ private static void recursiveFillField(final Map<String, Object> field, final Map<String, Object> data,boolean flag) { if (!field.containsKey(FORM_ITEM_CONFIG)) { return; } Map<String, Object> formItemConfigMap = (Map<String, Object>) field.get(FORM_ITEM_CONFIG); String modelKey = Convert.toStr(field.get(KEY)); Object value = data.get(modelKey); if (value != null) { formItemConfigMap.put("initialValue", value); } if (flag) { Map<String, Object> configMap = (Map<String, Object>) field.get(CONFIG); if (!configMap.isEmpty()) { configMap.put("disabled", true); } } } }
上述代码中,我标记了红色的布尔变量。此处是为了给表单对象中的值赋true,也就是disabled禁用为true,这样表单就不会被修改了,只能给用户展示历史表单信息。
给表单的config元素的disabled设置为true,则当前表单元素禁用,为了给审批人回显历史节点表单所使用
上述就是表单的数据回显,只涉及了【流程历史详情接口】的1/5左右
【相关代码繁多,如有需要可私信我(无偿)】