一、功能说明

表单属性设置

生成数据表:当选择生成数据表时,数据表字段和表单名称随机生成(也可以修改)。
绑定数据表:当选择绑定数据表时,需要选择关联的数据表,选择的数据表必须包含如下字段-绑定数据表必须含有字段:类型(type)、模块id(menu_id)、主表id(main_id)、状态(status)、创建人(create_user)、创建组织(create_organize)、创建时间(update_time)、修改人(update_user)、修改时间(update_time)
image.png
image.png

控件属性设置

生成数据表-数据字段:当选择生成数据表,在控件属性中的数据字段也随机生成-可以修改。
绑定数据表-数据字段:当选择数据表后,在控件属性设置中,数据字段需要关联选择。
image.png

注意事项

1、当控件拖拽完成后,如果表单数据发生改变,则需要重新选择控件属性设置中的数据字段(重新指定字段)
2、如果字段未指定,则为空白字段,无法进行存储。

二、拖拽数据表单改造

表单属性改造

image.png

页面属性改造

增加表单类型-新增表单类型字段(table_type),增加绑定数据表属性。

  1. <a-form-item label="表单类型" style="border-bottom: 0px solid #ccc">
  2. <a-select
  3. v-model="config.table_type"
  4. placeholder="请选择表单类型"
  5. @change="selectTypeChange"
  6. >
  7. <a-select-option value="0"> 生成数据表 </a-select-option>
  8. <a-select-option value="1"> 绑定数据表 </a-select-option>
  9. </a-select>
  10. </a-form-item>
  11. <a-form-item
  12. label="数据表名称"
  13. v-if="config.table_type == '0'"
  14. style="border-bottom: 0px solid #ccc"
  15. >
  16. <a-input
  17. placeholder="数据表名称"
  18. @change="changeData"
  19. v-model="config.table_name"
  20. />
  21. </a-form-item>
  22. <a-form-item
  23. label="选择数据表"
  24. v-if="config.table_type == '1'"
  25. style="border-bottom: 0px solid #ccc"
  26. >
  27. <a-select
  28. v-model="config.table_name"
  29. placeholder="请选择数据表"
  30. @change="selectTableChange"
  31. >
  32. <a-select-option
  33. v-for="(item, index) in formData"
  34. :key="index"
  35. :value="item.table_name"
  36. >
  37. {{ item.table_name }}
  38. </a-select-option>
  39. </a-select>
  40. </a-form-item>
  41. <a-form-item label="表单名称">
  42. <a-input
  43. placeholder="表单名称"
  44. @change="changeData"
  45. v-model="config.table_comment"
  46. />
  47. </a-form-item>

执行方法改造

当选择数据表类型或者绑定数据表,存储相关字段到store中,用于在控件属性设置获取对应规则及内容。

  1. selectTypeChange(value) {
  2. let tableList = this.formData.filter(item => item.table_name==this.config.table_name);
  3. if(tableList.length==0){
  4. if(value=='0'){
  5. this.config.table_name = this.table_name;
  6. }else{
  7. this.config.table_name="";
  8. }
  9. }
  10. store.commit("SET_TABLE_TYPE", value);
  11. // console.log(store.getters.tableType);
  12. },
  13. selectTableChange(value) {
  14. store.commit("SET_TABLE_NAME", value);
  15. // console.log(store.getters.tableName);
  16. },

查询数据表

  1. //查询表单列表
  2. getTableList({}).then((response) => {
  3. this.formData = response.data.data;
  4. });

辅助功能store

image.png

控件属性改造

页面属性改造

