<template>
  <div class="cms-table-list" ref="cmsTableList">
    <cms-drawer
      v-model="drawerConfig.viewVisible"
      class="router-view-drawer"
      ref="cmsDrawerRef"
      @close="handleClose"
      :with-header="false"
      :title="''" :show-close-btn="false"
      :direction="drawerConfig.direction"
      :size="drawerConfig.width">
      <cms-modal-iframe
        :iframe-url="drawerConfig.url"
        :data-id="new Date().getTime()"
      />
    </cms-drawer>
    <vxe-grid
      ref="tableRef"
      v-bind="$attrs"
      v-on="listeners"
      @dblclick="cellDblClick"
      :columns="columns"
      :loading="loading && partialLoading"
      :height="tableHeight"
      :menu-config="menuConfig"
      :valid-config="validConfig"
      :keyboard-config="keyboardConfig"
      :custom-config="customConfig"
      :mouse-config="mouseConfig"
      :show-overflow="showOverflow"
      :scroll-y="{mode: 'wheel'}"
      :toolbar-config="toolsBar ? (toolsBar.length > 0 || showRightToolbar ? toolsBarConfig : false) : false"
      :checkbox-config="Object.assign({}, {
        highlight: true,
        checkMethod: defaultCheckMethod
      }, checkboxConfig || {})"
      :row-config="Object.assign({
        useKey: false,
        keyField: 'id',
        isCurrent: true,
        isHover: true,
      }, rowConfig || {})"
    >
      <template v-slot:form v-if="showSearchForm">
        <el-card class="box-card"  v-if="formItemConfig.length > 0">
          <cms-query-form-condition
            ref="queryFormRef"
            :disabled="disabled"
            :query-params="defaultQueryForm"
            :query-rules="queryRules"
            :label-width="labelWidth"
            :items="items"
            :dictionary-config="dictionaryConfigArray"
            :constants="constantsModel"
            :item-column="itemColumn"
            :extend-template-fields="extendTemplateFieldList"
            @calculateTableHeight="calculateTableHeight"
            @search="searchTable"
            @reset="resetClick">
            <template v-for="(item) in items" :slot="item.prop">
              <slot :name="item.prop"></slot>
            </template>
          </cms-query-form-condition>
        </el-card>
      </template>
      <template v-slot:buttons>
        <cms-button-group v-if="toolsBar">
          <cms-button
            size="small"
            v-for="item in toolsBar"
            v-permission-button="[item.access]"
            @click="item.onClick"
            :disabled="item.disabled || viewVisible"
            :key="item.title"
            :type="item.status">
            <i v-if="item['customIcon']" :class="'icon ' + item.icon" style="font-size: 13px;margin-right: 7px"></i>
            <i v-else :class="item.icon"></i>
            {{ item.title }}
          </cms-button>
          <slot name="buttons"></slot>
        </cms-button-group>
      </template>
      <template v-slot:tools>
        <cms-button-group v-if="showRightToolbar">
          <el-tooltip class="item" effect="dark" content="打印表格" placement="top">
            <cms-link size="small" :underline="false">
              <i class="el-icon-printer"></i>
            </cms-link>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="导出表格" placement="top">
            <cms-link size="small" :underline="false" @click="openExportEvent">
              <i class="el-icon-download"></i>
            </cms-link>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="表格设置" placement="top">
            <cms-link size="mini" @click="visibleColumnConfig = true" :underline="false">
              <i class="el-icon-setting"></i>
            </cms-link>
          </el-tooltip>
        </cms-button-group>
      </template>
      <template v-slot:pager v-if="pagination">
        <vxe-pager
          @page-change="pageChange"
          :auto-hidden="false"
          :current-page.sync="tablePage.currentPage"
          :perfect="true"
          :page-size.sync="tablePage.limit"
          :total="tablePage.total"
          :layouts="layouts ? layouts : [ 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total' ]"
        />
      </template>
      <template v-slot:empty>
        <slot name="empty">
          <div>
            {{ $t("common.message.emptyText") }}
          </div>
        </slot>
      </template>
      <template v-slot:top>
        <slot name="top"></slot>
      </template>
      <template v-slot:bottom>
        <slot name="bottom"></slot>
      </template>
    </vxe-grid>
    <cms-column-config
      v-if="visibleColumnConfig"
      v-model="visibleColumnConfig"
      @onCancel="closeModalCallback"
      :finish-callback="finishCallback"
      :columns="tableConfigColumnList"
    />
  </div>
</template>

<script>
import { rootNav } from "@/comps/mixin/routerNavTools";
import { mixTableConfig, mixTableConstants } from "../mixin/common-mixins";
import CmsColumnConfig from "./CmsColumnConfig";
import HttpService from "@/utils/HttpService";

