Skip to content

技术选型

SpringBoot2.2.6+MySQL5.6+Vue2.0+ElementUI

数据库设计

考虑到不同的数据字典数据结构区别很小,除了在前台页面展示的列名和列的数量不一样以外,基本上都可以沿用同一种数据表结构,所以考虑使用两张表T_DICTIONARY和T_DICTIONARY_DETAIL,前者用来维护所有的数据字典表的表信息,包括表名、列名、标识、是否在用等,后者用来保存具体的某一个数据字典的数据,这里通过t_did关联前者的主键,用于区分该表的数据具体属于哪一张。后者的通用字段有五个,分别是col1到col5,根据需要从前到后存储数据字段的数据,而列名的显示通过T_DICTIONARY的字段t_col_name来保存,需要用户在录入数据的时候输入列名称,数据库存储的时候.用逗号隔开。

系统设计

系统采用前后端分离的模式,后台统一返回封装数据,前台对数据进行渲染,前台通过路由来进行数据表格页面的切换。

代码实现

后台

核心接口包括主表t_dictionary:

    @PostMapping("/list")
    public List<Dictionary> dictionaryListAll(){
        QueryWrapper<Dictionary> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("t_order");
        return dictionaryService.list(queryWrapper);
    }
    @GetMapping("/{id}")
    public Dictionary dictionaryOne(@PathVariable Long id){
        return dictionaryService.getById(id);
    }
    @PostMapping("/add")
    public boolean dictionaryAdd(@RequestBody Dictionary dictionary){
        return dictionaryService.save(dictionary);
    }
    @PostMapping("/delete/{id}")
    public boolean dictionaryDelete(@PathVariable Long id){
        return dictionaryService.removeById(id);
    }
    @PostMapping("/update")
    public boolean dictionaryUpdate(@RequestBody Dictionary dictionary){
        return dictionaryService.updateById(dictionary);
    }

以及其详情表的接口

@GetMapping("/query/{did}")
    public List<DictionaryDetail> dictionaryDetailList(@PathVariable Long did){
        QueryWrapper<DictionaryDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("t_did",did);
        return iDictionaryDetailService.list(queryWrapper);
    }
    @GetMapping("/{id}")
    public DictionaryDetail dictionaryDetailOne(@PathVariable Long id){
        return iDictionaryDetailService.getById(id);
    }

    @PostMapping("/update")
    public boolean dictionaryDetailUpdate(@RequestBody DictionaryDetail dictionaryDetail){
        return iDictionaryDetailService.updateById(dictionaryDetail);
    }
    @PostMapping("/add")
    public boolean dictionaryDetailAdd(@RequestBody DictionaryDetail dictionaryDetail){
        return iDictionaryDetailService.save(dictionaryDetail);
    }

    @PostMapping("/delete/{id}")
    public boolean dictionaryDetailDelete(@PathVariable Long id){
        return iDictionaryDetailService.removeById(id);
    }

后台代码较少,主要提供两表的CRUD功能即可.

前台

前台主要包括两部分:左侧列表和右侧表格内容.左侧列表第一个菜单默认为对主表的管理[综合管理],点击后右侧显示主表的表格数据,添加数据后左侧列表中多出一个菜单,点击后即可对该[新增的数据字典表]进行数据维护.

Dictionary.vue 路由配置:

 routes: [
    {
      path: '/',
      name: '',
      component: Dictionary,
      redirect: "/all",
      children: [
        {path: '/all', component: All, name: "All",hidden: false},
        {path: '/detail/:id', component: Detail, name: "Detail",hidden: true},

      ]
    },
// all是主表对应的页面,detail则是各个字典表的页面,需要循环输出
  ]
              <el-menu-item-group>
                <template slot="title"></template>
                <el-menu-item index="/all">
                  <span>综合管理</span>
                </el-menu-item>
                <el-menu-item v-for="(item,index) in navList" :index="'/detail/'+item.id" :key="index">
                  <span>{{item.dictionaryName}}</span>
                </el-menu-item>
              </el-menu-item-group>

All.vue 除了对t_dictionary的增上改查以外,在添加操作之后要对其父路由:Dictionary进行数据重新加载的操作. 在添加的回调里面,完成对Dictionary.vue的refresh方法调用

                this.$emit('refresh', "");

另外由于设计的字段是通用字段,所以在添加数据的时候需要同时添加字典表的字段名称,用于前台显示.

          dictionaryColName:[{ required: true, message: '请输入列名称(逗号隔开,最多支持五列)', trigger: 'blur' }],

Detail.vue 需要动态加载列和列名称

 <el-table-column
        v-for="(item,index) in col"
        :key="index"
        fixed
        :prop="item.prop"
        :label="item.name"
        width="150">
      </el-table-column>
data(){
      return {
        id : '',
        col : [],
        tableData: [],
        dialogTableVisible: false,
        dialogFormVisible: false,
        formData:['','','','','','','','',''],
      }
    }
initTable:function(id){
        this.axios({
          method: 'get',
          data: "",
          url: 'api/dic/'+id,
        }).then(result => {
          var col_names = result.data.data.dictionaryColName.split(',');
          var cols = [];
          for(var i = 0;i<col_names.length;i++){
            var obj = {};
            obj.name = col_names[i];
            obj.prop = 'col'+(i+1);
            cols.push(obj);
          }
          this.col = cols;
          this.initTableData(id);
        }).catch(error => {
          this.$message.error("网络异常");
        })
      },
      initTableData:function(id){
        this.axios({
          method: 'get',
          data: "",
          url: 'api/dic/detail/query/'+id,
        }).then(result => {
          this.tableData = result.data.data;
        }).catch(error => {
          this.$message.error("网络异常");
        })
      },

同样的在添加页面修改页面都需要动态显示列和列名称.