<template> 
 | 
  <div class="builder-container"> 
 | 
    <vol-box 
 | 
      ref="add" 
 | 
      :width="850" 
 | 
      :height="450" 
 | 
      title="新建配置信息" 
 | 
      padding="10px" 
 | 
      v-model="addModel" 
 | 
    > 
 | 
      <div style="padding: 30px 30px 10px 34px"> 
 | 
        <el-alert type="warning" :closable="false"> 
 | 
          1、如果只是创建目录,父级id填0,其他随便填写; 
 | 
          <br /> 
 | 
          2、如果是生成代码,父级id填写【代码生成配置】列表页面的id 
 | 
        </el-alert> 
 | 
      </div> 
 | 
      <div class="addModel" style="padding-right: 30px"> 
 | 
        <vol-form 
 | 
          ref="addForm" 
 | 
          :formRules="addOptions" 
 | 
          :formFields="layOutOptins.fields" 
 | 
        > 
 | 
        </vol-form> 
 | 
      </div> 
 | 
      <template #footer> 
 | 
        <div> 
 | 
          <el-button type="primary" size="small" @click="add" 
 | 
            ><i class="el-icon-plus"></i> 确 定</el-button 
 | 
          > 
 | 
        </div> 
 | 
      </template> 
 | 
    </vol-box> 
 | 
    <div class="builder-left"> 
 | 
      <div class="module-name">代码生成配置</div> 
 | 
      <div class="builder-tree"> 
 | 
        <el-scrollbar style="height: 100%; width: 200px"> 
 | 
          <!-- :onOpenChange="onOpenChange" --> 
 | 
          <VolMenu :list="tree" :onSelect="onSelect"></VolMenu> 
 | 
        </el-scrollbar> 
 | 
      </div> 
 | 
    </div> 
 | 
    <div class="builder-content"> 
 | 
      <div style="height: 100%"> 
 | 
        <el-scrollbar style="height: 100%"> 
 | 
          <div class="coder-container"> 
 | 
            <div class="coder-item" style="padding-top: 7px"> 
 | 
              <VolHeader icon="ios-chatbubbles" text="代码生成器"> 
 | 
                <template #content> 
 | 
                  <div style="color: red; font-size: 13px"> 
 | 
                    删除左侧配置菜单:删除行->保存->删除菜单 
 | 
                  </div> 
 | 
                </template> 
 | 
                <div class="action"> 
 | 
                  <span @click="save"> <i class="el-icon-check"></i>保存 </span> 
 | 
                  <span @click="addVisible()"> 
 | 
                    <i class="el-icon-plus"></i>新建 
 | 
                  </span> 
 | 
                  <span @click="ceateVuePage(0)"> 
 | 
                    <i class="el-icon-document"></i>生成Vue页面 
 | 
                  </span> 
 | 
                  <!-- <span @click="ceateVuePage(1)"> 
 | 
                    <i class="el-icon-document"></i>生成app页面 
 | 
                  </span> --> 
 | 
                  <span @click="ceateModel"> 
 | 
                    <i class="el-icon-tickets"></i>生成Model 
 | 
                  </span> 
 | 
                  <span @click="createService"> 
 | 
                    <i class="el-icon-document"></i>生成业务类 
 | 
                  </span> 
 | 
                  <span @click="delTree"> 
 | 
                    <i class="el-icon-delete"></i>删除菜单 
 | 
                  </span> 
 | 
                </div> 
 | 
              </VolHeader> 
 | 
              <div class="config"> 
 | 
                <vol-form 
 | 
                  :label-width="90" 
 | 
                  ref="form" 
 | 
                  :formRules="layOutOptins.options" 
 | 
                  :formFields="layOutOptins.fields" 
 | 
                ></vol-form> 
 | 
              </div> 
 | 
            </div> 
 | 
            <el-alert type="warning" :closable="false"> 
 | 
              1、如果需要修改表结构,请在数据库修改,再点同步表结构->生成vue页面->生成model。 
 | 
              2、修改编辑行后需要点击生成model、生成vue页面 
 | 
            </el-alert> 
 | 
            <div class="coder-item"> 
 | 
              <VolHeader 
 | 
                icon="md-podium" 
 | 
                style="border-bottom: 0" 
 | 
                text="表结构" 
 | 
              > 
 | 
                <template #content> 
 | 
                  <div style="color: red; font-size: 13px"> 
 | 
                    数据库表结构发生变化时请点【同步表结构】 
 | 
                  </div></template 
 | 
                > 
 | 
  
 | 
                <div class="action"> 
 | 
                  <span 
 | 
                    style="color: rgb(23, 156, 216)" 
 | 
                    class="ivu-icon ivu-icon-ios-folder" 
 | 
                    @click="help" 
 | 
                    >代码生成器参数文档</span 
 | 
                  > 
 | 
                  <span @click="delRow" class="ivu-icon ivu-icon-md-close" 
 | 
                    >删除行数据</span 
 | 
                  > 
 | 
                  <span @click="syncTable" class="ivu-icon ivu-icon-md-sync" 
 | 
                    >同步表结构</span 
 | 
                  > 
 | 
                </div> 
 | 
              </VolHeader> 
 | 
  
 | 
              <div class="grid-container" style="padding-bottom: 20px"> 
 | 
                <vol-table 
 | 
                  ref="table" 
 | 
                  :paginationHide="true" 
 | 
                  :tableData="data" 
 | 
                  :height="tableHeight" 
 | 
                  :columns="layOutOptins.columns" 
 | 
                  :color="false" 
 | 
                  :index="true" 
 | 
                  :allowEmpty="true" 
 | 
                  :clickEdit="true" 
 | 
                ></vol-table> 
 | 
              </div> 
 | 
            </div> 
 | 
          </div> 
 | 
        </el-scrollbar> 
 | 
      </div> 
 | 
    </div> 
 | 
  </div> 
 | 
