问题分析
表单管理做为要求性功能存在,所以通用表单管理需要考虑以下几个方面的内容:
- 监管问题:如何让用户知道自己某个时间点该填哪些表格,还有哪些表格没有填。
- 给用户生成未填写的历史上报表单,这就要求数据库中必须要有一个参考的列表点,与用户已经填写的进行对照,然后生成未填写的状态列表。
- 表单中的字段和类型是相似的,前端没必要字字去实现,可以考虑实现一个表单配置的模式。主要做如下抽象:数据类型的抽象:普通字符串类型,单选类型,多选类型、数字类型还是布尔类型等;是否必填;字段名称;等等。在之前写的amd项目的时候,也做过相关的配置,只不过那时候是将每个字段单独成为一个行,然后让PHP代码再去组装,目前这个似乎没必要那么做。直接使用auto的方式去生成即可。
- 不同类型的表单,如果都单独建立列表页,详情页,就非常多,所以还需要考虑将所有表单的填写列表放到一个列表页里面去控制,通过不同的类型来区别。
- 不同的表单,可以看做叶子节点,这个叶子节点可以是一张表,也可以是多张表,不能限制叶子表单的详情只能是一张表,这就意味着无法用一个相似的表或者一段相似的代码来描述所有的表单填写,只能具体业务具体建表并写相应的代码。
解决方案
建表方案
根据上面的问题分析,需要建立
- 表单周期等基础配置表
- 表单填写内容配置表
- 历史填报表
- 每种不同的表单单独的表
建表SQL如下:
- 上报填报配置表
--上报填报配置
CREATE TABLE IF NOT EXISTS report_config
(
id bigint PRIMARY KEY DEFAULT random_id(), --记录标识
report_name varchar(64) NOT NULL DEFAULT '--', --上报名称
report_type varchar(64) NOT NULL DEFAULT '--', --上报类型
rank integer NOT NULL DEFAULT '0', --展示位置
measure varchar(64) NOT NULL DEFAULT '--', --填报方式
report_desc varchar(500) NOT NULL DEFAULT '--', --填报描述
period integer NOT NULL DEFAULT '86400', --报表周期
--通用管理信息
... ...
);
该表作为填报提示存在,程序需要根据周期与用户上次填报的时间做对比,如果超期则做出提示。本质上就是作为管控而存在的数据表。
- 上报表单内容配置表
--上报表单配置
CREATE TABLE IF NOT EXISTS report_form_config
(
id bigint PRIMARY KEY DEFAULT random_id(), --记录标识
report_id bigint NOT NULL DEFAULT '0', --上报id
form_name varchar(64) NOT NULL DEFAULT '--', --表单名称
form_config text NOT NULL DEFAULT '{}', --表单配置
--通用管理信息
... ...
);
这是表单的内容配置表,需要在form_config中配置相关的内容,目前可以确定的配置如下:
- 字段类型:数字,长字符串,短字符串,文本框,多选,单选,布尔类型
- 字段变量名:该名称用于传输到服务层
- 字段默认值:0,“”,多选和单选选中什么,布尔类型默认值
- 字段备选值:只有多选和单选存在
- 是否必填
- 字段描述:该字段的Label部分内容
如果表单复杂也可以不走该过程。因为这要求前端能适配出所有复杂情况,对前端来说难度也有点大。
- 填报历史表
--填报历史表
CREATE TABLE IF NOT EXISTS report_history
(
id bigint PRIMARY KEY DEFAULT random_id(), --记录标识
report_id bigint NOT NULL DEFAULT '0', --填报配置id
--数据权限管理信息
... ...
--通用管理信息
... ...
);
由于填报历史表与业务有关了,所以该表需要建立数据权限管理信息,即该条数据或属于哪个组织或属于哪个人。
然后,再根据每个业务表单建立自己的数据表即可。
所需代码
在我们的分析中,需要写一部分代码,让我们这个思路可以正常的流转起来。
首先,我们需要实现对配置的自动生成,这就要求我们首先定义好配置的结构。
public class FormField {
private String fieldType;
private String fieldName;
private String fieldDescription;
private String defaultValue;
private List<String> optionValues;
private Boolean required;
... ...
}
然后,实现生成对应的配置
/**
* 生成配置
*/
public class GenerateFormConfig {
/**
* 生成表单配置
* 对于单个字段 ['字段名','字段类型','字段描述','字段默认值','备选字段','是否必填']
*
* @param configs
* @return
*/
public static String getFormConfig(String[][] configs) {
Map<String, Object> ans = new HashMap<>();
List<FormField> data = new ArrayList<>();
for (String[] config : configs) {
FormField formField = new FormField();
formField.setFieldName(config[0]);
formField.setFieldType(config[1]);
formField.setFieldDescription(config[2]);
formField.setDefaultValue(config[3]);
formField.setOptionValues(ArrayStrUtil.str2Array(config[4]));
formField.setRequired(Boolean.parseBoolean(config[5]));
data.add(formField);
}
ans.put("data", data);
return Json.toJson(ans);
}
}
调用方法
@Test
public void demo7(){
String[][] configs = {{"demo1","demo1","demo1","demo1","demo1","true"},{"demo2","demo2","demo2","demo2","demo2","true"}};
String ans = GenerateFormConfig.getFormConfig(configs);
System.out.println(ans);
}
生成的结果
{
"data": [
{
"field_type": "demo1",
"field_name": "demo1",
"field_description": "demo1",
"default_value": "demo1",
"option_values": [
"demo1"
],
"required": true
},
{
"field_type": "demo2",
"field_name": "demo2",
"field_description": "demo2",
"default_value": "demo2",
"option_values": [
"demo2"
],
"required": true
}
]
}