/**
* Description: 列表组件
*
* Created by longyihuang on 2020/3/13
* E-Mail: 475865662@qq.com
* Location: shenzhen
*/

<template>
  <div>
    <div
      v-if="showTableTitleFilter"
      style="display: flex; align-items: center"
    >
      <label
        class="normal-text"
        style="margin-right: 10px"
      >数据筛选：</label>
      <el-select
        style="width: 250px"
        v-model="openColumns"
        multiple
        placeholder="请选择要查看的数据"
        collapse-tags
        @change="handleOpenColumnsChange"
      >
        <el-option
          v-for="item in tableTitles"
          :key="item.prop"
          :label="item.label"
          :value="item.prop"
        >
        </el-option>
      </el-select>
    </div>

    <el-table
      ref="table"
      :data="dataSource"
      :border="border"
      style="width: 100%"
      :row-style="rowStyle"
      :highlight-current-row="highlight"
      @row-click="onRowClick"
      @sort-change="onSortChange"
      @select-all="onSelectAll"
      @selection-change="handleSelectionChange"
      @current-change="handleCurrentChange"
      :empty-text="emptyText"
      :row-key="rowKey"
      :max-height="maxHeight"
      :span-method="objectSpanMethod"
      :row-class-name="tableRowClassName"
    >

      <el-table-column
        v-if="isSelect"
        type="selection"
        width="55"
        :selectable="selectable"
        :reserve-selection="reserveSelection"
      >
      </el-table-column>

      <el-table-column
        :key="index"
        v-for="(item, index) in tableTitlesData"
        :label="item.label"
        :prop="item.prop"
        :width="item.width"
        :min-width="item.minWidth"
        :align="item.align"
        :type="item.type"
        :fixed="item.fixed"
        :sortable="item.sortable"
        :show-overflow-tooltip="item.tooltip"
      >
        <template slot="empty">
          <span>-</span>
        </template>
        <slot
          v-if="item.template"
          slot-scope="scope"
          :name="item.prop"
          :row="scope.row"
          :index="scope.$index"
        ></slot>

        <template v-else-if="item.overlength">
          <el-tooltip
            v-if="computedText(scope.row[item.prop]) && computedText(scope.row[item.prop]).length > item.overlength"
            :content="computedText(scope.row[item.prop])" placement="top-start">
            <div>{{computedText(scope.row[item.prop]).substring(0, item.overlength)}}...</div>
          </el-tooltip>
          <div v-else>{{computedText(scope.row[item.prop])}}</div>
        </template>

        <div v-else>{{computedText(scope.row[item.prop])}}</div>
      </el-table-column>
    </el-table>

    <div
      class="table-pagination"
      v-if="pagination"
    >
      <el-pagination
        background
        @size-change="handlePageSizeChange"
        @current-change="handlePageChange"
        :current-page.sync="currentPage"
        :page-sizes="pageNumberlist"
        :page-size="pageSize"
        :layout="paginationLayout"
        :total="total"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
