<template>
  <div
    :id="emstableWrapId"
    ref="emstable-wrap"
    class="emstable-wrap-new"
    :class="{'noSearchbar': !slots['search-bar']}"
  >
    <div
      v-if="slots['search-bar']"
      class="search-bar"
    >
      <div
        class="search-form"
        :class="{'expand': expandMore}"
      >
        <div class="handle-bar">
          <div><b style="font-size:16px">{{ this.pageName }}</b></div>
          <div
            class="handle-bar-solt"
            :class="{'no_search_more': !isShowSearchMore}"
          >
            <slot name="handle-bar"></slot>
          </div>
        </div>
        <slot name="search-bar"></slot>
      </div>
    </div>
    <div style="clear:both"></div>
    <div class="single-table-con">
      <div style="text-align:right">
        <slot name="footer-bar"></slot>
      </div>
      <Checkbox-group
        v-if="columnsFilters.length > 0"
        v-model="columnsChecked"
        @on-change="changeColumns"
      >
        <Checkbox
          v-for="(item, index) in columnsFilters"
          v-if="item.filterFlag !== 'N'"
          :key="index"
          :label="item.key"
        >
          {{ item.label }}
        </Checkbox>
      </Checkbox-group>
      <Table
        ref="table"
        :loading="loading"
        :highlight-row="highlightRow"
        :max-height="tableMaxHeight"
        :data="tableData"
        :columns="tableColumns"
        :row-class-name="rowClassName"
        @on-current-change="onCurrentChange"
        @on-selection-change="selectionChange"
        @on-sort-change="sortHandle"
        @on-row-click="rowClickMt"
        @on-expand="rowClickExpand"
      >
      </Table>
      <div
        v-if="isFooter"
        slot="footer"
        style="margin-top: 8px; overflow: hidden; position: relative;"
      >
        <div
          class="table-bar"
          style="float: left;"
        >
          <slot name="table-bar"></slot>
          <slot name="footer-bar"></slot>
        </div>
        <div style="float: right;">
          <Page
            v-if="isPage"
            :placement="placement"
            :total="total"
            size="small"
            show-total
            show-elevator
            :page-size-opts="pageSizeOpts"
            :page-size="param.page.pageSize"
            :current="param.page.currentPage"
            :show-sizer="showSizer"
            :transfer="!autoFill"
            @on-change="changePage"
            @on-page-size-change="changePageSize"
            :max-height="maxHeight"
          >
          </Page>
        </div>
      </div>
    </div>
    <Epoptip
      :id="emstablePoptipId"
      :content="emstablePoptipContent"
      :can-copy-flag="canCopyFlag"
      class="emstablePoptip"
    ></Epoptip>
  </div>
