<template>
  <div class="builder-container">
    <mes-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">
        <mes-form
          ref="addForm"
          :formRules="addOptions"
          :formFields="layOutOptins.fields"
        >
        </mes-form>
      </div>
      <template #footer>
        <div>
          <el-button type="primary" size="small" @click="add"
            ><i class="el-icon-plus"></i> 确 定</el-button
          >
        </div>
      </template>
    </mes-box>
    <div class="builder-left">
      <div class="module-name">代码生成配置</div>
      <div class="builder-tree">
        <el-scrollbar style="height: 100%; width: 200px">
          <!-- :onOpenChange="onOpenChange" -->
          <MesMenu :list="tree" :onSelect="onSelect"></MesMenu>
        </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">
              <MesHeader 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>
              </MesHeader>
              <div class="config">
                <mes-form
                  :label-width="90"
                  ref="form"
                  :formRules="layOutOptins.options"
                  :formFields="layOutOptins.fields"
                ></mes-form>
              </div>
            </div>
            <el-alert type="warning" :closable="false">
              1、如果需要修改表结构，请在数据库修改，再点同步表结构->生成vue页面->生成model。
              2、修改编辑行后需要点击生成model、生成vue页面
            </el-alert>
            <div class="coder-item">
              <MesHeader
                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>
              </MesHeader>

              <div class="grid-container" style="padding-bottom: 20px">
                <mes-table
                  ref="table"
                  :paginationHide="true"
                  :tableData="data"
                  :height="tableHeight"
                  :columns="layOutOptins.columns"
                  :color="false"
                  :index="true"
                  :allowEmpty="true"
                  :clickEdit="true"
                ></mes-table>
              </div>
            </div>
          </div>
        </el-scrollbar>
      </div>
    </div>
  </div>
</template>
<script>
import builderData from './builderData';
import MesForm from '@/components/basic/MesForm.vue';
import MesTable from '@/components/basic/MesTable.vue';
import MesBox from '@/components/basic/MesBox.vue';
import MesHeader from '@/components/basic/MesHeader.vue';
import MesMenu from '@/components/basic/MesElementMenu.vue';
export default {
  components: {
    MesForm: MesForm,
    MesTable: MesTable,
    MesBox: MesBox,
    MesHeader: MesHeader,
    MesMenu
  },
  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('https://www.625sc.com');
      // 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>
