<!--
 * @Description: In User Settings Edit
 * @Author: your name
 * @Date: 2018-08-13 20:18:10
 * @LastEditTime: 2019-11-25 14:07:06
 * @LastEditors: Please set LastEditors
 -->
<template>
  <div class="zte-table" :class="'zte-table--' + size" ref="zteTable">
    <div class="search-body" v-if="searchInfo.length">
      <el-form
        ref="searchForm"
        :size="size"
        :model="searchForm"
        :rules="currentRules"
        :label-width="labelWidth * (isCn ? 1 : 1.5) + 'px'"
        @submit.native.prevent
      >
        <transition
          name="search-info-transition"
          enter-active-class="animated fadeIn"
          leave-active-class="animated fadeOut"
          v-for="(info, index) of searchInfo"
          :key="info.code">
          <el-form-item
            v-if="info.show !== false"
            v-show="searchExpend || expendAll ? index < searchInfo.length : index < expendSize"
            :class="info.code"
            :style="'width: ' + widthPercent * (info.grow || 1) + '%;margin-top:' + errorSize"
            :label="$t(info.label)"
            :prop="info.code">
            <zte-item v-if="!info.range"
              :props="info"
              v-model="searchForm[info.code]"
              :show="searchForm[info.showLabel]"
              :params="Object.assign({}, info.params, preParams[info.code])"
              @select-change="handlerSelectChange($event, info)"
              @show-change="showChange"
              @single-picker-change="pickerChange($event, info)"
              @tree-pick-change="treeChange"
              @enter="submitForm"
              @range-change="handlerRangeChange($event, info)"
            />
            <zte-item-range v-else
              :props="info"
              :form="searchForm"
              :same="info.same"
            />
          </el-form-item>
        </transition>
        <!-- 隐藏域input解决浏览器默认提交bug -->
        <!-- <input type="text" style="display: none" v-if="searchInfo.filter(i => i.show !== false).length === 1"> -->
        <el-form-item v-if="!cancelSearch" class="button-list" :style="'width: ' + widthPercent + '%;'">
          <el-button type="primary" @click.native="submitForm" icon="el-icon-search">{{$t('查询')}}</el-button>
          <el-button @click.native="resetForm" icon="el-icon-refresh">{{$t('重置')}}</el-button>
        </el-form-item>
      </el-form>
      <div class="more" v-if="seachIsMore && !expendAll" @click="searchExpend = !searchExpend">
        <i class="icon el-icon-arrow-up" v-if="searchExpend"></i>
        <i class="icon el-icon-arrow-down" v-else></i>
      </div>
    </div>
    <div class="content-body" v-if="Object.keys(buttonList).length || $scopedSlots.content || $slots.content">
      <el-button
        v-if="buttonList.add"
        :size="size"
        plain
        icon="el-icon-plus"
        @click.native="handlerAddRow">
        {{$t('新增')}}
      </el-button>
      <el-button
        v-if="buttonList.del"
        :size="size"
        plain
        icon="el-icon-minus"
        @click.native="debounceDelete">
        {{$t('删除')}}
      </el-button>
      <Throttle :time="1000" events="click" v-if="buttonList.enable">
        <el-button
          :size="size"
          plain
          @click.native="handlerSwitch('enable')">
          {{$t('启用')}}
        </el-button>
      </Throttle>
      <Throttle :time="1000" events="click" v-if="buttonList.disable">
        <el-button
          :size="size"
          plain
          @click.native="handlerSwitch('disable')">
          {{$t('禁用')}}
        </el-button>
      </Throttle>
      <slot name="content" :rows="selectionRows"></slot>
      <Throttle :time="1000" events="click" v-if="buttonList.downTemp">
        <el-button
          :size="size"
          icon="el-icon-downtemp"
          @click.native="handlerDownTemp">
          {{$t('下载模板')}}
        </el-button>
      </Throttle>
      <el-upload
        v-if="buttonList.upload"
        ref="upload"
        :action="uploadFullUrl"
        :onError="handleUploadError"
        :beforeUpload="handleBeforeUpload"
        :onSuccess="handleUploadSuccess"
        :fileList="fileList"
        :data="params"
        style="display: inline-block;margin-left:10px;margin-right:10px;"
        :limit="uploadLimit"
        :show-file-list="false">
        <el-button
          :size="size"
          plain
          icon="el-icon-impordata"
          @click="upload"
          :loading="importLoading">
          {{$t('导入模板')}}
        </el-button>
      </el-upload>
      <Throttle :time="1000" events="click" v-if="buttonList.export">
        <el-button
          :size="size"
          plain
          icon="el-icon-export"
          @click.native="handlerExport">
          {{$t('导出')}}
        </el-button>
      </Throttle>
    </div>
    <div class="table-body">
      <ul
        v-if="isLazy"
        class="infinite-list"
        v-infinite-scroll="getLazyTableData"
        :infinite-scroll-distance="200"
        :infinite-scroll-delay="300"
        :infinite-scroll-immediate="false"
        :infinite-scroll-disabled="lazyFinshed"
      >
        <li
          v-for="(row, index) in tableData"
          :key="index"
          class="infinite-list-item"
        >
          <slot name="item" :row="row" :$index="index"></slot>
        </li>
      </ul>
      <el-table
        v-else-if="tableColumn.length"
        v-loading="loading"
        element-loading-text="加载中"
        element-loading-spinner="el-icon-loading"
        header-cell-class-name="table-head-cell"
        highlight-current-row
        ref="table"
        :size="size"
        :data="tableData"
        :stripe="!tableRowClassName"
        :span-method="arraySpanMethod"
        :height="height || autoHeight"
        :max-height="1000"
        :row-key="rowKey"
        :border="border"
        :resizable="resizable"
        :expand-row-keys="expandRowKeys"
        :row-class-name="tableRowClassName"
        v-bind="$attrs"
        v-on="$listeners"
        @current-change="handlerRowSelect"
        @row-click="hanlerRowClick"
        @row-dblclick="handleDBclick"
        @cell-click="handleCellclick"
        @cell-dblclick="handleCellDblclick"
        @selection-change="handlerRowCheck"
        @select="handleSelectionCheck"
        @select-all="handleSelectionCheckAll"
        @sort-change="handlerSortChange">
        <el-table-column
          v-if="currentIndex === 'selection'"
          type="selection"
          :selectable="selectable"
          :reserve-selection='!!rowKey'
          :fixed='hasFixedLeft || selectionFixed'
          width="55">
        </el-table-column>
        <el-table-column
          :label="$t('序号')"
          type="index"
          :fixed="hasFixedLeft"
          width="55"
        >
        </el-table-column>
        <el-table-column
          type="expand"
          v-if="$scopedSlots.expand"
        >
          <template slot-scope="scope">
            <slot name="expand" :row="scope.row" :$index="scope.$index"></slot>
          </template>
        </el-table-column>
        <template v-for="column of tableColumn">
          <template  v-if="column.show !== false">
            <el-table-column
              v-if="column.temp"
              :key="column.code"
              :class-name="column.code + '-temp'"
              :prop="column.code"
              :label="$t(column.label)"
              :min-width="column.width || computeColumnWidth(column)"
              :fixed="column.fixed"
              :show-overflow-tooltip="column.tips"
              :sortable="isSortable && column.sort && 'custom'"
            >
              <template slot-scope="{row, $index, column: col}">
                <el-button
                  v-if="buttonList.edit && column.temp === 'operate'"
                  :size="size"
                  type="text"
                  :disabled="!!(editDisabled && editDisabled(row))"
                  @click.native.stop="handlerEdit(row, $index, col)">
                  {{$t('编辑')}}
                </el-button>

                <!-- 复制功能 -->
                <el-tooltip effect="light" v-if="column.copy" :visible-arrow="false" popper-class="tooltip-copy" placement="right">
                  <div slot="content" >
                    <el-button @click.native="copy(row[column.code])" size="mini">{{ $t('复制') }}</el-button>
                  </div>
                  <slot
                    class="column-temp"
                    :name="column.code"
                    :row="row"
                    :column="col"
                    :$index="$index">
                  </slot>
                </el-tooltip>

                <slot
                  v-else
                  class="column-temp"
                  :name="column.code"
                  :row="row"
                  :column="col"
                  :$index="$index">
                </slot>
              </template>
            </el-table-column>
            <el-table-column
              v-else-if="column.isAmount"
              :key="column.code"
              :class-name="`${column.code} amount`"
              :prop="column.code"
              :label="$t(column.label)"
              :min-width="column.width || computeColumnWidth(column)"
              :fixed="column.fixed"
              :show-overflow-tooltip="column.tips"
              :sortable="isSortable && column.sort && 'custom'"
            >
              <template slot-scope="{ row }">
                {{ row[column.code] | fmoney }}
              </template>
            </el-table-column>
            <el-table-column
              v-else
              v-show="column.show !== false"
              :key="column.code"
              :class-name="column.code"
              :prop="column.code"
              :label="$t(column.label)"
              :min-width="column.width || computeColumnWidth(column)"
              :fixed="column.fixed"
              :show-overflow-tooltip="column.tips"
              :sortable="isSortable && column.sort && 'custom'"
            >
            </el-table-column>
          </template>
        </template>
        <el-table-column
          v-if="buttonList.edit && !$scopedSlots.operate"
          class-name="operate-temp"
          prop="operate"
          :label="$t('操作')"
          width="100"
          fixed="right">
          <template slot-scope="{row, $index, column}">
            <el-button
              :size="size"
              type="text"
              :disabled="!!(editDisabled && editDisabled(row))"
              @click.native.stop="handlerEdit(row, $index, column)">
              {{$t('编辑')}}
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <template v-else>
        <div class="table-data" v-loading="loading">
          <slot :data="tableData"></slot>
        </div>
      </template>
    </div>
    <div class="bottom-body" v-if="!isLazy">
      <template v-if="$slots.pageExtend">
        <slot name="pageExtend" />
      </template>
      <el-pagination
        v-if="isPagination"
        background
        :layout="layout"
        :current-page="pageNum"
        :page-size="currentPageSize"
        :page-sizes="pageSizes"
        :total="totalSize"
        @size-change="handlerSizeChange"
        @current-change="handlerPageChange">
      </el-pagination>
    </div>
    <div v-if="buttonList && buttonList.export && (exportUrl || exportTitle)" v-show="false">
      <form :action="exportFullUrl" method="post">
        <input type="text" v-for="key of Object.keys(exportData)"
          :key="key"
          :name="key"
          :value="exportData[key]"
        />
        <input ref="submit" type="submit" value="提交">
      </form>
    </div>
    <div v-if="buttonList && buttonList.downTemp && downloadUrl" v-show="false">
      <form :action="downloadFullUrl" method="post">
        <input type="text" v-for="key of Object.keys(downloadData)"
          :key="key"
          :name="key"
          :value="downloadData[key]"
        />
        <input ref="download" type="submit" value="提交">
      </form>
    </div>
  </div>