export default {
  name: "CmsQueryTable",
  components: { CmsColumnConfig },
  mixins: [ rootNav, mixTableConstants ],
  data() {
    return {
      tableHeight: '400px',
      defaultQueryForm: { ...this.queryParams, extendMap: undefined },
      visibleColumnConfig: false,
      extendTemplateFieldList: [],
      toolsBarConfig: {
        size: "small",
        perfect: true,
        slots: {
          buttons: "buttons",
          tools: "tools",
        },
      },
      items: [],
      itemColumn: undefined,
      // 初始化表格配置参数
      tableConfigColumnList: [],
    };
  },
  inject: {
    CmsPageForm: {
      default: undefined
    }
  },
  provide() {
    return {
      $routerView: this
    }
  },
  async activated() {
    await this.initTableConfig();
  },
  watch: {
    requestCall: {
      handler(val) {
        if (Array.isArray(val)) {
          if (this.$refs["tableRef"]) this.$refs["tableRef"].loadData(val);
        }
      },
      immediate: true,
      deep: true,
    },
  },
  methods: {
    async initTableConfig() {
      // 获取扩展字段
      const config = this.extendTemplateConfig;
      if (config && config.enable && config.dataSource) {
        const newVar = { funCode: config.funCode, operationType: config.operationType };
        const { code, data } = await HttpService.post(config.dataSource, newVar);
        if (code === 200) {
          const columnList = this.columns;
          if (data && data.length > 0) {
            console.log('---------------data： ', data)
            let opts = undefined;
            this.extendTemplateFieldList = data;
            for (let i = 0; i < this.columns.length; i++) {
              if (this.columns.hasOwnProperty(i)) {
                const row = this.columns[i];
                if (row.field === 'opts') {
                  opts = row;
                  for (let dataKey in data) {
                    if (data.hasOwnProperty(dataKey)) {
                      const row = data[dataKey];
                      columnList.splice(i - 1 + parseInt(dataKey), 1, {
                        ...mixTableConfig.default,
                        title: row.fieldName,
                        field: row.fieldKey,
                        slots: {
                          default: ({ row, column }) => {
                            if (row.extendMap) {
                              return row.extendMap[column.property]
                            } else {
                              return row[column.property];
                            }
                          }
                        }
                      })
                    }
                  }
                  columnList.push(opts);
                  setTimeout(async() => {
                    await this.initColumns();
                    await this.initTableData();
                    this.$refs.tableRef.reloadColumn(columnList);
                    this.$refs.tableRef.loadColumn(columnList);
                  }, 300);
                  break;
                }
              }
            }
            const fields = this.extendTemplateFieldList;
            for (let index in fields) {
              if (fields.hasOwnProperty(index)) {
                const row = fields[index];
                this.$set(this.defaultQueryForm, row['fieldKey'], undefined);
              }
            }
          }
        } else {
          // this.$message.error(msg);
          this.$refs.tableRef.reloadColumn(this.columns);
        }
      } else {
        this.$refs.tableRef.reloadColumn(this.columns);
        await this.initColumns();
        await this.initTableData();
      }
    },
    async initColumns() {
      const columns = this.columns;
      for (let col of columns) {
        if (!col.align) {
          col.align = 'left'
        }
        this.tableConfigColumnList.push(col);
      }
      if (this.tableConfig.enable) {
        const params = { tableCode: this.tableCode };
        const res = await this.tableConfig.queryConfigUrl({ ...params });
        if (res && res['code'] === 200) {
          console.log('-----------', res);
        }
      }
    },
    defaultCheckMethod(params) {
      if (this.CmsPageForm) {
        return this.viewVisible;
      }
      if (this.checkMethod) {
        return this.checkMethod(params);
      }
      const row = params.row;
      return row['approvalStatus'] !== 4;
    },
    /**
     * 导出操作
     */
    openExportEvent() {
      const cols = []
      this.columns.forEach(item => {
        if (item.field !== 'opts' && item.field !== 'checkbox' && item.field !== 'radio') {
          cols.push(item)
        }
      })
      this.$refs.tableRef.openExport({
        columns: cols,
      })
    },
    searchTable() {
      this.getExtendMapQueryParams();
      if (this.searchMethod) {
        this.searchMethod()
      }
    },
    setTableData(data = []) {
      this.$refs["tableRef"].loadData(data);
    },
    // 搜索添加验证
    validate(callback) {
      this.$refs.queryFormRef.validate(valid => {
        if (callback) callback(valid);
        return false;
      })
    },
    async initTableData() {
      this.$forceUpdate();
      if (!Array.isArray(this.formItemConfig)) {
        this.items = this.formItemConfig.items;
        this.itemColumn = this.formItemConfig.column;
      } else {
        this.items = this.formItemConfig;
      }
      if (this.constantLoad && typeof this.constantLoad === 'function') {
        await this.constantLoad({});
        if (this.initLoadTableData) {
          await this.loadTableData();
        }
      } else {
        if (this.initLoadTableData) {
          await this.loadTableData();
        }
      }
    },
    resetClick() {
      for (const key in this.defaultQueryForm) {
        if (this.defaultQueryForm.hasOwnProperty(key)) {
          this.defaultQueryForm[key] = undefined
        }
      }
      this.$emit('resetClick')
    },
    /**
     * 初始化加载表格
     */
    async loadTableData() {
      if (!this.requestCall) {
        this.$messageTips.warning("请求地址不存在，请检查配置.");
        return false;
      }
      this.loading = true
      if (typeof this.requestCall === "function") {
        if (this.pagination) {
          this.defaultQueryForm.rows = this.tablePage.pageSize;
          this.defaultQueryForm.page = this.tablePage.currentPage;
        }
        this.defaultQueryForm = Object.assign({}, { ...this.defaultQueryForm }, { ...this.queryParams })
        const config = { loading: !this.partialLoading };
        const response = await this.requestCall({ ...this.defaultQueryForm }, { ...config });
        if (this.pagination && this.$refs["tableRef"] && response) {
          const { rows, total, extraMap, code } = response;
          if (code === 200) {
            this.tablePage.total = total;
            if (this.resultCallback) {
              const resultCallback = this.resultCallback(rows, extraMap);
              this.$refs["tableRef"].loadData(resultCallback ? resultCallback : rows);
            } else {
              this.$refs["tableRef"].loadData(rows);
            }
            setTimeout(() => {
              delete this.defaultQueryForm.extendMap
              this.loading = false;
            }, 300);
          } else {
            this.loading = false
            this.$messageTips.error(response.msg);
          }
        } else {
          if (this.$refs["tableRef"] && response) {
            const { data, extraMap } = response;
            if (this.resultCallback) {
              const resultCallback = this.resultCallback(data, extraMap);
              this.$refs["tableRef"].loadData(resultCallback ? resultCallback : data);
            } else {
              this.$refs["tableRef"].loadData(data);
            }
          }
          setTimeout(() => {
            this.loading = false;
          }, 300);
        }
      } else if (Array.isArray(this.requestCall)) {
        if (this.$refs["tableRef"]) {
          this.$refs["tableRef"].loadData(this.requestCall);
        }
        setTimeout(() => {
          this.loading = false;
        }, 300);
      } else if (typeof this.requestCall == "object") {
        if (this.pagination && this.$refs["tableRef"]) {
          const { rows, total, extraMap } = this.requestCall;
          if (this.resultCallback) {
            const resultCallback = this.resultCallback(rows, extraMap);
            this.$refs["tableRef"].loadData(resultCallback ? resultCallback : rows);
          } else {
            this.$refs["tableRef"].loadData(rows);
          }
          this.tablePage.total = total;
        } else {
          this.tableData = this.requestCall;
        }
        setTimeout(() => {
          this.loading = false;
        }, 300);
      } else if (typeof this.requestCall == "string") {
        if (this.pagination) {
          this.defaultQueryForm.rows = this.tablePage.pageSize;
          this.defaultQueryForm.page = this.tablePage.currentPage;
        }
        const config = { loading: !this.partialLoading };
        const response = await HttpService.page(this.requestCall, { ...this.defaultQueryForm }, config);
        if (this.pagination && this.$refs["tableRef"] && response) {
          const { rows, total, extraMap, code } = response;
          if (code === 200) {
            this.tablePage.total = total;
            if (this.resultCallback) {
              const resultCallback = this.resultCallback(rows, extraMap);
              this.$refs["tableRef"].loadData(resultCallback ? resultCallback : rows);
            } else {
              this.$refs["tableRef"].loadData(rows);
            }
            setTimeout(() => {
              this.loading = false;
              delete this.defaultQueryForm.extendMap
            }, 300);
          } else {
            this.loading = false
            this.$messageTips.error(response.msg);
          }
        } else {
          if (this.$refs["tableRef"] && response) {
            const { data, extraMap } = response;
            if (this.resultCallback) {
              const resultCallback = this.resultCallback(data, extraMap);
              this.$refs["tableRef"].loadData(resultCallback ? resultCallback : data);
            } else {
              this.$refs["tableRef"].loadData(data);
            }
          }
          setTimeout(() => {
            this.loading = false;
          }, 300);
        }
      }
    },
    getCheckboxRecords() {
      return this.$refs["tableRef"].getCheckboxRecords();
    },
    /**获取扩展模板查询参数*/
    getExtendMapQueryParams() {
      const config = this.extendTemplateConfig;
      if (config && config.enable && this.extendTemplateFieldList.length > 0) {
        const fieldKeyList = [];
        this.extendTemplateFieldList.forEach(row => fieldKeyList.push(row.fieldKey));
        const extendMap = {};
        fieldKeyList.forEach(fieldKey => {
          Object.keys(this.defaultQueryForm).forEach(newFieldKey => {
            if (fieldKey === newFieldKey) {
              extendMap[[ fieldKey ]] = this.defaultQueryForm[fieldKey];
            }
          })
        })
        this.$set(this.defaultQueryForm, 'extendMap', extendMap);
      }
    },
    reload() {
      this.getExtendMapQueryParams();
      this.loadTableData();
    },
    pageChange({ type, currentPage, pageSize }) {
      if (type === "size") {
        this.tablePage.currentPage = 1;
        this.tablePage.pageSize = pageSize;
      } else {
        this.tablePage.currentPage = currentPage;
      }
      this.loadTableData();
    },
    currentChange(event) {
      this.$emit("current-change", event);
    },
    filterMethod({ value, row, column }) {
      console.log(value, row, column);
    },
    cellDblClick(data) {
      this.$emit("cell-dblclick", data);
    },
    // finishCallback 配置完成进行重新加载， 并且保存到数据库
    finishCallback(columns) {
      if (this.tableConfig.enable) {
        const params = { tableCode: this.tableCode, tableTitle: this.tableTitle };
        this.tableConfig.saveConfigUrl({ ...params }).then(res => {
          if (res.code === 200) {
            this.$messageTips.success(res.msg);
            this.visibleColumnConfig = false;
            this.$refs['tableRef'].reloadColumn(columns);
          }
        })
      }
    },
    closeModalCallback(visible) {
      this.visibleColumnConfig = visible;
    },
    calculateTableHeight(formHeight, collapse) {
      if (collapse) {
        this.tableHeight = this.$refs.cmsTableList.clientHeight - formHeight;
      } else {
        this.initResizeTable();
      }
    },
    initResizeTable() {
      if (!this.fixedHeight) {
        const h = window.document.body.clientHeight;
        if (h < 800) {
          this.tableHeight = h - this.marginTop - 2;
        } else {
          this.tableHeight = (h - this.marginTop - 10);
        }
      }
    },
  },
  computed: {
    viewVisible() {
      if (!this.CmsPageForm) {
        return false;
      }
      return this.CmsPageForm && (this.CmsPageForm.formType === 'view' || this.CmsPageForm.formType === 'approval')
    }
  },
  beforeDestroy() {
    document.body.removeEventListener('resize', this.initResizeTable);
    window.removeEventListener('resize', this.initResizeTable);
  },
  async mounted() {
    if (this.fixedHeight) {
      this.tableHeight = this.height;
    }
    document.body.addEventListener('resize', this.initResizeTable, false);
    window.addEventListener('resize', this.initResizeTable, false);
    setTimeout(this.initResizeTable, 40);
    await this.initTableConfig();
  },
  props: {
    columns: {
      type: Array,
      default: () => {
        return []
      },
    },
    layouts: Array,
    tableConfig: {
      type: Object,
      default: () => {
        return {
          enable: false,  // 是否启用表格配置
          saveConfigUrl: Function, // 保存表格配置信息的地址
          queryConfigUrl: Function, // 查询表格配置信息的地址
        }
      }
    }
  }
};
</script>