</template> 
 | 
<script> 
 | 
import builderData from './builderData'; 
 | 
import VolForm from '@/components/basic/VolForm.vue'; 
 | 
import VolTable from '@/components/basic/VolTable.vue'; 
 | 
import VolBox from '@/components/basic/VolBox.vue'; 
 | 
import VolHeader from '@/components/basic/VolHeader.vue'; 
 | 
import VolMenu from '@/components/basic/VolElementMenu.vue'; 
 | 
export default { 
 | 
  components: { 
 | 
    VolForm: VolForm, 
 | 
    VolTable: VolTable, 
 | 
    VolBox: VolBox, 
 | 
    VolHeader: VolHeader, 
 | 
    VolMenu 
 | 
  }, 
 | 
  data() { 
 | 
    return { 
 | 
      more: { 
 | 
        addChild: 'addChild', 
 | 
        ceateController: 'ceateController', 
 | 
        addRow: 'addRow', 
 | 
        delRow: 'delRow', 
 | 
        delTree: 'delTree' 
 | 
      }, 
 | 
      addModel: false, 
 | 
      helpModel: false, 
 | 
      tableHeight: 500, 
 | 
      addOptions: builderData.form.addOptions, 
 | 
      layOutOptins: { 
 | 
        fields: builderData.form.fields, 
 | 
        options: builderData.form.options, 
 | 
        columns: builderData.columns 
 | 
      }, 
 | 
      tableInfo: null, 
 | 
      data: [], 
 | 
      tree: [] 
 | 
    }; 
 | 
  }, 
 | 
  watch: { 
 | 
    'layOutOptins.fields.vuePath'(val) { 
 | 
      localStorage.setItem('vuePath', val); 
 | 
    }, 
 | 
    deep: true 
 | 
    //localStorage.setItem("vuePath", this.layOutOptins.fields.vuePath || ""); 
 | 
  }, 
 | 
  methods: { 
 | 
    changeMore(funName) { 
 | 
      this[funName](); 
 | 
    }, 
 | 
    help() { 
 | 
      window.open('http://v2.volcore.xyz/document/coder'); 
 | 
      // this.helpModel = true; 
 | 
    }, 
 | 
    addVisible(pid) { 
 | 
      this.addModel = true; 
 | 
      this.$refs.form.reset(); 
 | 
      this.data.splice(0); 
 | 
      if (pid) { 
 | 
        this.layOutOptins.fields.parentId = pid; 
 | 
      } 
 | 
    }, 
 | 
    delTree() { 
 | 
      let tableId = this.layOutOptins.fields.table_Id; 
 | 
      if (!tableId) return this.$message.error('请选择节点'); 
 | 
      let tigger = false; 
 | 
      this.$confirm('删除警告?', '确认要删除吗', { 
 | 
        confirmButtonText: '确定', 
 | 
        cancelButtonText: '取消', 
 | 
        type: 'warning', 
 | 
        center: true 
 | 
      }).then(() => { 
 | 
        if (tigger) return; 
 | 
        tigger = true; 
 | 
        this.http 
 | 
          .post('/api/builder/delTree?table_Id=' + tableId, {}, true) 
 | 
          .then((x) => { 
 | 
            if (!x.status) return this.$message.error(x.message); 
 | 
            this.$message.error('删除成功,请刷新页面'); 
 | 
            // for (let index = 0; index < this.tree.length; index++) { 
 | 
            //   if (this.tree[index].id == tableId) { 
 | 
            //     this.tree.splice(index, 1); 
 | 
            //   } 
 | 
            // } 
 | 
          }); 
 | 
      }); 
 | 
    }, 
 | 
    add() { 
 | 
      this.$refs.form.validate(() => { 
 | 
        // this.layOutOptins.fields.tableName = 
 | 
        //   this.layOutOptins.fields.tableName.slice(0, 1).toUpperCase() + 
 | 
        //   this.layOutOptins.fields.tableName.slice(1); 
 | 
        if (!this.layOutOptins.fields.tableTrueName) { 
 | 
          this.layOutOptins.fields.tableTrueName = this.layOutOptins.fields.tableName; 
 | 
        } 
 | 
  
 | 
        let queryParam = 
 | 
          'parentId=' + 
 | 
          this.layOutOptins.fields.parentId + 
 | 
          '&tableName=' + 
 | 
          this.layOutOptins.fields.tableName + 
 | 
          '&columnCNName=' + 
 | 
          this.layOutOptins.fields.columnCNName + 
 | 
          '&nameSpace=' + 
 | 
          this.layOutOptins.fields.namespace + 
 | 
          '&foldername=' + 
 | 
          this.layOutOptins.fields.folderName + 
 | 
          '&isTreeLoad=false'; 
 | 
        this.http 
 | 
          .post('/api/builder/LoadTableInfo?' + queryParam, {}, true) 
 | 
          .then((x) => { 
 | 
            if (!x.status) { 
 | 
              this.$message.error(x.message); 
 | 
              return; 
 | 
            } 
 | 
            let hasTree = this.tree.some((t) => { 
 | 
              return t.id == x.data.table_Id; 
 | 
            }); 
 | 
            if (!hasTree) { 
 | 
              this.tree.push({ 
 | 
                id: x.data.table_Id, 
 | 
                pId: x.data.parentId, 
 | 
                parentId: x.data.parentId, 
 | 
                name: x.data.columnCNName, 
 | 
                orderNo: x.data.orderNo 
 | 
              }); 
 | 
            } 
 | 
            if (!x.data.tableTrueName) { 
 | 
              x.data.tableTrueName = x.data.tableName; 
 | 
            } 
 | 
            this.addModel = false; 
 | 
            this.tableInfo = x.data; 
 | 
            this.$refs.form.reset(x.data); 
 | 
            this.data = x.data.tableColumns; 
 | 
          }); 
 | 
      }); 
 | 
    }, 
 | 
    addChild() { 
 | 
      // this.$message.info("开发中"); 
 | 
      let id = this.layOutOptins.fields.table_Id; 
 | 
      if (!id) { 
 | 
        return this.$message.error('请选中节点'); 
 | 
      } 
 | 
      this.addVisible(id); 
 | 
    }, 
 | 
    addRow() { 
 | 
      this.data.push({}); 
 | 
    }, 
 | 
    delRow() { 
 | 
      let tigger = false; 
 | 
      this.$confirm('删除警告?', '确认要删除选择的数据吗', { 
 | 
        confirmButtonText: '确定', 
 | 
        cancelButtonText: '取消', 
 | 
        type: 'warning', 
 | 
        center: true 
 | 
      }).then(() => { 
 | 
        if (tigger) return; 
 | 
        tigger = true; 
 | 
        this.$refs.table.delRow(); 
 | 
      }); 
 | 
    }, 
 | 
    validateTableInfo(callback) { 
 | 
      this.$refs.form.validate(() => { 
 | 
        if (!this.tableInfo) { 
 | 
          this.$message.error('请先加载数据'); 
 | 
          return false; 
 | 
        } 
 | 
        if (this.data && this.data.length > 0) { 
 | 
          let keyInfo = this.data.find((x) => { 
 | 
            return x.isKey; 
 | 
          }); 
 | 
          if (!keyInfo) { 
 | 
            this.$message.error('请勾选设置主键'); 
 | 
            return false; 
 | 
          } 
 | 
          if (keyInfo.isNull == 1) { 
 | 
            this.$message.error('主键【可为空】必须设置为否'); 
 | 
            return false; 
 | 
          } 
 | 
          if ( 
 | 
            keyInfo.columnType != 'int' && 
 | 
            keyInfo.columnType != 'bigint' && 
 | 
            !this.layOutOptins.fields.sortName 
 | 
          ) { 
 | 
            this.$message.error('主键非自增类型,请设置上面表单的【排序字段】'); 
 | 
            return false; 
 | 
          } 
 | 
        } 
 | 
  
 | 
        for (const key in this.tableInfo) { 
 | 
          if (this.layOutOptins.fields.hasOwnProperty(key)) { 
 | 
            let newVal = this.layOutOptins.fields[key]; 
 | 
            this.tableInfo[key] = newVal; 
 | 
          } 
 | 
        } 
 | 
        callback(); 
 | 
      }); 
 | 
    }, 
 | 
    ceateVuePage(isApp) { 
 | 
      this.validateTableInfo(() => { 
 | 
        let vuePath; 
 | 
        if (!isApp) { 
 | 
          vuePath = localStorage.getItem('vuePath'); 
 | 
          if (!vuePath) { 
 | 
            return this.$message.error( 
 | 
              '请先设置Vue项目对应Views的绝对路径,然后再保存!' 
 | 
            ); 
 | 
          } 
 | 
        } else { 
 | 
          vuePath = localStorage.getItem('appPath'); 
 | 
          if (!vuePath) { 
 | 
            return this.$message.error('请先设置app路径,然后再保存!'); 
 | 
          } 
 | 
        } 
 | 
  
 | 
        let url = `/api/builder/createVuePage?vuePath=${vuePath}&v3=1&app=${isApp || 
 | 
          0}`; 
 | 
        this.http.post(url, this.tableInfo, true).then((x) => { 
 | 
          this.$Message.info(x); 
 | 
        }); 
 | 
      }); 
 | 
    }, 
 | 
    createService() { 
 | 
      this.validateTableInfo(() => { 
 | 
        let queryParam = 
 | 
          'tableName=' + 
 | 
          this.layOutOptins.fields.tableName + 
 | 
          '&nameSpace=' + 
 | 
          this.layOutOptins.fields.namespace + 
 | 
          '&foldername=' + 
 | 
          this.layOutOptins.fields.folderName; 
 | 
        this.http 
 | 
          .post( 
 | 
            '/api/builder/CreateServices?' + queryParam, 
 | 
            this.tableInfo, 
 | 
            true 
 | 
          ) 
 | 
          .then((x) => { 
 | 
            this.$Message.info(x); 
 | 
          }); 
 | 
      }); 
 | 
    }, 
 | 
    ceateModel() { 
 | 
      this.validateTableInfo(() => { 
 | 
        this.http 
 | 
          .post('/api/builder/CreateModel', this.tableInfo, true) 
 | 
          .then((x) => { 
 | 
            this.$message.info(x); 
 | 
          }); 
 | 
      }); 
 | 
    }, 
 | 
    syncTable() { 
 | 
      if (!this.layOutOptins.fields.tableName) 
 | 
        return this.$Message.error('请选模块'); 
 | 
      this.http 
 | 
        .post( 
 | 
          '/api/builder/syncTable?tableName=' + 
 | 
            this.layOutOptins.fields.tableName, 
 | 
          {}, 
 | 
          true 
 | 
        ) 
 | 
        .then((x) => { 
 | 
          if (!x.status) { 
 | 
            return this.$Message.error(x.message); 
 | 
          } 
 | 
          this.$Message.info(x.message); 
 | 
          this.loadTableInfo(this.layOutOptins.fields.table_Id); 
 | 
        }); 
 | 
    }, 
 | 
    ceateApiController() {}, 
 | 
    ceateController() {}, 
 | 
    checkSortName() {}, 
 | 
    save() { 
 | 
      localStorage.setItem('vuePath', this.layOutOptins.fields.vuePath || ''); 
 | 
      localStorage.setItem('appPath', this.layOutOptins.fields.appPath || ''); 
 | 
  
 | 
      if ( 
 | 
        this.tableInfo && 
 | 
        this.tableInfo.tableColumns && 
 | 
        this.tableInfo.tableColumns.length && 
 | 
        this.tableInfo.tableColumns.filter((x) => { 
 | 
          return x.isKey == 1; 
 | 
        }).length > 1 
 | 
      ) { 
 | 
        return this.$Message.error('表结构只能勾选一个主键字段'); 
 | 
      } 
 | 
      this.validateTableInfo(() => { 
 | 
        this.http.post('/api/builder/Save', this.tableInfo, true).then((x) => { 
 | 
          if (!x.status) { 
 | 
            this.$Message.error(x.message); 
 | 
            return; 
 | 
          } 
 | 
          this.$Message.info(x.message); 
 | 
          this.tree.forEach((x) => { 
 | 
            if (x.id == this.layOutOptins.fields.table_Id) { 
 | 
              x.name = this.layOutOptins.fields.columnCNName; 
 | 
              x.parentId = this.layOutOptins.fields.parentId; 
 | 
            } 
 | 
          }); 
 | 
          this.tableInfo = x.data; 
 | 
          x.data.vuePath = this.layOutOptins.fields.vuePath; 
 | 
          x.data.appPath = this.layOutOptins.fields.appPath; 
 | 
          this.$refs.form.reset(x.data); 
 | 
          //  this.layOutOptins.fields.vuePath = localStorage.getItem("vuePath"); 
 | 
          this.data = x.data.tableColumns; 
 | 
          //  this.$Message.info(x); 
 | 
        }); 
 | 
      }); 
 | 
    }, 
 | 
    onSelect(node) { 
 | 
      this.loadTableInfo(node); 
 | 
    }, 
 | 
    onOpenChange(node) { 
 | 
      if (node.length == 0) return; 
 | 
      this.loadTableInfo(node.length == 1 ? node[0] : node[node.length - 1]); 
 | 
    }, 
 | 
    loadTableInfo(id) { 
 | 
      // localStorage.setItem("vuePath", this.layOutOptins.fields.vuePath || ""); 
 | 
      this.http 
 | 
        .post( 
 | 
          '/api/builder/LoadTableInfo?table_Id=' + id + '&isTreeLoad=true', 
 | 
          {}, 
 | 
          true 
 | 
        ) 
 | 
        .then((x) => { 
 | 
          if (!x.data.tableTrueName) { 
 | 
            x.data.tableTrueName = x.data.tableName; 
 | 
          } 
 | 
          //2021.01.09增加代码生成器设置table排序功能 
 | 
          const _fields = [ 
 | 
            'sortable', 
 | 
            'isNull', 
 | 
            'isReadDataset', 
 | 
            'isColumnData', 
 | 
            'isDisplay' 
 | 
          ]; 
 | 
          x.data.tableColumns.forEach((item) => { 
 | 
            for (let index = 0; index < _fields.length; index++) { 
 | 
              item[_fields[index]] = item[_fields[index]] || 0; 
 | 
            } 
 | 
          }); 
 | 
          this.tableInfo = x.data; 
 | 
  
 | 
          this.$refs.form.reset(x.data); 
 | 
          this.data = x.data.tableColumns; 
 | 
        }); 
 | 
    }, 
 | 
    getVuePath(key) { 
 | 
      let vuePath = localStorage.getItem(key); 
 | 
      if (!vuePath || vuePath == 'null' || vuePath == 'undefined') { 
 | 
        vuePath = ''; 
 | 
      } 
 | 
      return vuePath; 
 | 
    } 
 | 
  }, 
 | 
  mounted() {}, 
 | 
  created() { 
 | 
    let clientHeight = document.documentElement.clientHeight - 170; 
 | 
    this.tableHeight = clientHeight < 400 ? 400 : clientHeight; 
 | 
    this.http 
 | 
      .post('/api/Sys_Dictionary/GetBuilderDictionary', {}, true) 
 | 
      .then((dic) => { 
 | 
        let column = this.layOutOptins.columns.find((x) => { 
 | 
          return x.field == 'dropNo'; 
 | 
        }); 
 | 
        if (!column) return; 
 | 
  
 | 
        let data = [{ key: '', value: '' }]; 
 | 
        for (let index = 0; index < dic.length; index++) { 
 | 
          data.push({ key: dic[index], value: dic[index] }); 
 | 
        } 
 | 
  
 | 
        column.bind.data = data; 
 | 
      }); 
 | 
  
 | 
    builderData.form.fields.vuePath = this.getVuePath('vuePath'); 
 | 
    builderData.form.fields.appPath = this.getVuePath('appPath'); 
 | 
    this.http.post('/api/builder/GetTableTree', {}, false).then((x) => { 
 | 
      this.tree = JSON.parse(x.list); 
 | 
      if (!x.nameSpace) { 
 | 
        return this.$message.error( 
 | 
          '未获取后台项目类库所在命名空间,请确认目录或调试Sys_TableInfoService类GetTableTree方法' 
 | 
        ); 
 | 
      } 
 | 
      let nameSpace = JSON.parse(x.nameSpace); 
 | 
      let nameSpaceArr = []; 
 | 
      for (let index = 0; index < nameSpace.length; index++) { 
 | 
        nameSpaceArr.push({ 
 | 
          key: nameSpace[index], 
 | 
          value: nameSpace[index] 
 | 
        }); 
 | 
      } 
 | 
  
 | 
      //初始化项目命令空间 
 | 
      this.layOutOptins.options.forEach((option) => { 
 | 
        option.forEach((item) => { 
 | 
          if (item.field == 'namespace') { 
 | 
            item.data.push(...nameSpaceArr); 
 | 
          } 
 | 
        }); 
 | 
      }); 
 | 
      this.addOptions.forEach((option) => { 
 | 
        option.forEach((item) => { 
 | 
          if (item.field == 'namespace') { 
 | 
            item.data.push(...nameSpaceArr); 
 | 
          } 
 | 
        }); 
 | 
      }); 
 | 
    }); 
 | 
  } 
 | 
}; 
 | 