import _ from 'loadsh';
export default {
  name: "TableComponent",
  props: {
    isSelect: {
      type: Boolean,
      default: false
    },

	  reserveSelection: {
		  type: Boolean,
		  default: false
	  },

    tableData: {
      type: Array,
      default: function () {
        return []
      }
    },

    rowKey: {
      type: String,
      default: function () {
        return undefined
      }
    },

    defaultPageNumber: {
      type: Number,
      default: 10
    },

    border: {
      type: Boolean,
      default: false
    },

    pageNumberlist: {
      type: Array,
      default: function () {
        return [10, 50, 100]
      }
    },

    tableTitles: {
      type: Array,
      default: function () {
        return []
      }
    },

    pagination: {
      type: Boolean,
      default: true
    },


    paginationLayout: {
      type: String,
      default: function () {
        return "total, prev, pager, next, sizes"
      }
    },

    autoLoad: {
      type: Boolean,
      default: true
    },

    remoteApi: {
      type: Function,
      default: null
    },

    objectSpanMethod: {
      type: Function,
      default: null
    },

    showTableTitleFilter: {
      type: Boolean,
      default: false
    },

    rowStyle: {
      type: Function,
      default: undefined
    },

    emptyText: {
      type: String,
      default: function () {
        return '暂无数据'
      }
    },

    emptyDataText: {
      type: String,
      default: function () {
        return ''
      }
    },

    ppageText: {
      type: String,
      default: function () {
        return 'currentPage'
      }
    },

    pnumberText: {
      type: String,
      default: function () {
        return 'pageSize'
      }
    },

    maxHeight: {
      type: Number,
      default: 10000
    },
    selectable: {
      type: Function,
      default: function () {
        return true
      }
    },
    tableRowClassName: {
      type: Function,
      default: null
    },

    highlight: {
      type: Boolean,
      default: false
    },
  },

  data() {
    const currentPage = 1;
    const pageSize = this.defaultPageNumber;
    let dataSource = !this.remoteApi && this.tableData ? [...this.tableData] : [];
    if (this.pagination && dataSource.length > 0) {
      dataSource = dataSource.slice(0, this.defaultPageNumber)
    }
    const total = !this.remoteApi && this.tableData ? this.tableData.length : 0;
    const tableTitlesData = this.tableTitles;
    const openColumns = this.tableTitles.map(item => item.prop);
    return {
      dataSource,
      total,
      currentPage,
      pageSize,
      params: undefined,
      tableTitlesData,
      openColumns,
      pdirection: undefined,
      pcolumn: undefined
    }
  },

  computed: {
  	computedText() {
  		return function (text) {
  			let res = text
  			if (text === undefined || text === null || text === '') {
  				res = this.emptyDataText
        }
        return res
		  }
    }
  },

  watch: {
    tableData: {
      handler(newVal, oldVal) {
        let data = !this.remoteApi && newVal ? [...newVal] : [];
        if (this.pagination && newVal.length > 0) {
          data = newVal.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
          if (data.length === 0 && this.currentPage - 1 > 0) {
            data = newVal.slice((this.currentPage - 2) * this.pageSize, (this.currentPage - 1) * this.pageSize)
          }
        }
        this.dataSource = data;
        this.total = !this.remoteApi && newVal ? newVal.length : 0;
      },
      deep: true
    },

    tableTitles: {
      handler(newVal, oldVal) {
        this.tableTitlesData = newVal;
      }
    },

    dataSource: {
      handler(newVal) {
        this.$emit('onDataChange', newVal)
      },
      deep: true
    }
  },

  mounted() {
    this.autoLoad && this.queryData();
  },


  methods: {
    queryData(queryParams) {
      this.getDataSourceFormServer(queryParams);
    },

    refreshData(queryParams) {
      this.currentPage = 1;
      this.pageSize = this.defaultPageNumber;
      this.getDataSourceFormServer(queryParams);
    },

    async getDataSourceFormServer(params) {
      if (!this.remoteApi) {
        return;
      }
      this.params = params
      const p = {
        [this.ppageText]: this.pagination ? this.currentPage : undefined,
        [this.pnumberText]: this.pagination ? this.pageSize : undefined,
        pdirection: this.pdirection,
        pcolumn: this.pcolumn,
        ...this.params
      }
      const data = await this.remoteApi(p)
      if (data) {
        this.dataSource = data.rows
        this.total = data.total
        this.autoLoad && this.$emit('onLoaded', data);
      }
    },

    handlePageChange(currentPage) {
      this.currentPage = currentPage;
      if (this.remoteApi) {
        this.getDataSourceFormServer(this.params)
      } else {
        this.dataSource = this.tableData ? this.tableData.slice((currentPage - 1) * this.pageSize, currentPage * this.pageSize) : []
      }
    },

    handlePageSizeChange(pageSize) {
      this.currentPage = 1;
      this.pageSize = pageSize;
      if (this.remoteApi) {
        this.getDataSourceFormServer(this.params)
      } else {
        this.dataSource = this.tableData ? this.tableData.slice(0, pageSize) : []
      }
    },

    handleOpenColumnsChange(selection) {
      this.tableTitlesData = _.intersectionBy(this.tableTitles, selection.map(item => {
        return {
          prop: item
        }
      }), 'prop');
    },

    getDataSource() {
      return this.dataSource;
    },

    getTotal() {
      return this.total;
    },

    getPageNumber() {
      return this.currentPage
    },

    getPageSize() {
      return this.pageSize
    },

    onRowClick(row) {
      this.$emit('onRowClick', row);
    },

    onSelectAll(val) {
      this.$emit('onSelectAll', val);
    },

    handleSelectionChange(val) {
      this.$emit('onSelectChange', val);
    },

    clearSelection() {
      this.$refs.table.clearSelection()
    },

    toggleRowSelection(row, val) {
      this.$refs.table.toggleRowSelection(row, val)
    },

    onSortChange({ column, prop, order }) {
      this.pcolumn = order === null ? undefined : prop;
      this.pdirection = order === null ? undefined : order === 'ascending';
      this.getDataSourceFormServer(this.params)
    },

    refreshSelection(selection = []) {
      this.clearSelection()
      selection.forEach(row => {
        if (row) {
          this.toggleRowSelection(row, true);
        }
      });
    },

    handleCurrentChange(currentRow, oldCurrentRow) {
      this.$emit('currentChange', currentRow, oldCurrentRow);
    }
  }
}
</script>

<style lang='scss' scoped>
	.table-pagination {
		margin-top: 5px;
		background: #fff;
	  display: -webkit-flex;
    display: flex; 
		justify-content: end;
	}
</style>
