<template>
  <a-modal
    wrapClassName="ant-modal-cust-warp"
    :style="{top:'5%',height:'95%'}"
    :title="title"
    :visible="visible"
    :width="modalWidth"
    :confirm-loading="confirmLoading"
    ok-text="生成代码"
    cancel-text="取消"
    @ok="handleSubmit"
    @cancel="handleCancel"
  >
    <a-form :form="form">
      <a-row :gutter="24">
        <a-col :span="24">
          <a-form-item
            label="代码生成目录"
            :labelCol="single ? labelCol: labelCol2"
            :wrapperCol="single ? wrapperCol: wrapperCol2"
          >

            <a-input-search
              placeholder="请选择代码生成目录"
              @change="storeProjectPath"
              @search="onSelectDir"
              v-decorator="['projectPath', validatorRules.projectPath]"
            >
              <a-button slot="enterButton" icon="folder-open">浏览</a-button>
            </a-input-search>
          </a-form-item>
          <a-form-item
            label="页面风格"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
          >
            <a-select placeholder="请选择代码生成目录" v-decorator="['jspMode']">
              <a-select-option v-for="(item, index) in jspModeList"
                               :key="index" :value="item.code">
                {{ item.note }}
              </a-select-option>
            </a-select>

          </a-form-item>

        </a-col >

        <a-col :span="single ? 24 : 12">

          <a-form-item
            label="功能说明"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
          >
            <a-input
              placeholder="请输入功能说明"
              v-decorator="['ftlDescription',validatorRules.ftlDescription]"
            />
          </a-form-item>
        </a-col>

        <a-col :span="single ? 24 : 12">
          <a-form-item
            label="数据模型"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
          >
            <a-select v-decorator="['jformType']">
              <a-select-option :value="1">单表</a-select-option>
              <a-select-option :value="2">一对多</a-select-option>
            </a-select>
          </a-form-item>
        </a-col>

        <a-col :span="single ? 24 : 12">
          <a-form-item
            label="表名"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
          >
            <a-input
              placeholder="请输入表名"
              v-decorator="['tableName_tmp',validatorRules.tableName_tmp]"
            />
          </a-form-item>
        </a-col>

        <a-col :span="single ? 24 : 12">
          <a-form-item
            label="实体类名"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
          >
            <a-input
              placeholder="请输入实体类名(首字母大写)"
              v-decorator="['entityName',validatorRules.entityName]"
            />
          </a-form-item>
        </a-col>

        <a-col :span="single ? 24 : 12">
          <a-form-item
            label="包名(小写)"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
          >
            <a-input
              placeholder="请输入包名"
              v-decorator="['entityPackage',validatorRules.entityPackage]"
            />
          </a-form-item>
        </a-col>

        <a-col :span="single ? 24 : 12">
          <a-form-item
            label="代码分层样式"
            :labelCol="labelCol"
            :wrapperCol="wrapperCol"
          >
            <a-select v-decorator="['packageStyle']">
              <a-select-option value="service">业务分层</a-select-option>
              <a-select-option value="project">代码分层</a-select-option>
            </a-select>
          </a-form-item>
        </a-col>

        <a-col :span="24" v-show="false">
          <a-form-item
            label="需要生成的代码"
            :labelCol="single ? labelCol : labelCol2"
            :wrapperCol="wrapperCol"
          >
            <j-checkbox v-decorator="['codeTypes']"
                        :options="genCodeTypes"
                        :trigger-change="true"/>
          </a-form-item>
        </a-col>

      </a-row>
    </a-form>

    <file-select-modal ref="fsm" @callback="updateFileDir"/>

    <a-modal title="代码生成结果"
             :width="1200"
             :visible="generateLogVisible"
             @cancel="generateLogVisible = false"
    >
      <template slot="footer">
        <a-button key="back" @click="handleGenerateOk">下载到本地</a-button>
        <a-button key="cancel" @click="generateLogVisible = false">取消</a-button>
        <a-button key="submit" @click="generateLogVisible = false" type="primary">确认关闭</a-button>
      </template>
      <p style="line-height: 10px;" v-for="(name, index) in generateLogList" :key="index" >
        {{name}}
      </p>
    </a-modal>

  </a-modal>
</template>

<script>

import {getNoAuthCols} from "@/utils/authFilter";
import FileSelectModal from './FileSelectModal'

import {getAction,postAction,downFile} from '@/api/manage'
import {underLine2CamelCase} from "@/utils/util";
import Template1 from '@views/jeecg/JVxeDemo/layout-demo/Template1'

let SocialSharing = {
  props : ["formData"],
  data : function() {
    return {};
  },
  methods : {
    isDisabledAuth : function(e) {
      return getNoAuthCols(e, this.formData);
    }
  }
};
let STORAGE_KEY_MOCKSTORE = "jeecg_onl_project_path";