</template>
<script>
import axios from '../axios.js';
import Epoptip from './epoptip.vue';
export default {
  name: 'EMSTable',
  components: {
    Epoptip
  },
  directives: {},
  props: {
    pageName: {
      type: [Number, String],
      default: ''
    },
    formItemNumForFold: {
      type: [Number, String],
      default: 4
    },
    rowClickExpand: {
      type: Function,
      default() {
        return function() {};
      }
    },
    // 展开所有行
    expandAll: {
      type: Boolean,
      default: false
    },
    changePageFun: {
      type: Function,
      default() {
        return function() {};
      }
    },
    resource: {
      type: Array,
      default() {
        return [];
      }
    },
    useCatch: {
      type: Boolean,
      default() {
        return false;
      }
    },
    catchParams: {
      type: Object,
      default() {
        return {};
      }
    },
    highlightRow: {
      type: Boolean,
      default() {
        return false;
      }
    },
    action: {
      type: String,
      default() {
        return '';
      }
    },
    params: {
      type: Object,
      default() {
        return {};
      }
    },
    server: {
      type: Object,
      default() {
        return {};
      }
    },
    columns: {
      type: Array,
      default() {
        return [];
      }
    },
    columnsFn: {
      type: Function
    },
    initParam: {
      type: Object,
      default() {
        return {};
      }
    },
    loadCallback: {
      type: Function,
      default() {
        return function(data) {};
      }
    },
    autoFirst: {
      type: Boolean,
      default() {
        return true;
      }
    },
    pageSize: {
      type: Number,
      default() {
        return 10;
      }
    },
    showTotal: {
      type: Boolean,
      default() {
        return true;
      }
    },
    showSizer: {
      type: Boolean,
      default() {
        return true;
      }
    },
    pageSizeOpts: {
      type: Array,
      default() {
        return [10, 20, 50, 100, 150, 200, 300];
      }
    },
    isPage: {
      type: Boolean,
      default() {
        return true;
      }
    },
    isFooter: {
      type: Boolean,
      default: true
    },
    onSelectionChange: {
      type: Function
    },
    onRowDblclick: {
      type: Function
    },
    rowClickHandle: {
      type: Function
    },
    showElevator: {
      type: Boolean,
      default: false
    },
    // 是否给行自动 加 序号
    isIndexAuto: {
      type: Boolean,
      default: true
    },
    border: {
      type: Boolean,
      default: true
    },
    autoFill: {
      type: Boolean,
      default: false
    },
    columnsFilters: {
      type: Array,
      default() {
        return [];
      }
    },
    isPoptip: {
      type: Boolean,
      default: true
    },
    // ajax 数据取值
    listName: {
      type: String,
      default: 'list'
    },
    maxHeight: {
      type: [String, Number],
      default: ''
    },
    tableMaxHeight: {
      type: [String, Number],
      default: ''
    }
  },
  data() {
    return {
      timestamp: new Date().getTime(),
      columnsChecked: [],
      tableData: [],
      tableColumns: [],
      sourceTableColumns: [],
      total: 0,
      currentPage: 1,
      selection: [],
      loading: false,
      param: {
        page: {
          currentPage: 1,
          pageSize: this.pageSize
        },
        params: this.params,
        sortDTO: {
          fieldName: '',
          orderBy: ''
        }
      },
      messageJob: undefined,
      isSelectionChange: false,
      currentRow: undefined,
      expandMore: false,
      slots: this.$slots,
      tableHeight: '',
      isShowSearchMore: false,
      emstablePoptip: '',
      emstablePoptipContent: '',
      itableEle: '',
      poptipTimer: '',
      canCopyFlag: false // 是否启用复制按钮
    };
  },
  computed: {
    placement() {
      let pageTotal = 0;
      if (this.total % this.pageSize === 0) {
        pageTotal = this.total / this.pageSize;
      } else {
        pageTotal = this.total / this.pageSize + 1;
      }
      pageTotal = parseInt(pageTotal);
      return this.total % this.pageSize < 3 && this.currentPage === pageTotal ? 'bottom' : 'top';
    },
    lang() {
      return window.$app.$store.state.lang;
    },
    // 是否开启了复选框
    isOpenSel() {
      return this.tableColumns.some(item => {
        return item.type === 'selection';
      });
    },
    // 是否开启了展开行
    isOpenExpand() {
      return this.tableColumns.some(item => {
        return item.type === 'expand';
      });
    },
    emstableWrapId() {
      return `emstableWrap${this.timestamp}`;
    },
    emstablePoptipId() {
      return `emstablePoptip${this.timestamp}`;
    }
  },
  watch: {
    lang() {
      this.getColumns();
    },
    resource(newVal, oldVal) {
      this.resource = newVal;
      this.loadLocal();
    },
    tableData: {
      handler(newVal, oldVal) {
        // 填充序号 方便后面其他操作
        newVal.map((item, index) => {
          item.__INDEX = index;
          this.expandAll && (item._expanded = true);
        });
        // 填充空行
        if (this.autoFill) {
          this.fill(newVal);
        }
      },
      immediate: true
    },
    expandMore(newVal, oldVal) {
      // this.$nextTick(this.tableHeightComputed);
    }
  },
  created: function() {
    if (!!this.action && this.autoFirst) {
      this.load(this.initParam);
    } else if (!this.action) {
      this.loadLocal();
    }
    for (const c of this.columns) {
      if (!~'selection'.indexOf(c.type)) {
        c.ellipsis = true;
      }
    }
    for (const item of this.columnsFilters) {
      if (item.filterFlag !== 'N') {
        this.columnsChecked.push(item.key);
      }
    }
    this.getColumns();
  },
  beforeMount: function() {},
  mounted: function() {
    this.tableHeightComputed();
    // window.resizeHandle.push(this.tableHeightComputed);
    this.showSearchMore();
    // 通过操作DOM来添加TIP提示 是为了优化列表渲染速度
    this.itableEle = document.querySelector(`#${this.emstableWrapId} .ivu-table-body`);
    document.body.appendChild(document.querySelector(`#${this.emstablePoptipId}`));
    this.emstablePoptip = document.querySelector(`#${this.emstablePoptipId} .ivu-poptip-popper`);
  },
  updated() {
    this.itableEle.removeEventListener('mouseover', this.showPoptip);
    this.itableEle.addEventListener('mouseover', this.showPoptip);
    this.emstablePoptip.removeEventListener('mouseleave', this.hidePoptip);
    this.emstablePoptip.addEventListener('mouseleave', this.hidePoptip);
    this.emstablePoptip.removeEventListener('mouseenter', this.clearPoptipTimer);
    this.emstablePoptip.addEventListener('mouseenter', this.clearPoptipTimer);
  },
  beforeDestroy: function() {
    this.itableEle.removeEventListener('mouseover', this.showPoptip);
    this.emstablePoptip.removeEventListener('mouseleave', this.hidePoptip);
    this.emstablePoptip.removeEventListener('mouseenter', this.clearPoptipTimer);
    try {
      document.querySelector(`#${this.emstablePoptipId}`).remove();
    } catch (err) {
      // 兼容ie
      document.querySelector(`#${this.emstablePoptipId}`).removeNode(true);
    }
  },
  destroyed: function() {},
  methods: {
    showMore() {
      this.expandMore = !this.expandMore;
    },
    showPoptip(e) {
      const that = this;
      const emstablePoptip = this.emstablePoptip;
      if (e.target.title && e.target.getAttribute('data-title')) { // 页面搜索之后，删除data-title
        e.target.removeAttribute('data-title');
      }
      if (e.target.title || e.target.getAttribute('data-title')) {
        this.clearPoptipTimer();
        const node = e.target;
        const nodeCR = node.getBoundingClientRect();
        // 获取配置中的canCopyFlag标识，1-表示启用复制按钮
        that.canCopyFlag = node.getAttribute('canCopyFlag') === '1';
        if (!node.getAttribute('data-title')) {
          node.setAttribute('data-title', node.title);
          node.removeAttribute('title');
        }
        let pwidth = 150;
        const tlen = node.getAttribute('data-title').replace(/[^\u0000-\u00ff]/g, 'aa').length;
        if (tlen > 20) {
          pwidth = tlen * 7;
        }
        that.emstablePoptipContent = node.getAttribute('data-title');
        window.xxx = node;
        setTimeout(() => {
          emstablePoptip.style.display = 'block';
          emstablePoptip.style.position = 'fixed';
          emstablePoptip.style.top = nodeCR.top - emstablePoptip.offsetHeight + 55 + 'px';
          // emstablePoptip.style.left = nodeCR.left + (emstablePoptip.width - pwidth) / 2 + 'px';
          emstablePoptip.style.left = nodeCR.left + 'px';
          emstablePoptip.style.marginTop = -(nodeCR.height + 30) + 'px';
          node.removeEventListener('mouseout', this.hidePoptipDelay);
          node.addEventListener('mouseout', this.hidePoptipDelay);
        }, 0);
      }
    },
    hidePoptip() {
      this.emstablePoptip.style.display = 'none';
    },
    hidePoptipDelay() {
      this.poptipTimer = setTimeout(() => {
        this.emstablePoptip.style.display = 'none';
      }, 1000);
    },
    clearPoptipTimer() {
      clearTimeout(this.poptipTimer);
    },
    changeColumns() {
      if (!this.sourceTableColumns.length) {
        this.sourceTableColumns = [...this.tableColumns];
      }
      this.tableColumns = this.sourceTableColumns.filter(item => {
        const temObj = this.columnsFilters.filter(obj => obj.key === item.key)[0];
        // 没有设置key属性的列，例如操作列、序号列等
        if (!item.key) {
          return true;
        } else if (temObj && temObj.filterFlag === 'N') {
          return true;
          // 在筛选列数组内的
        } else {
          return this.columnsChecked.includes(item.key);
        }
      });
    },
    onCurrentChange(currentRow, oldCurrentRow) {
      this.currentRow = Object.assign({}, currentRow);
    },
    getHighlightRow() {
      return this.currentRow;
    },
    getColumns() {
      let bfcolumns = [];
      if (typeof this.columnsFn === 'function') {
        bfcolumns = [].concat(this.columnsFn());
      } else {
        bfcolumns = [].concat(this.columns);
      }
      this.tableColumns = bfcolumns;

      // 加上序号列
      // if (this.isIndexAuto) {
      //   this.tableColumns.unshift({
      //     title: '序号',
      //     type: 'index',
      //     align: 'center',
      //     width: 30
      //   });
      // }

      return this.tableColumns;
    },
    refresh(currentPage) {
      this.param.page.currentPage = currentPage || 1;
      this.$nextTick(() => {
        this.load();
      });
    },
    resetSelection() {
      this.selection = [];
      this.onSelectionChange && this.onSelectionChange(this.selection);
      this.$emit('on-selection-change', this.selection);
    },
    load(param = {}, page, cb = function() {}) {
      this.resetSelection(); // 重置选中项，以便在搜索、重置、分页时能正确显示操作按钮状态

      for (const p in param) {
        this.param.params[p] = param[p];
      }
      this.loading = true;
      if (!!page && typeof page === 'number') {
        this.param.page.currentPage = page;
      }
      this.param.page.recordCount = this.total;
      this.action ? this.loadAjax(cb) : this.loadLocal(cb);
    },
    loadLocal(cb) {
      this.loadCallback(this.resource);
      if (!this.isPage) {
        this.$nextTick(() => {
          this.tableData = [].concat(this.resource);
          this.loading = false;
        });
        return;
      }
      this.total = this.resource.length;
      const start = (this.param.page.currentPage - 1) * this.param.page.pageSize;
      let end = start + this.param.page.pageSize;
      end = this.resource.length > end ? end : this.resource.length;
      this.tableData = [];
      for (let i = start; i < end; i++) {
        this.tableData.push(this.resource[i]);
      }
      this.changePageFun();
      cb && cb(this.tableData);
      this.$nextTick(() => {
        this.loading = false;
      });
    },
    loadAjax(cb) {
      if (this.server[this.action]) {
        this.server[this.action](this.param).then(res => {
          this.loading = false;

          // 若返回的数据不符合要求
          if (!res || !res.data || res.data.pageNum === undefined) {
            return this.$Message.error((res && res.msg) || '数据加载失败');
          }
          this.currentPage = res.data.pageNum;
          this.total = res.data.total;
          this.tableData = [];
          this.loadCallback(res.data[this.listName]);
          for (const item of res.data[this.listName]) {
            this.tableData.push(item);
          }
          this.changePageFun();
          cb(this.tableData);
        });
      } else {
        this.$axios.post(this.action, this.param).then(res => {
          this.loading = false;
          if (!res) return;
          if (res.data.dataResult) {
            res.data = res.data.dataResult;
          }
          this.currentPage = res.data.pageNum;
          this.total = res.data.total;
          this.tableData = [];
          this.loadCallback(res.data[this.listName]);
          for (const item of res.data[this.listName]) {
            this.tableData.push(item);
          }
          this.changePageFun();
          cb(this.tableData);
        });
      }
    },
    changePage(page) {
      this.param.page.currentPage = page;
      this.load();
    },
    changePageSize(page) {
      this.param.page.pageSize = page;
      this.load();
    },
    selectionChange(selection) {
      this.isSelectionChange = true;
      this.selection = selection;

      // 选中的背景高亮
      this.tableData.map(row => {
        this.$set(this.tableData[row.__INDEX], '_checked', false);
        this.$set(this.tableData[row.__INDEX], '_highlight', false);
      });
      selection.map(row => {
        this.$set(this.tableData[row.__INDEX], '_checked', true);
        this.$set(this.tableData[row.__INDEX], '_highlight', true);
      });

      // 回调
      if (typeof this.onSelectionChange === 'function') {
        this.onSelectionChange(selection);
      }
      this.$emit('on-selection-change', selection);
    },
    rowDblclick(selection, index) {
      if (typeof this.onRowDblclick === 'function') {
        this.onRowDblclick(selection, index);
      }
      this.$emit('on-row-dblclick', selection);
    },
    getSelectioned() {
      return this.isSelectionChange ? this.selection : undefined;
    },
    sortHandle(obj) {
      this.param.sortDTO.fieldName = obj.key;
      this.param.sortDTO.orderBy = obj.order;
      if (this.param.sortDTO.orderBy === 'normal') {
        this.param.sortDTO = {
          fieldName: '',
          orderBy: ''
        };
      }
      this.refresh(this.currentPage);
    },
    getSortData() {
      return this.param.sortDTO;
    },
    getTableObj() {
      return this.$refs.table;
    },

    // 展开更多搜索选项
    expandMoreSearch() {
      this.expandMore = !this.expandMore;
    },
    rowClickMt(row, index) {
      // 回掉方法
      this.rowClickHandle && this.rowClickHandle(row, index);
    },

    // 表格数据不够时用空白表格填满
    fill(list) {
      const size = 10;
      const bkline = { _disabled: true, _blank: true };
      if (list.length < size) {
        const len = size - list.length;
        for (var i = 0; i < len; i++) {
          // 这个判断修复 不够10条时进行排序，空行会跑到非空行上面的bug
          if (!this.param.sortDTO.orderBy || this.total > 10) {
            this.tableData.push(bkline);
          } else if (this.param.sortDTO.orderBy && this.total < 10) {
            this.tableData.push(bkline);
          } else {
            this.tableData.unshift(bkline);
          }
        }
      }
    },
    // 给空行添加样式
    rowClassName(row, index) {
      let cls = '';
      if (row._disabled) {
        cls += 'disabled ';
      }
      if (row._blank) {
        cls += 'blank ';
      }
      if (row._checked) {
        cls += 'checked ';
      }
      return cls;
    },
    // 表格高度计算
    tableHeightComputed() {
      if (this.$slots['search-bar']) {
        const winH = window.innerHeight;
        const emstableWrap = this.$refs['emstable-wrap'];
        const searchBar = emstableWrap.querySelector('.search-bar');
        const searchBarH = searchBar.getBoundingClientRect().height;
        const tabsbar = document.querySelector('.ivu-tabs-bar');
        const tabsbarH = tabsbar ? tabsbar.getBoundingClientRect().height : 0;
        let coreModal = null;
        const findCoreModal = el => {
          if (el.parentNode) {
            if (el.parentNode.querySelector('.core-modal-body')) {
              coreModal = el.parentNode;
            } else {
              findCoreModal(el.parentNode);
            }
          }
        };
        findCoreModal(emstableWrap);
        if (coreModal) {
          // 如果表格是嵌套在pageModal里面的
          coreModal.parentNode.className += ' width-emstable';
          const coreModalFooterH = coreModal.querySelector('.core-modal-footer').getBoundingClientRect().height;
          this.tableHeight = winH - searchBarH - 78 - 38 - coreModalFooterH - 13;
        } else {
          const minHeight = this.tableData.length * 45;
          this.tableHeight = winH - searchBarH - tabsbarH - 78 - 35 - 20;
          this.tableHeight = Math.min(500, (winH - searchBarH - tabsbarH - 78 - 35 - 15));
        }
      }
    },
    showSearchMore() {
      if (this.$el.querySelectorAll('.search-form .ivu-form-item').length > this.formItemNumForFold) {
        this.isShowSearchMore = true;
      }
    }
  }
};
</script>