页面属性改造-新增绑定数据字段。

  1. <a-form-item
  2. v-if="!hideModel && typeof selectItem.model !== 'undefined'"
  3. :label="modelTitle"
  4. >
  5. <a-input
  6. v-model="selectItem.model"
  7. placeholder="请输入"
  8. v-if="tableType == '0'"
  9. />
  10. <a-select
  11. v-if="tableType == '1' && selectItem.type != 'batch'"
  12. v-model="selectItem.model"
  13. placeholder="请选择数据字段"
  14. @change="selectFieldChange"
  15. >
  16. <a-select-option
  17. v-for="(item, index) in fileData"
  18. :key="index"
  19. :value="item.column_name"
  20. :text="item.column_comment"
  21. >
  22. {{ item.column_name }}
  23. </a-select-option>
  24. </a-select>
  25. <a-select
  26. v-if="tableType == '1' && selectItem.type == 'batch'"
  27. v-model="selectItem.model"
  28. placeholder="请选择数据表"
  29. @change="selectTableChange"
  30. >
  31. <a-select-option
  32. v-for="(item, index) in formData"
  33. :key="index"
  34. :value="item.table_name"
  35. >
  36. {{ item.table_name }}
  37. </a-select-option>
  38. </a-select>
  39. </a-form-item>

新增异步计算属性

新增异步计算属性asyncComputed,根据table类型,查询对应的数据表字段。

  1. asyncComputed: {
  2. fieldData() {
  3. if (this.tableType == "1") {
  4. this.findFieldData(store.getters.tableName);
  5. }
  6. },
  7. },

因为计算属性,需要引用才起作用,增加隐藏模块,进行数据的查询及调用,代码如下:

  1. <div v-if="1 == 2">{{ fieldData }}</div>

执行方法改造

  1. mounted() {
  2. //查询表单列表
  3. getTableList({}).then((response) => {
  4. this.formData = response.data.data;
  5. });
  6. },
  1. methods: {
  2. selectChange(record) {
  3. console.log(this.selectItem);
  4. if (this.tableType == "1" && this.selectItem.type != "batch") {
  5. //处理batch下的数据
  6. if (this.selectItem.table_id != undefined) {
  7. let tableName = this.selectItem.table_id;
  8. this.findFieldData(tableName);
  9. } else {
  10. let tableName = store.getters.tableName;
  11. this.findFieldData(tableName);
  12. }
  13. }
  14. if (this.tableType == "1" && this.selectItem.type == "batch") {
  15. this.modelTitle = "选择数据子表";
  16. let tableList = this.formData.filter(
  17. (item) => item.table_name == this.selectItem.model
  18. );
  19. if (tableList.length == 0) {
  20. this.selectItem.model = "";
  21. }
  22. } else if (this.tableType == "0" && this.selectItem.type == "batch") {
  23. this.modelTitle = "请输入数据子表";
  24. } else {
  25. this.modelTitle = "数据字段";
  26. }
  27. },
  28. selectTableChange(value) {
  29. //console.log(value);
  30. //this.selectItem.model = value;
  31. },
  32. selectFieldChange(value, option) {
  33. let label = option.data.attrs.text;
  34. if (label != undefined) {
  35. this.selectItem.label = label;
  36. }
  37. },
  38. findFieldData(table_name) {
  39. getColumndList({ table_name: table_name }).then((response) => {
  40. this.fileData = response.data.data;
  41. if (this.tableType == "1") {
  42. let resData = this.fileData.filter((item) => {
  43. return item.column_name == this.selectItem.model;
  44. });
  45. if (resData.length == 0) {
  46. this.selectItem.model = "";
  47. }
  48. }
  49. });
  50. },
  51. findDictionary() {
  52. console.log(this.selectItem.options);
  53. findDictionaryList({
  54. parent_code: this.selectItem.options.dynamicKey,
  55. }).then((response) => {
  56. let options = response.data.data;
  57. options.forEach((op) => {
  58. op.label = op.name;
  59. op.value = op.id;
  60. });
  61. console.log(options);
  62. this.selectItem.options.options = options;
  63. });
  64. },
  65. },
  66. };

三、springboot后台方法改造

image.png
实现逻辑说明:
原来的保存及更新方法的核心是分析拖拽表单的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);
    }