export default {
  name: 'CodeGenerator',
  components : {
    Template1,
    FileSelectModal : FileSelectModal
  },
  mixins : [SocialSharing],
  data : function() {
    return {
      modalWidth : 800,
      title : "代码生成",
      visible : false,
      confirmLoading : false,
      form : this.$form.createForm(this),
      subLabelCol : {
        xs : {span : 24},
        sm : {span : 8}
      },
      subWrapperCol : {
        xs : {span : 24},
        sm : {span : 15}
      },
      labelCol : {
        xs : {span : 24},
        sm : {span : 6}
      },
      labelCol2 : {
        xs : {span : 24},
        sm : {span : 3}
      },
      wrapperCol : {
        xs : {span : 24},
        sm : {span : 16}
      },
      wrapperCol2 : {
        xs : {span : 24},
        sm : {span : 20}
      },
      genCodeTypes : [{
        label : "controller",
        value : "controller"
      }, {
        label : "service",
        value : "service"
      }, {
        label : "dao",
        value : "dao"
      }, {
        label : "mapper.xml",
        value : "mapper"
      }, {
        label : "entity",
        value : "entity"
      }, {
        label : "vue",
        value : "vue"
      }],
      validatorRules : {
        projectPath : {
          rules : [{
            required : true,
            message : "请选择代码生成目录!"
          }]
        },
        tableName_tmp : {
          rules : [{
            required : true,
            message : "请输入表名!"
          }]
        },
        entityPackage : {
          rules : [{
            required : true,
            message : "请输入包名!"
          }]
        },
        entityName : {
          rules : [{
            required : true,
            message : "请输入实体类名!"
          }]
        }
      },
      url : {
        tableInfo : "/online/form/head/tableInfo",
        codeGenerate : "/online/form/api/codeGenerate",
        downGenerateCode : "/online/form/api/downGenerateCode"
      },
      code : "",
      subInfoList : [],
      single : false,
      metaModel : {
        projectPath : "",
        packageStyle : "service",
        jspMode : "",
        jformType : "1",
        tableName_tmp : "",
        ftlDescription : "",
        entityName : "",
        codeTypes : "controller,service,dao,mapper,entity,vue"
      },
      model : {},
      jspModeList : [],
      generateLogList : [],
      generateLogVisible : false,
      generateTableName : ""
    };
  },
  methods : {
    handleSubmit : function() {
      let scope = this;
      let div = this;
      this.form.validateFields(function(n, file) {
        if (!n) {
          scope.confirmLoading = true;
          let precompiledFileName = Object.assign({}, file, {
            code : scope.code,
            tableName : file.tableName_tmp
          });
          postAction(scope.url.codeGenerate, precompiledFileName).then(function(data) {
            if (data.success) {
              scope.handleCancel();
              div.generateLogList = data.result;
              div.generateLogVisible = true;
              div.generateTableName = file.tableName_tmp;
            } else {
              scope.$message.warning(data.message);
            }
            scope.confirmLoading = false;
          });
        }
      });
    },
    handleCancel : function() {
      this.visible = false;
    },
    handleGenerateOk : function() {
      let self = this;
      this.generateLogVisible = false;
      let report = {
        fileList : encodeURI(this.generateLogList)
      };
      downFile(this.url.downGenerateCode, report).then(function(torrent) {
        if (torrent && 0 != torrent.size) {
          let filename = "导到生成代码_" + self.generateTableName + "_" + (new Date).getTime() + ".zip";
          if ("undefined" !== typeof window.navigator.msSaveBlob) {
            window.navigator.msSaveBlob(new Blob([torrent], {
              type : "application/zip"
            }), filename);
          } else {
            let objUrl = window.URL.createObjectURL(new Blob([torrent], {
              type : "application/zip"
            }));
            let link = document.createElement("a");
            link.style.display = "none";
            link.href = objUrl;
            link.setAttribute("download", filename);
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(objUrl);
          }
        } else {
          self.$message.warning("导出代码失败！");
        }
      });
    },
    show : function(value) {
      let self = this;
      this.confirmLoading = false;
      this.visible = true;
      this.getStoreProjectPath();
      this.code = value;
      this.subInfoList = [];
      this.model = Object.assign({}, this.metaModel);
      this.modalWidth = 800;
      getAction(this.url.tableInfo, {
        code : value
      }).then(function(stats) {
        if (stats.success) {
          let state = stats.result.main;
          self.jspModeList = [...stats.result.jspModeList];
          if ("Y" == state.isTree) {
            self.model.jspMode = "tree";
          } else {
            if (2 == state.tableType) {
              self.model.jspMode = "jvxe";
            } else {
              self.model.jspMode = self.jspModeList[0].code;
            }
          }
          self.single = 1 == state.tableType;
          self.title = "代码生成【" + state.tableName + "】";
          if (!self.model.projectPath) {
            self.model.projectPath = stats.result.projectPath;
            window.localStorage.setItem(STORAGE_KEY_MOCKSTORE, stats.result.projectPath);
          }
          self.model.jformType = state.tableType + "";
          self.model.tableName_tmp = state.tableName;
          self.model.ftlDescription = state.tableTxt;
          let diffUnnormalized = underLine2CamelCase(state.tableName);
          self.model.entityName = diffUnnormalized.substring(0, 1).toUpperCase() + diffUnnormalized.substring(1);
          self.$nextTick(function() {
            self.form.setFieldsValue(self.model);
          });
          if (stats.result.sub && stats.result.sub.length > 0) {
            self.subInfoList = stats.result.sub;
            self.modalWidth = 1200;
          }
        } else {
          self.$message.warning("表信息加载失败");
        }
      });
    },
    onSelectDir : function() {
      this.$refs.fsm.show();
    },
    updateFileDir : function(path) {
      window.localStorage.setItem(STORAGE_KEY_MOCKSTORE, path);
      this.form.setFieldsValue({
        projectPath : path
      });
    },
    getCamelCase : function(str) {
      var asciiString = underLine2CamelCase(str);
      return asciiString.substring(0, 1).toUpperCase() + asciiString.substring(1);
    },
    storeProjectPath : function(obj) {
      if (obj.target.value) {
        window.localStorage.setItem(STORAGE_KEY_MOCKSTORE, obj.target.value);
      }
    },
    getStoreProjectPath : function() {
      /** @type {(null|string)} */
      var projectPath = window.localStorage.getItem(STORAGE_KEY_MOCKSTORE);
      if (projectPath) {
        /** @type {string} */
        this.metaModel.projectPath = projectPath;
      }
    }
  }
}
</script>

<style scoped>

</style>