<template>
  <a-config-provider :locale="locale">
    <div class="form-designer-container-9136076486841527">
      <k-header v-if="showHead" :title="title" />
      <!-- 操作区域 start -->
      <operatingArea
        v-if="toolbarsTop"
        :showToolbarsText="showToolbarsText"
        :toolbars="toolbars"
        @handleSave="handleSave"
        @handlePreview="handlePreview"
        @handleOpenImportJsonModal="handleOpenImportJsonModal"
        @handleOpenCodeModal="handleOpenCodeModal"
        @handleOpenJsonModal="handleOpenJsonModal"
        @handleReset="handleReset"
        @handleClose="handleClose"
        @handleUndo="handleUndo"
        @handleRedo="handleRedo"
        :recordList="recordList"
        :redoList="redoList"
      >
        <template slot="left-action">
          <slot name="left-action"></slot>
        </template>

        <template slot="right-action">
          <slot name="right-action"></slot>
        </template>
      </operatingArea>
      <!-- 操作区域 end -->
      <div
        class="content"
        :class="{
          'show-head': showHead,
          'toolbars-top': toolbarsTop,
          'show-head-and-toolbars-top': toolbarsTop && showHead
        }"
      >
        <!-- 左侧控件区域 start -->
        <aside class="left">
          <a-collapse @change="collapseChange" :defaultActiveKey="collapseDefaultActiveKey">
            <!-- 基础控件 start -->
            <a-collapse-panel v-if="basicsArray.length > 0" header="基础控件" key="1">
              <collapseItem
                :list="basicsArray"
                @generateKey="generateKey"
                @handleListPush="handleListPush"
                @start="handleStart"
              />
            </a-collapse-panel>
            <!-- 基础控件 end -->
            <!-- 自定义控件 start -->
            <a-collapse-panel
              v-if="customComponents.list.length > 0"
              :header="customComponents.title"
              key="3"
            >
              <collapseItem
                :list="customComponents.list"
                @generateKey="generateKey"
                @handleListPush="handleListPush"
                @start="handleStart"
              />
            </a-collapse-panel>
            <!-- 自定义控件 end -->

            <!-- 布局控件 start -->
            <a-collapse-panel v-if="layoutArray.length > 0" header="布局控件" key="4">
              <collapseItem
                :list="layoutArray"
                @generateKey="generateKey"
                @handleListPush="handleListPush"
                @start="handleStart"
              />
            </a-collapse-panel>
            <!-- 布局控件 end -->
          </a-collapse>
        </aside>
        <!-- 左侧控件区域 end -->

        <!-- 中间面板区域 start -->
        <section>
          <!-- 操作区域 start -->
          <operatingArea
            v-if="!toolbarsTop"
            :showToolbarsText="showToolbarsText"
            :toolbars="toolbars"
            @handleSave="handleSave"
            @handlePreview="handlePreview"
            @handleOpenImportJsonModal="handleOpenImportJsonModal"
            @handleOpenCodeModal="handleOpenCodeModal"
            @handleOpenJsonModal="handleOpenJsonModal"
            @handleReset="handleReset"
            @handleClose="handleClose"
            @handleUndo="handleUndo"
            @handleRedo="handleRedo"
            @handleQuery="handleQuery"
            :recordList="recordList"
            :redoList="redoList"
          >
            <template slot="left-action">
              <slot name="left-action"></slot>
            </template>

            <template slot="right-action">
              <slot name="right-action"></slot>
            </template>
          </operatingArea>
          <!-- 操作区域 end -->
          <k-form-component-panel
            :class="{ 'no-toolbars-top': !toolbarsTop }"
            :data="data"
            :selectItem="selectItem"
            :noModel="noModel"
            :hideModel="hideModel"
            :startType="startType"
            ref="KFCP"
            @handleSetSelectItem="handleSetSelectItem"
          />
          <!-- 操作区域 start -->
          <k-json-modal ref="jsonModal" />
          <k-code-modal ref="codeModal" />
          <importJsonModal ref="importJsonModal" />
          <previewModal ref="previewModal" />
          <!-- 查询弹框 -->
          <queryModal ref="queryModal" />
          <!-- 同表多个表单先择弹框 -->
          <selectTbTableInfoModal ref="selectTbTableInfoModal"/>
        </section>
        <!-- 中间面板区域 end -->

        <!-- 右侧控件属性区域 start -->
        <aside class="right">
          <a-tabs :activeKey="activeKey" @change="changeTab" :tabBarStyle="{ margin: 0 }">
            <a-tab-pane :key="1" tab="表单属性设置">
              <formProperties :config="data.config" :formData="formData" :previewOptions="previewOptions" />
            </a-tab-pane>
            <a-tab-pane :key="2" tab="控件属性设置">
              <formItemProperties
                class="form-item-properties"
                :selectItem="selectItem"
                :hideModel="hideModel"
                :tableColumnList="tableColumnList"
              />
            </a-tab-pane>
          </a-tabs>
        </aside>
        <!-- 右侧控件属性区域 end -->
      </div>
      <!-- <k-footer /> -->
    </div>
  </a-config-provider>