</template>

<script>
import qs from 'qs';
import debounce from 'throttle-debounce/debounce';
import zteItem from './zte-item';
import zteItemRange from './zte-item-range';
import fmoney from './es/formatMoney';
import concatUrl from './es/concatUrl';
import selection from './mixins/selection';

export default {
  name: 'zteTable',
  components: {
    zteItem,
    zteItemRange,
  },
  mixins: [selection],
  props: {
    searchInfo: {
      type: Array,
      default: () => ([]),
    },
    expendAll: {
      type: Boolean,
      default: false,
    },
    rules: {
      type: Object,
      default: () => ({}),
    },
    tableColumn: {
      type: Array,
      default: () => ([]),
    },
    requestUrl: {
      type: String,
      required: true,
    },
    exportUrl: String,
    exportTitle: String,
    uploadUrl: String,
    downloadUrl: String,
    downloadData: Object,
    uploadFileType: {
      type: Array,
      default: () => (['.xlsx', '.xls']),
    },
    uploadLimit: {
      type: Number,
      default: 1,
    },
    params: {
      type: Object,
      default: () => ({}),
    },
    autoSearch: {
      type: Boolean,
      default: true,
    },
    indexStyle: {
      type: String,
      default: 'index',
    },
    border: {
      type: Boolean,
      default: true,
    },
    resizable: {
      type: Boolean,
      default: true,
    },
    rowKey: {
      type: [String, Function],
    },
    selectionFixed: {
      type: Boolean,
      default: true,
    },
    checkedRow: {
      type: Array,
      default: () => ([]),
    },
    labelWidth: {
      type: Number,
      default: 100,
    },
    rowSize: {
      type: Number,
      default: 4,
    },
    pageSize: {
      type: Number,
      default: 10,
    },
    pageSizes: {
      type: Array,
      default: () => ([10, 20, 30, 40]),
    },
    isPagination: {
      type: Boolean,
      default: true,
    },
    isSortable: {
      type: Boolean,
      default: true,
    },
    buttonList: {
      type: Object,
      default: () => ({}),
    },
    height: {
      type: [Number, String],
    },
    clickToCheck: {
      type: Boolean,
      default: true,
    },
    cancelSearch: {
      type: Boolean,
      default: false,
    },
    expandAfterSearch: {
      type: Boolean,
      default: false,
    },
    deleteCheck: Function,
    selectable: Function,
    editDisabled: Function,
    tableRowClassName: Function,
    layout: {
      type:String,
      default: 'total, sizes, prev, pager, next',
    },
    size: {
      type:String,
      default: 'small',
    },
    subCode: String,
    isLazy: Boolean,
    lazyCode: {
      type: String,
      default: 'scrollId',
    },
  },
  filters: {
    fmoney,
  },
  data() {
    return {
      tableData: [],
      totalSize: 0,
      searchForm: {},
      searchExpend: false,
      pageNum: 1,
      currentPageSize: this.pageSize,
      orderField: '',
      order: '',
      defaultRow: 1,
      selectionRows: [],
      expandRowKeys: null,
      exportBaseUrl: '/sys/file/download',
      loading: false,
      importLoading: false,
      fileList: [],
      autoHeight: null,
      scrollId: '',
      lazyFinshed: false,
    };
  },
  computed: {
    // 是否有fixed: left的列
    hasFixedLeft() {
      const fixedLeft = this.tableColumn.filter(col => ['left', true].includes(col.fixed));
      const hasFixedLeft = !!(fixedLeft && fixedLeft.length)
      return hasFixedLeft;
    },
    // 合并单元格的对象，{key: value}， key:需要合并的列， value：合并行的时候依赖的值的Code。
    rowSpanObj() {
      const obj = {};
      this.tableColumn.forEach(item => {
        if (item.rowSpan) {
          obj[item.code] = item.refSpanCode ? item.refSpanCode : item.code;
        }
      });
      return obj;
    },
    searchObj() {
      const { currentPageSize, pageNum, orderField, order } = this;
      const searchObj = Object.assign({
        page: pageNum,
        limit: currentPageSize,
        orderField,
        order,
      }, this.searchForm);
      return searchObj;
    },
    errorSize() {
      let size = '0px';
      if (this.searchInfo && this.searchInfo.findIndex(item => item.required) > -1) size = '9px';
      return size;
    },
    preParams() {
      const params = {};
      for (const info of this.searchInfo) {
        if (info.prev && Object.keys(info.prev).length) {
          params[info.code] = {};
          for (const key of Object.keys(info.prev)) {
            params[info.code][info.prev[key]] = this.searchForm[key] || '';
          }
        }
      }
      return params;
    },
    currentRules() {
      const rules = {};
      const inputList = ['text', 'num', 'textarea'];
      this.searchInfo.forEach((info) => {
        const rule = this.rules[info.code] || [];
        if (info.required) {
          const message = (inputList.indexOf(info.type) > -1 ? this.$t('请输入') : this.$t('请选择')) + this.$t(info.label);
          rule.push({
            type: info.dataType || 'string',
            required: true,
            message,
            trigger: ['blur', 'change'],
          });
        }
        if (rule.length) {
          rules[info.code] = rule;
        }
      });
      if (this.$refs.searchForm) {
        this.$nextTick(() => {
          this.$refs.searchForm.clearValidate();
        })
      }
      return rules;
    },
    widthPercent() {
      return (100 / this.rowSize).toFixed(2);
    },
    expendSize() {
      return this.rowSize * this.defaultRow - 1;
    },
    seachIsMore() {
      return this.searchInfo.filter(item => item.show !== false).length > this.expendSize;
    },
    isCn() {
      return this.$i18n.locale === 'zh-CN';
    },
    currentIndex() {
      let indexStyle = this.indexStyle;
      if (this.buttonList && (
        this.buttonList.del ||
        this.buttonList.enable ||
        this.buttonList.disable
      )) {
        indexStyle = 'selection';
      }
      return indexStyle;
    },
    exportFullUrl() {
      if (this.exportUrl) {
        return concatUrl(this.$http.defaults.baseURL, this.exportUrl);
      } else if (this.exportTitle) {
        const exportUrl = `${this.service}/common/export/exportExcel`;
        return concatUrl(this.$http.defaults.baseURL, exportUrl);
      }
      return '';
    },
    downloadFullUrl() {
      if (this.downloadUrl) {
        return concatUrl(this.$http.defaults.baseURL, this.downloadUrl);
      }
      return '';
    },
    uploadFullUrl() {
      if (this.uploadUrl) {
        return concatUrl(this.$http.defaults.baseURL, this.uploadUrl);
      }
      return '';
    },
    // 导出参数
    exportData() {
      let exportObj = {};
      if (this.exportTitle) {
        exportObj = {
          url: this.requestUrl,
          title: this.exportTitle,
        };
      }
      // 去除操作列
      const exportColumn=this.tableColumn.filter(item=>item.code !== 'operate')
      const fieldList = {};
      fieldList[`${this.exportTitle ? 'columnTitles': 'colName'}`] = exportColumn.map(col => col.label).join(',');
      fieldList[`${this.exportTitle ? 'columnFields': 'colField'}`] = exportColumn.map(col => col.code).join(',');

      const exportData = Object.assign(
        exportObj,
        fieldList,
        this.searchObj,
        this.params,
        // {
        //   colField: this.tableColumn.map(col => col.code).join(','),
        //   colName: this.tableColumn.map(col => col.label).join(','),
        // },
      );
      return exportData;
    },
    service() {
      const service = this.requestUrl.split('/')[0];
      return service;
    },
  },
  watch: {
    'tableData.length': {
      handler() {
        this.doTableLayout();
      }
    },
    tableData(val) {
      if (this.indexStyle === 'selection' && !!this.rowKey) {
        // 当表格数据重载时，需要将记忆的选中回填
        this.$refs.table.clearSelection();
        if (this.checkedRow.length) {
          for (const newrow of val) {
            if (this.indexOfRowKey(this.checkedRow, newrow) >= 0) {
              this.$refs.table.toggleRowSelection(newrow);
            }
          }
        }
      } else if (this.rowKey) {
        // 当有checkedRow且长度为1的时候,有rowKey传入则视为单选表格
        if (this.checkedRow.length === 1) {
          const singleIndex = this.indexOfRowKey(val, this.checkedRow[0]);
          if (singleIndex >= 0) {
            this.$nextTick(() => {
              this.$refs.table.setCurrentRow(val[singleIndex]);
            });
          }
        }
      }
    },
    checkedRow() {
      this.$refs.table.clearSelection();
      if (this.checkedRow.length) {
        for (const newrow of this.tableData) {
          if (this.indexOfRowKey(this.checkedRow, newrow) >= 0) {
            this.$refs.table.toggleRowSelection(newrow);
          }
        }
      }
    },
    pageSize() {
      this.currentPageSize = this.pageSize;
      this.getTableData();
    },
    params: {
      deep: true,
      handler() {
        this.pageNum = 1;
        this.getTableData();
      },
    },
  },
  created() {
    this.initForm();
    this.initSelectOptions();
    this.debounceDelete = debounce(300, () => {
      this.handlerDeleteRow();
    });
  },
  mounted() {
    if (this.autoSearch) {
      this.getTableData();
      this.$emit('search', this.searchObj);
    }
    // 将content插槽中的所有按钮按照size属性统一大小
    const content = this.$refs.zteTable && this.$refs.zteTable.getElementsByClassName('content-body');
    if (this.size && content && content[0]) {
      const buttons = content[0].getElementsByClassName('el-button');
      if (buttons && buttons.length) {
        Array(buttons.length).fill('').forEach((item, index) => {
          const button = buttons[index];
          if (!button.className.includes(`el-button--${this.size}`)) {
            button.className += ` el-button--${this.size}`;
          }
        });
      }
    }
    this.debounceGetTableHeight = debounce(300, () => {
      this.getTableHeight();
    });
    window.addEventListener('resize', this.debounceGetTableHeight);
  },
  destroyed () {
    window.removeEventListener('resize', this.debounceGetTableHeight);
  },
  methods: {
    getTableData() {
      if (this.isLazy) {
        this.getLazyTableData();
        return;
      }
      this.loading = true;
      this.tableData = [];
      const params = Object.assign({}, this.searchObj, this.params);
      this.$http.post(this.requestUrl, qs.stringify(params)).then(
        (res) => {
          try {
            res = res.data;
            this.$emit('data-loaded',res)
            const list = res.page.list || []
            // 数据存在子对象，则将子对象合并至父级
            this.tableData = list.map(row => {
              if (this.subCode && row[this.subCode] && typeof row[this.subCode] === 'object') {
                Object.assign(row, row[this.subCode]);
              }
              return row;
            });
            this.totalSize = res.page.totalCount;
            this.$emit('total-size', this.totalSize);
            this.getTableHeight();
            this.loading = false;
          } catch (error) {
            this.loading = false;
          }
        },
        () => {
          this.loading = false;
        },
      ).catch();
    },
    getLazyTableData() {
      this.loading = true;
      const params = Object.assign({ [this.lazyCode]: this.scrollId }, this.searchForm, this.params);
      this.$http.post(this.requestUrl, qs.stringify(params))
        .then(
          ({ data }) => {
            const list = data.data || [];
            this.tableData = this.scrollId ? this.tableData.concat(list) : list;
            this.scrollId = list[0] && list[0][this.lazyCode] || '';
          }
        )
        .catch(
          (data) => {
            if (data.type === 'ERROR') {
              this.scrollId = '';
              // this.getLazyTableData();
            }
          }
        )
        .finally(
          () => {
            this.loading = false;
          }
        );
    },
    getTableHeight() {
      if (!this.$refs.table) return;
      const layout = this.$refs.table.layout;
      const height = layout && layout.viewportHeight;
      this.tableData = [].concat(this.tableData);
      this.$nextTick(() => {
        this.autoHeight = height;
        if (typeof this.$refs.table.doLayout === 'function') {
          this.$refs.table.doLayout();
        }
      });
    },
    doTableLayout() {
      this.$nextTick(() => {
        if (this.$refs.table && typeof this.$refs.table.doLayout === 'function') {
          this.$refs.table.doLayout();
        }
      });
    },
    initForm(force) {
      const form = {};
      if(!force){
        this.searchInfo.forEach((info) => {
          if (info.value || info.value === '') {
            form[info.code] = info.value;
          }
          // table 类型默认显示文本值
          if (info.showValue || info.showValue === 0) {
            form[info.showLabel] = info.showValue;
          }
        });
      }
      this.searchForm = form;
    },
    initSelectOptions() {
      this.searchInfo.forEach((info) => {
        this.getOptions(info);
      });
    },
    submitForm() {
      let valiFlag = true;
      if (this.rules) {
        this.$refs.searchForm.validate((valid) => {
          valiFlag = valid;
        });
      }
      if (!valiFlag) {
        return;
      }

      this.pageNum = 1;
      this.scrollId = '';
      this.getTableData();
      this.$emit('search', this.searchObj);
    },
    resetForm() {
      this.initForm(true);
      this.$emit('reset', this.searchObj);
    },
    computeColumnWidth(column) {
      const label = this.$t(column.label);
      const sort = column.sort !== false && this.isSortable;
      const width = this.isCn ? 14 : 10;
      let labelWidth = label.length * width + 20;
      labelWidth += sort ? 24 : 0;
      return labelWidth;
    },
    handlerSizeChange(currentSize) {
      this.currentPageSize = currentSize;
      this.pageNum = 1;
      this.getTableData();
      this.$emit('search', this.searchObj);
    },
    handlerPageChange(currentPage) {
      this.pageNum = currentPage;
      this.getTableData();
      this.$emit('search', this.searchObj);
    },
    handlerSortChange({ column, prop, order }) {
      const config = this.tableColumn.find(item => item.code === prop) || {};
      this.orderField = config.sortCode || prop;
      this.order = order === 'ascending' ? 'asc' : 'desc';
      this.getTableData();
      this.$emit('search', this.searchObj);
    },
    handlerRowSelect(currentRow) {
      this.$emit('row-select', currentRow);
    },
    hanlerRowClick(row) {
      if (this.currentIndex === 'selection' && this.clickToCheck) {
        if (this.selectable && !this.selectable(row)) return;
        this.$refs.table.toggleRowSelection(row);
        this.handleSelectionCheck(this.selectionRows, row);
      }
    },
    handleDBclick(row) {
      this.$emit('dblclick', row);
    },
    handleCellclick(row, column, cell) {
      this.$emit('cell-click', row, column, cell);
    },
    handleCellDblclick(row, column, cell) {
      this.$emit('cell-dblclick', row, column, cell);
    },
    handlerRowCheck(selection) {
      this.selectionRows = selection;
      this.$emit('row-check', selection);
    },
    handlerAddRow() {
      this.$emit('add-row');
    },
    handlerDeleteRow() {
      if (!this.selectionRows.length) {
        this.$message.warning(this.$t('请选择一条数据'));
        return;
      }
      if (this.deleteCheck && !this.deleteCheck(this.selectionRows)) {
        return;
      }
      this.$confirm(this.$t('是否删除'), this.$t('警告'), {
        confirmButtonText: this.$t('确认'),
        cancelButtonText: this.$t('取消'),
        type: 'warning',
      }).then(() => {
        this.$emit('delete-row', this.selectionRows);
      }).catch();
    },
    handlerSwitch(type) {
      if (!this.selectionRows.length) {
        this.$message.warning(this.$t('请选择一条数据'));
        return;
      }
      this.$emit('switch-status', this.selectionRows, type);
    },
    handlerEdit(row, index, column) {
      this.$emit('edit-row', row, index, column);
    },
    handlerExport() {
      this.$emit('export');
      this.$refs.submit.click();
    },
    upload() {
      this.$emit('upload');
    },
    handlerDownTemp() {
      this.$refs.download.click();
    },
    // 处理单行checkbox变更，修改checkedRow
    handleSelectionCheck(selection, row) {
      const rowInSelection = selection.indexOf(row);
      const rowInCheckRows = this.indexOfRowKey(this.checkedRow, row);
      if (rowInSelection > -1) {
        if (rowInCheckRows === -1) {
          this.checkedRow.push(row);
        } else if (rowInCheckRows > -1) {
          this.checkedRow[rowInCheckRows] = row;
        }
      }
      if (rowInSelection === -1 && rowInCheckRows > -1) {
        this.checkedRow.splice(rowInCheckRows, 1);
      }
      this.$emit('checkedChange', this.checkedRow);
    },
    // 处理全选checkbox变更，修改checkedRow
    handleSelectionCheckAll(rows) {
      if (rows.length) {
        for (const row of rows) {
          const index = this.indexOfRowKey(this.checkedRow, row);
          if (index === -1) {
            this.checkedRow.push(row);
          } else if (index > -1) {
            this.checkedRow[index] = row;
          }
        }
      } else {
        for (const row of this.tableData) {
          const index = this.indexOfRowKey(this.checkedRow, row);
          if (index > -1) {
            this.checkedRow.splice(index, 1);
          }
        }
      }
      this.$emit('checkedChange', this.checkedRow);
    },
    // 根据rowkey查询index
    indexOfRowKey(array, row) {
      if (array.indexOf(row) >= 0) {
        return array.indexOf(row);
      }
      for (const temprow of array) {
        if ((typeof this.rowKey === 'string' &&
              temprow[this.rowKey] === row[this.rowKey])
            || (this.rowKey instanceof Function &&
              this.rowKey(temprow) === this.rowKey(row))
        ) {
          return array.indexOf(temprow);
        }
      }
      return -1;
    },
    showChange(showLabel, value) {
      this.searchForm[showLabel] = value;
    },
    pickerChange(row, info) {
      const keys = Object.keys(row);
      keys.forEach((key) => {
        if (this.searchForm[key] !== undefined) {
          this.searchForm[key] = row[key];
        } else {
          this.$set(this.searchForm, key, row[key]);
        }
      });
      this.$emit('picker-change',this.searchForm, info)
    },
    treeChange(showLabel, checked, halfId, halfChecked) {
      this.searchForm[showLabel] = checked;
      this.searchForm[halfId] = halfChecked;
    },
    // [LX-TAG01]一个搜索区有多个range的时候，用searchObj接收值会导致 只有最有输入值的一个range有值
    handlerRangeChange(val, info) {
      if (val && val instanceof Array && info.subCode && info.subCode.length === 2) {
        this.$set(this.searchForm, info.subCode[0], val[0]);
        this.$set(this.searchForm, info.subCode[1], val[1]);
      }
    },
    // 清理上传容器
    handleClearUploadFiles() {
      this.fileList = [];
    },
    // 上传错误处理
    handleUploadError() {
      this.importLoading = false;
      this.$message({
        message: this.$t('数据有误'),
        type: 'warning',
      });
      this.handleClearUploadFiles();
      this.$emit('upload-error');
    },
    handleBeforeUpload(file) {
      const fileType = file.name.slice(file.name.lastIndexOf('.'));
      const validator = this.uploadFileType.includes(fileType);
      if (validator) {
        this.importLoading = true;
      } else {
        this.$message({
          message: this.$t('请上传excel'),
          type: 'warning',
        });
      }
      return validator;
    },
    handleUploadSuccess(res) {
      this.importLoading = false;
      if (res.code !== 0) {
        this.$message({
          dangerouslyUseHTMLString: true,
          message: res.msg,
          type: 'error',
        });
      } else {
        this.$message.success(this.$t('导入成功'));
      }
      this.handleClearUploadFiles();
      this.getTableData();
      this.$emit('upload-success', res);
    },
    // select后置字段，清空及重新请求数据
    handlerSelectChange(val, info) {
      if (info.next && val) {
        for (const code in info.next) {
          const item = this.itemInfo.find(item => item.code === code);
          if (item && item.type === 'select') {
            // const item = this.itemInfo[index];
            const params = {};
            params[info.code] = val;
            this.getOptions(item, params);
            this.currentForm[code] = '';
          } else if (info.next[code]) {
            if (info.multiple) {
              const options = info.options.filter(opt => val.indexOf(opt[info.optionProps.value]) > -1);
              this.currentForm[code] = options.map(opt => opt[info.next[code]]).join(',');
            } else {
              const option = info.options.filter(opt => opt[info.optionProps.value] === val)[0];
              this.currentForm[code] = option[info.next[code]];
            }
          } else {
            this.currentForm[code] = '';
          }
        }
      }
      this.$emit('select-change', val, info);
    },
    // 合并单元格（行）
    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
      if (this.rowSpanObj && Object.keys(this.rowSpanObj)) {
        if(Object.keys(this.rowSpanObj).indexOf(column.property) > -1) {
          const refCode = this.rowSpanObj[column.property];
          if( this.tableData[rowIndex-1] && row[refCode] === this.tableData[rowIndex-1][refCode]) {
            return [0, 0];
          } else {
            let rowSpan = 1;
            for (let i = rowIndex + 1; i < this.tableData.length; i++) {
              if (row[refCode] === this.tableData[i][refCode]) {
                rowSpan ++;
              } else break;
            }
            return [rowSpan, 1];
          }
        }
      }
    },
    // 复制功能
    copy(text) {
      const textArea = document.createElement('textarea');
      textArea.style.position = 'fixed';
      textArea.style.top = 0;
      textArea.style.left = 0;
      textArea.style.width = '2em';
      textArea.style.height = '2em';
      textArea.style.padding = 0;
      textArea.style.border = 'none';
      textArea.style.outline = 'none';
      textArea.style.boxShadow = 'none';
      textArea.style.background = 'transparent';
      textArea.value = text;
      document.body.appendChild(textArea);
      textArea.select();
      try {
        const msg = document.execCommand('copy');
        // console.log('复制内容 ' + msg)
      } catch (err) {
        // console.log('不能使用这种方法复制内容')
      }
      document.body.removeChild(textArea);
    },
  },
};
</script>