</script> 
 | 
<style scoped> 
 | 
.builder-tree { 
 | 
  position: absolute; 
 | 
  top: 41px; 
 | 
  bottom: 0; 
 | 
} 
 | 
.builder-tree >>> .ivu-menu { 
 | 
  text-align: left; 
 | 
  width: 200px !important; 
 | 
} 
 | 
.builder-container { 
 | 
  widows: 100%; 
 | 
  /* padding: 20px; */ 
 | 
  position: absolute; 
 | 
  top: 0px; 
 | 
  left: 0; 
 | 
  right: 0; 
 | 
  display: inline-block; 
 | 
  bottom: 0; 
 | 
} 
 | 
.grid-container >>> tr:hover { 
 | 
  cursor: pointer; 
 | 
} 
 | 
.builder-left { 
 | 
  position: relative; 
 | 
  width: 201px; 
 | 
  height: 100%; 
 | 
  border-right: 2px solid #dcd6d6; 
 | 
} 
 | 
.builder-content { 
 | 
  position: absolute; 
 | 
  top: 0px; 
 | 
  left: 200px; 
 | 
  display: inline-block; 
 | 
  bottom: 0; 
 | 
  right: 0px; 
 | 
} 
 | 
.builder-content .ivu-alert { 
 | 
  position: relative; 
 | 
  display: flex; 
 | 
  padding: 12px 18px 12px 38px; 
 | 
} 
 | 