</template>
<script>
/*
 * author kcz
 * date 2019-11-20
 * description 表单设计器
 */
import kHeader from "./module/header";
import operatingArea from "./module/operatingArea";

// import kFooter from "./module/footer";
import kFormComponentPanel from "./module/formComponentPanel";
import kJsonModal from "./module/jsonModal";
import kCodeModal from "./module/codeModal";
import collapseItem from "./module/collapseItem";
import importJsonModal from "./module/importJsonModal";
import queryModal from "./module/queryModal";
import selectTbTableInfoModal from "./module/selectTbTableInfoModal";
import previewModal from "../KFormPreview/index.vue";
import zhCN from "ant-design-vue/lib/locale-provider/zh_CN";

import { Revoke } from "../core/revoke";
import {
  basicsList,
  layoutList,
  customComponents
} from "./config/formItemsConfig";
import formItemProperties from "./module/formItemProperties";
import formProperties from "./module/formProperties";
import { getFormByBusinessTable, getTableColumnList } from "../api/api";
export default {
  name: "KFormDesign",
  props: {
    title: {
      type: String,
      default: "表单设计器"
    },
    showHead: {
      type: Boolean,
      default: true
    },
    hideResetHint: {
      type: Boolean,
      default: false
    },
    toolbarsTop: {
      type: Boolean,
      default: false
    },
    toolbars: {
      type: Array,
      default: () => [
        "save",
        "preview",
        "importJson",
        "exportJson",
        "exportCode",
        "reset",
        "close",
        "undo",
        "redo"
      ]
    },
    showToolbarsText: {
      type: Boolean,
      default: false
    },
    fields: {
      type: Array,
      default: () => [
        "input",
        "textarea",
        "number",
        "select",
        "checkbox",
        "radio",
        "date",
        "time",
        "rate",
        "slider",
        "uploadFile",
        "uploadImg",
        "cascader",
        "treeSelect",
        "batch",
        "selectInputList",
        "editor",
        "switch",
        "button",
        "alert",
        "text",
        "html",
        "divider",
        "card",
        "tabs",
        "grid",
        "table"
      ]
    },
    hideModel: {
      // 隐藏数据字段
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      businessTableHC:"",//用来记录关联的数据库表
      tableColumnList:[],//数据表字段集合
      formData: {}, //表单数据
      locale: zhCN,
      customComponents,
      activeKey: 1,
      updateTime: 0,
      updateRecordTime: 0,
      startType: "",
      revoke: null,
      recordList: [],
      redoList: [],
      noModel: [
        "button",
        "divider",
        "card",
        "grid",
        "tabs",
        "table",
        "alert",
        "text",
        "html"
      ],
      data: {
        list: [],
        config: {
          layout: "horizontal",
          labelCol: { xs: 4, sm: 4, md: 4, lg: 4, xl: 4, xxl: 4 },
          labelWidth: 100,
          labelLayout: "flex",
          wrapperCol: { xs: 18, sm: 18, md: 18, lg: 18, xl: 18, xxl: 18 },
          hideRequiredMark: false,
          customStyle: ""
        }
      },
      previewOptions: {
        width: 850
      },
      selectItem: {
        key: ""
      }
    };
  },
  components: {
    kHeader,
    // kFooter,
    operatingArea,
    collapseItem,
    kJsonModal,
    kCodeModal,
    importJsonModal,
    previewModal,
    kFormComponentPanel,
    formItemProperties,
    formProperties,
    queryModal,
    selectTbTableInfoModal
  },
  watch: {
    data: {
      handler(e) {
        this.$nextTick(() => {
          this.revoke.push(e);
        });
      },
      deep: true,
      immediate: true
    }
  },
  computed: {
    basicsArray() {
      // 计算需要显示的基础字段
      return basicsList.filter(item => this.fields.includes(item.type));
    },
    layoutArray() {
      // 计算需要显示的布局字段
      return layoutList.filter(item => this.fields.includes(item.type));
    },
    collapseDefaultActiveKey() {
      // 计算当前展开的控件列表
      const defaultActiveKey = window.localStorage.getItem(
        "collapseDefaultActiveKey"
      );
      if (defaultActiveKey) {
        return defaultActiveKey.split(",");
      } else {
        return ["1"];
      }
    }
  },
  methods: {
    generateKey(list, index) {
        // 生成key值
          const key = list[index].type + "_" + new Date().getTime();
          this.$set(list, index, {
            ...list[index],
            key,
            model: key
          });
          if (this.noModel.includes(list[index].type)) {
            // 删除不需要的model属性
            delete list[index].model;
          }
    },
    handleListPush(item) {
      if(this.formData.businessTable){
          // 双击控件按钮push到list
          // 生成key值
          if (!this.selectItem.key) {
            // 在没有选择表单时，将数据push到this.data.list
            const key = item.type + "_" + new Date().getTime();
            item = {
              ...item,
              key,
              model: key,
            };
            if (this.noModel.includes(item.type)) {
              // 删除不需要的model属性
              delete item.model;
            }
            const itemString = JSON.stringify(item);
            const record = JSON.parse(itemString);
            // 删除icon及compoent属性
            delete record.icon;
            delete record.component;
            this.data.list.push(record);
            this.handleSetSelectItem(record);
            return false;
          }
          this.$refs.KFCP.handleCopy(false, item);
      }else{
        this.$message.error("请先选择表单属性中的关联数据表")
      }
    },
    handleOpenJsonModal() {
      // 打开json预览模态框
      this.$refs.jsonModal.jsonData = this.data;
      this.$refs.jsonModal.formData =JSON.parse(JSON.stringify(this.formData));
      this.$refs.jsonModal.visible = true;
    },
    handleOpenCodeModal() {
      // 打开代码预览模态框
      this.$refs.codeModal.jsonData = this.data;
      this.$refs.codeModal.visible = true;
    },
    handleOpenImportJsonModal() {
      // 打开json预览模态框
      this.$refs.importJsonModal.jsonData = this.data;
      this.$refs.importJsonModal.handleSetSelectItem = this.handleSetSelectItem;
      this.$refs.importJsonModal.visible = true;
    },
    handlePreview() {
      // 打开预览模态框
      this.$refs.previewModal.jsonData = this.data;
      this.$refs.previewModal.previewWidth = this.previewOptions.width;
      this.$refs.previewModal.visible = true;
    },
    handleQuery() {
      // 打开查询模态框
      this.$refs.queryModal.jsonData = this.data;
      this.$refs.queryModal.formData = this.formData;
      // this.$refs.queryModal.previewWidth = this.previewOptions.width;
      this.$refs.queryModal.visible = true;
    },
    handleReset() {
      // 清空
      if (this.hideResetHint) {
        this.formData = {};
        this.$refs.queryModal.formData = {};
        this.tableColumnList=[];
        // 不显示提示直接清空
        this.resetData();
        return;
      }

      this.$confirm({
        title: "警告",
        content: "是否确认清空内容?",
        okText: "是",
        okType: "danger",
        cancelText: "否",
        onOk: () => {
          this.resetData();
        }
      });
    },
    resetData() {
      this.data = {
        list: [],
        config: {
          layout: "horizontal",
          labelCol: { xs: 4, sm: 4, md: 4, lg: 4, xl: 4, xxl: 4 },
          labelWidth: 100,
          labelLayout: "flex",
          wrapperCol: { xs: 18, sm: 18, md: 18, lg: 18, xl: 18, xxl: 18 },
          hideRequiredMark: false,
          customStyle: ""
        }
      };
      this.handleSetSelectItem({ key: "" });
      this.$message.success("已清空");
    },
    handleSetSelectItem(record) {
        // 操作间隔不能低于100毫秒
        const newTime = new Date().getTime();
        if (newTime - this.updateTime < 100) {
          return false;
        }

        this.updateTime = newTime;
        // 设置selectItem的值
          this.selectItem = record;
        ///获取表字段的下拉数据
        //判断字段下拉数据是否有集合 或者关联的数据库表有改动
        if(!this.tableColumnList||this.tableColumnList.length<=0||(this.formData.businessTable!=this.businessTableHC)){//没有则查询
              //获取表字段下拉数据接口
              getTableColumnList(this.formData.businessTable).then(res=>{
                this.businessTableHC=this.formData.businessTable;
                this.tableColumnList=res.data.result;//表字段下拉数据
              });
        }
        // 判断是否选中控件，如果选中则弹出属性面板，否则关闭属性面板
        if (record.key) {
          this.startType = record.type;
          this.changeTab(2);
        } else {
          this.changeTab(1);
        }
    },
    /**
     * @description: 切换属性设置面板
     * @param {*}
     * @return {*}
     */

    changeTab(e) {
      this.activeKey = e;
    },
    /**
     * @Author: kcz
     * @description: 遍历json结构，获取所有字段
     * @param {*}
     * @return {*} Array
     */
    getFieldSchema() {
      const fields = [];
      const traverse = array => {
        array.forEach(element => {
          if (element.type === "grid" || element.type === "tabs") {
            // 栅格布局
            element.columns.forEach(item => {
              traverse(item.list);
            });
          } else if (element.type === "card") {
            // 卡片布局
            traverse(element.list);
          } else if (element.type === "batch") {
            // 动态表格内复制
            traverse(element.list);
          } else if (element.type === "table") {
            // 表格布局
            element.trs.forEach(item => {
              item.tds.forEach(val => {
                traverse(val.list);
              });
            });
          } else {
            if (element.model) {
              fields.push(element);
            }
          }
        });
      };
      traverse(this.data.list);
      return fields;
    },
    handleSetData(data) {
      // 用于父组件赋值
      try {
        if (typeof data !== "object") {
          return false;
        } else {
          this.data = data;
          // 导入json数据后，需要清除已选择key
          this.handleSetSelectItem({ key: "" });
        }
        return true;
      } catch (error) {
        console.error(error);
        return false;
      }
    },
    collapseChange(val) {
      // 点击collapse时，保存当前collapse状态
      window.localStorage.setItem("collapseDefaultActiveKey", val);
    },
    handleStart(type) {
      this.startType = type;
    },

    /**
     * @description: 撤销
     * @param {*}
     * @return {*}
     */
    handleUndo() {
      const record = this.revoke.undo();
      if (!record) {
        return false;
      }
      this.data = record;

      this.handleSetSelectItem({ key: "" });
    },

    /**
     * @description: 重做
     * @param {*}
     * @return {*}
     */
    handleRedo() {
      const record = this.revoke.redo();
      if (!record) {
        return false;
      }
      this.data = record;
    },

    handleSave() {
      // 保存函数
      this.$emit("save", JSON.stringify(this.data));
    },
    getValue() {
      // 获取数据
      return this.data;
    },
    handleClose() {
      this.$emit("close");
    }
  },
  created() {
    this.revoke = new Revoke();
    this.recordList = this.revoke.recordList;
    this.redoList = this.revoke.redoList;
    console.log(this.$route.query.tableName);
    //判断是否有接收到表明
    if (this.$route.query.tableName) {
      //有则根据表明查询表单json以及相关数据
      getFormByBusinessTable(this.$route.query.tableName).then(res => {
        if (res.data.success) {

          if(res.data.result.tbTableInfoList!=null&&res.data.result.tbTableInfoList.length>1){
            // 打开查询模态框
            // this.$refs.queryModal.jsonData = this.data;
            // this.$refs.queryModal.formData = this.formData;
            // this.$refs.queryModal.previewWidth = this.previewOptions.width;
            this.$refs.selectTbTableInfoModal.visible = true;
            this.$refs.selectTbTableInfoModal.dataSource=res.data.result.tbTableInfoList;
            this.$refs.selectTbTableInfoModal.jsonData = this.data;//表单json
            this.$refs.selectTbTableInfoModal.formData = this.formData;//表单相关字段数据
          }else{
            //获取Json字符串装json格式
            const editorJsonData = res.data.result.jsonContent;
            const jsonData = {};
            //获取json展示的数据
            jsonData.list = editorJsonData.list;
            jsonData.config = editorJsonData.config;
            jsonData.config.layout = editorJsonData.config.layout;
            this.data = jsonData;
            //当前填写数据存储，用于其他页面获取
            this.formData.businessTable = this.$route.query.tableName; //数据库表明
            this.formData.text = res.data.result.text; //表单标题
            this.formData.stepMemo=res.data.result.stepMemo;//表单备注
            this.formData.type=res.data.result.type;//表单类型
            // this.$message.success("查询成功");
          }
        } else {
          this.$message.error(res.data.message);
        }
      });
    }
  }
};
//根据表名称获取表字段与表说明
// function getTableColumnListShow(item,formData){
    // getTableColumnList(formData.businessTable).then(res=>{
    //   if(res.data.success){
    //     item.tableList=res.data.result;
    //   }
    // });
    // item.tableList=[
    //   {columnName:"123",columnComment:"123"}
    // ]
// }
</script>
