一、功能说明
表单属性设置
生成数据表:当选择生成数据表时,数据表字段和表单名称随机生成(也可以修改)。
绑定数据表:当选择绑定数据表时,需要选择关联的数据表,选择的数据表必须包含如下字段-绑定数据表必须含有字段:类型(type)、模块id(menu_id)、主表id(main_id)、状态(status)、创建人(create_user)、创建组织(create_organize)、创建时间(update_time)、修改人(update_user)、修改时间(update_time)
控件属性设置
生成数据表-数据字段:当选择生成数据表,在控件属性中的数据字段也随机生成-可以修改。
绑定数据表-数据字段:当选择数据表后,在控件属性设置中,数据字段需要关联选择。
注意事项
1、当控件拖拽完成后,如果表单数据发生改变,则需要重新选择控件属性设置中的数据字段(重新指定字段)
2、如果字段未指定,则为空白字段,无法进行存储。
二、拖拽数据表单改造
表单属性改造
页面属性改造
增加表单类型-新增表单类型字段(table_type),增加绑定数据表属性。
<a-form-item label="表单类型" style="border-bottom: 0px solid #ccc"><a-selectv-model="config.table_type"placeholder="请选择表单类型"@change="selectTypeChange"><a-select-option value="0"> 生成数据表 </a-select-option><a-select-option value="1"> 绑定数据表 </a-select-option></a-select></a-form-item><a-form-itemlabel="数据表名称"v-if="config.table_type == '0'"style="border-bottom: 0px solid #ccc"><a-inputplaceholder="数据表名称"@change="changeData"v-model="config.table_name"/></a-form-item><a-form-itemlabel="选择数据表"v-if="config.table_type == '1'"style="border-bottom: 0px solid #ccc"><a-selectv-model="config.table_name"placeholder="请选择数据表"@change="selectTableChange"><a-select-optionv-for="(item, index) in formData":key="index":value="item.table_name">{{ item.table_name }}</a-select-option></a-select></a-form-item><a-form-item label="表单名称"><a-inputplaceholder="表单名称"@change="changeData"v-model="config.table_comment"/></a-form-item>
执行方法改造
当选择数据表类型或者绑定数据表,存储相关字段到store中,用于在控件属性设置获取对应规则及内容。
selectTypeChange(value) {let tableList = this.formData.filter(item => item.table_name==this.config.table_name);if(tableList.length==0){if(value=='0'){this.config.table_name = this.table_name;}else{this.config.table_name="";}}store.commit("SET_TABLE_TYPE", value);// console.log(store.getters.tableType);},selectTableChange(value) {store.commit("SET_TABLE_NAME", value);// console.log(store.getters.tableName);},
查询数据表
//查询表单列表getTableList({}).then((response) => {this.formData = response.data.data;});
辅助功能store
控件属性改造
页面属性改造
页面属性改造-新增绑定数据字段。
<a-form-itemv-if="!hideModel && typeof selectItem.model !== 'undefined'":label="modelTitle"><a-inputv-model="selectItem.model"placeholder="请输入"v-if="tableType == '0'"/><a-selectv-if="tableType == '1' && selectItem.type != 'batch'"v-model="selectItem.model"placeholder="请选择数据字段"@change="selectFieldChange"><a-select-optionv-for="(item, index) in fileData":key="index":value="item.column_name":text="item.column_comment">{{ item.column_name }}</a-select-option></a-select><a-selectv-if="tableType == '1' && selectItem.type == 'batch'"v-model="selectItem.model"placeholder="请选择数据表"@change="selectTableChange"><a-select-optionv-for="(item, index) in formData":key="index":value="item.table_name">{{ item.table_name }}</a-select-option></a-select></a-form-item>
新增异步计算属性
新增异步计算属性asyncComputed,根据table类型,查询对应的数据表字段。
asyncComputed: {fieldData() {if (this.tableType == "1") {this.findFieldData(store.getters.tableName);}},},
因为计算属性,需要引用才起作用,增加隐藏模块,进行数据的查询及调用,代码如下:
<div v-if="1 == 2">{{ fieldData }}</div>
执行方法改造
mounted() {//查询表单列表getTableList({}).then((response) => {this.formData = response.data.data;});},
methods: {selectChange(record) {console.log(this.selectItem);if (this.tableType == "1" && this.selectItem.type != "batch") {//处理batch下的数据if (this.selectItem.table_id != undefined) {let tableName = this.selectItem.table_id;this.findFieldData(tableName);} else {let tableName = store.getters.tableName;this.findFieldData(tableName);}}if (this.tableType == "1" && this.selectItem.type == "batch") {this.modelTitle = "选择数据子表";let tableList = this.formData.filter((item) => item.table_name == this.selectItem.model);if (tableList.length == 0) {this.selectItem.model = "";}} else if (this.tableType == "0" && this.selectItem.type == "batch") {this.modelTitle = "请输入数据子表";} else {this.modelTitle = "数据字段";}},selectTableChange(value) {//console.log(value);//this.selectItem.model = value;},selectFieldChange(value, option) {let label = option.data.attrs.text;if (label != undefined) {this.selectItem.label = label;}},findFieldData(table_name) {getColumndList({ table_name: table_name }).then((response) => {this.fileData = response.data.data;if (this.tableType == "1") {let resData = this.fileData.filter((item) => {return item.column_name == this.selectItem.model;});if (resData.length == 0) {this.selectItem.model = "";}}});},findDictionary() {console.log(this.selectItem.options);findDictionaryList({parent_code: this.selectItem.options.dynamicKey,}).then((response) => {let options = response.data.data;options.forEach((op) => {op.label = op.name;op.value = op.id;});console.log(options);this.selectItem.options.options = options;});},},};
三、springboot后台方法改造

实现逻辑说明:
原来的保存及更新方法的核心是分析拖拽表单的json结构,进行数据字段的提取,创建数据表和数据字段;本次改造则采用的是绑定是数据表,无需进行数据表和数据字段的创建,则此处主要根据表类型(table_type)判断是生成数据表还是绑定数据表,如果是绑定数据表,则无需创建。
1、修改Controller保存和修改方法逻辑
判断table_type如果=0,则执行生成数据表的创建逻辑-此处不做讲解,可-自定义表单模块说明
判断table_type如果=1,则执行生成数据表的创建逻辑,继续判断record是否为空,为空则新增,否则为修改。
/**
* @title save
* @description 保存方法
* @author qingfeng
* @updateTime 2021/4/3 0003 20:31
*/
@PostMapping
@PreAuthorize("hasAnyAuthority('vform:add')")
public void save(@Valid @RequestBody PageData pd,HttpServletResponse response) throws Exception {
Json json = new Json();
try {
System.out.println(pd);
Map maps = (Map) JSON.parse(pd.get("config").toString());
if(maps.get("table_type").toString().equals("0")){
//根据record判断是否为空,为空则添加,不为空则更新
if(Verify.verifyIsNotNull(pd.get("record"))){
//查询数据表是否已经存在,如果存在则提示
Map record = (Map) JSON.parse(pd.get("record").toString());
if(record.get("table_name").equals(maps.get("table_name"))){
this.vformService.updateVform(pd);
json.setSuccess(true);
json.setMsg("数据更新成功");
}else{
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("table_name",maps.get("table_name"));
int num = vformService.list(queryWrapper).size();
if(num==0){
pd.put("table_schema",table_schema);
pd.put("table_name",maps.get("table_name"));
int n = vformService.findTableList(pd).size();
if(n==0){
//添加-创建信息
this.vformService.updateVform(pd);
json.setSuccess(true);
json.setMsg("数据更新成功");
}else{
json.setSuccess(false);
json.setMsg("数据表已创建,不可重复创建。");
}
}else{
json.setSuccess(false);
json.setMsg("数据表信息已存在,不可重复创建。");
}
}
}else{
//判断数据表是否存在,存在则提示
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("table_name",maps.get("table_name"));
int num = vformService.list(queryWrapper).size();
if(num==0){
pd.put("table_schema",table_schema);
pd.put("table_name",maps.get("table_name"));
int n = vformService.findTableList(pd).size();
if(n==0){
//添加-创建信息
this.vformService.saveVform(pd);
json.setSuccess(true);
json.setMsg("新增信息成功");
}else{
json.setSuccess(false);
json.setMsg("数据表已创建,不可重复创建。");
}
}else{
json.setSuccess(false);
json.setMsg("数据表信息已存在,不可重复创建。");
}
}
}else if(maps.get("table_type").toString().equals("1")){
if(Verify.verifyIsNotNull(pd.get("record"))){
this.vformService.updateform(pd);
json.setSuccess(true);
json.setMsg("数据更新成功");
}else{
//添加-创建信息
this.vformService.saveform(pd);
json.setSuccess(true);
json.setMsg("新增信息成功");
}
}
} catch (Exception e) {
e.printStackTrace();
String message = "新增信息失败";
json.setSuccess(false);
json.setMsg(message);
throw new MyException(message);
}
this.writeJson(response,json);
}
重点方法如下:
if(Verify.verifyIsNotNull(pd.get("record"))){
this.vformService.updateform(pd);
json.setSuccess(true);
json.setMsg("数据更新成功");
}else{
//添加-创建信息
this.vformService.saveform(pd);
json.setSuccess(true);
json.setMsg("新增信息成功");
}
2、修改ServiceImpl-saveform方法逻辑
代码逻辑和saveVform基本一致,去掉了创建数据表和数据字段的部分。
/**
* @title saveMycontent
* @description 保存数据
* @author qingfeng
* @updateTime 2021/4/3 0003 20:58
*/
@Transactional
public void saveform(PageData pd) throws Exception{
//更新操作:如果表名称发生改变,则修改表名称;如果字段发生变更,则变更数据表结构。
Map maps = (Map) JSON.parse(pd.get("config").toString());
Vform vform = new Vform();
String id = GuidUtil.getUuid();
vform.setId(id);
String time = DateTimeUtil.getDateTimeStr();
vform.setCreate_time(time);
String type = "0";
//处理数据权限
String authParams = SecurityContextHolder.getContext().getAuthentication().getName();
vform.setCreate_user(authParams.split(":")[1]);
vform.setCreate_organize(authParams.split(":")[2]);
vform.setType(type);
vform.setTable_type("1");
vform.setTable_name(maps.get("table_name").toString());
vform.setTable_comment(maps.get("table_comment").toString());
vform.setTable_content(pd.get("table_content").toString());
this.save(vform);
//数据表字段
List<Vfield> vfields = new ArrayList<Vfield>();
List<PageData> list = JSON.parseArray(pd.get("list").toString(),PageData.class);
//获取需要创建的主表字段
vfields = createField(id,list,vfields,"save",new ArrayList<Vform>(),maps);
vfieldService.saveBatch(vfields);
}
其他逻辑如:创建字段-createField,创建关联表-createLinkTable,更新关联表-updateLinkTable 等,大家可以搜索:table_type,到具体的位置分析下代码即可,核心就是判断是否需要创建数据表,此处不做过多的介绍。
3、修改ServiceImpl-updateform方法
@Transactional
public void updateform(PageData pd){
Vform vform = new Vform();
Map record = (Map) JSON.parse(pd.get("record").toString());
// 更新信息
String type = "0";
String id = record.get("id").toString();
vform.setId(id);
//查询原数据
Vform myForm = this.getById(id);
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("table_id",id);
List<Vfield> fieldList = this.vfieldService.list(wrapper);
myForm.setVfields(fieldList);
//查询关联表
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("main_id",id);
List<Vform> myFormList = this.list(queryWrapper);
for (Vform form:myFormList) {
QueryWrapper wp = new QueryWrapper();
wp.eq("table_id",form.getId());
List<Vfield> fieldLs = this.vfieldService.list(wp);
form.setVfields(fieldLs);
}
//更新操作:如果表名称发生改变,则修改表名称;如果字段发生变更,则变更数据表结构。
Map maps = (Map) JSON.parse(pd.get("config").toString());
String time = DateTimeUtil.getDateTimeStr();
vform.setUpdate_time(time);
//处理数据权限
String authParams = SecurityContextHolder.getContext().getAuthentication().getName();
vform.setUpdate_user(authParams.split(":")[1]);
vform.setTable_name(maps.get("table_name").toString());
vform.setTable_comment(maps.get("table_comment").toString());
vform.setTable_content(pd.get("table_content").toString());
vform.setType("0");
vform.setTable_type("1");
this.updateById(vform);
//数据表字段
QueryWrapper removeWrapper = new QueryWrapper();
removeWrapper.eq("table_id",id);
this.vfieldService.remove(removeWrapper);
//组织新-子表表明
StringBuilder newTablesSB = new StringBuilder();
List<Vfield> vfields = new ArrayList<Vfield>();
List<PageData> list = JSON.parseArray(pd.get("list").toString(),PageData.class);
//获取需要创建的主表字段
vfields = createField(id,list,vfields,"update",myFormList,maps);
newTablesSB = getLinkTableNames(id,list,newTablesSB);
vfieldService.saveBatch(vfields);
}