.builder-content .ivu-alert-icon { 
 | 
  top: 10px; 
 | 
} 
 | 
.builder-content .action { 
 | 
  text-align: right; 
 | 
  line-height: 33px; 
 | 
  padding-right: 26px; 
 | 
} 
 | 
.builder-content .action i { 
 | 
  top: 0px; 
 | 
  position: relative; 
 | 
} 
 | 
.builder-content .action > span { 
 | 
  padding: 0px 6px; 
 | 
  font-size: 12px; 
 | 
  letter-spacing: 1px; 
 | 
  color: #5a5f5e; 
 | 
} 
 | 
.builder-content .action > span:hover { 
 | 
  cursor: pointer; 
 | 
  color: black; 
 | 
} 
 | 
.builder-content .config { 
 | 
  /* border: 1px solid #e9e8e8; */ 
 | 
  padding: 15px 15px 0px 15px; 
 | 
  border-radius: 3px; 
 | 
  background: #ffffff; 
 | 
  margin-bottom: 10px; 
 | 
} 
 | 
.builder-container .config >>> .ivu-form > .ivu-form-item { 
 | 
  display: none; 
 | 
} 
 | 
.coder-container { 
 | 
  background: #eee; 
 | 
} 
 | 
.coder-container .coder-item { 
 | 
  background: white; 
 | 
  padding: 0px 15px; 
 | 
} 
 | 
.module-name { 
 | 
  color: #2d8cf0; 
 | 
  font-size: 13px; 
 | 
  line-height: 39px; 
 | 
  padding-left: 15px; 
 | 
  border: 1px solid #abdcff; 
 | 
  background-color: #f0faff; 
 | 
} 
 | 
.module-name >>> .ivu-alert-icon { 
 | 
  top: 12px; 
 | 
} 
 | 
.help { 
 | 
  margin-left: 15px; 
 | 
  top: 2px; 
 | 
  position: relative; 
 | 
  border-bottom: 1px solid; 
 | 
} 
 | 
.help:hover { 
 | 
  color: #f56c6c; 
 | 
  cursor: pointer; 
 | 
} 
 | 
.more { 
 | 
  text-align: left; 
 | 
  position: relative; 
 | 
  top: 2px; 
 | 
} 
 | 
.addModel { 
 | 
  padding: 10px; 
 | 
} 
 | 
</style> 
 |