<style scoped lang="scss">
.el-card__body {
  padding: 0 !important;
}

.el-card__header {
  padding: 10px;
  background: #f8f8f9 !important;

  .clearfix {
    span {
      i {
        margin-right: 5px;
      }
    }
  }
}

.cms-form .r-main {
  padding: 0;
}

.cms-form .r-bottom {
  line-height: 55px;
  height: 45px;
  padding: 0 !important;
}

.vxe-toolbar .vxe-buttons--wrapper {
  -webkit-box-flex: 1;
  flex-grow: 1;
  padding-left: 5px;
  padding-right: 5px;
}

.cms-search-container {
  display: flex;
  width: 100%;
  padding-right: 5px;
  flex-direction: row;

  .cms-search-form {
    flex: 1;
  }

  .cms-search-tools {
    width: auto;
    margin-top: 10px;
  }
}

.toolbar-tools {
  display: flex;
  flex-direction: row;

  .toolbar-tools-left {
    flex: 1;
  }

  .toolbar-tools-right {
    width: auto;
  }
}

.el-popover__reference-wrapper {
  a:hover {
    text-decoration: none;
  }
}

.el-button-group {
  .el-button {
    padding: 8px !important;
  }
}

.vxe-tools--wrapper {
  .el-link {
    .el-link--inner {
      padding: 0 !important;
    }
  }
}
</style>
