<template>
  <el-main
    class="box"
    ref="tablePanel"
  >
    <!-- 搜索条件 -->
    <div
      class="search-form-box"
      ref="searchPanel"
    >
      <slot name="searchInput"></slot>
    </div>
    <!-- 内容部分 -->
    <div class="content">
      <!-- 操作按钮 -->
      <div
        class="operation-btn"
        ref="toolbarPanel"
      >
        <slot name="operationBtn"></slot>
      </div>
      <!-- 表格 -->
      <el-table
        ref="table"
        id="AtTable"
        :data="data"
        v-loading="loading"
        height="250"
        border
        row-key="id"
        :expand-row-keys="expandRowKeys"
        :stripe="stripe"
        :header-row-class-name="tableRowClassName"
        :style="{height: `${tableMaxHeight}` + 'px'}"
        :show-header="showHeader"
        :max-height="tableMaxHeight"
        :default-querys="defaultQuerys"
        :default-sorter="defaultSorter"
        :row-class-name="setClassName"
        :default-expand-all="defaultExpandAll"
        :isSortLoad='isSortLoad'
        @row-click="handleRowClick"
        @row-dblclick="handleRowDBClick"
        @select="handleTableSelect"
        @select-all="handleTableSelect"
        @sort-change="handleSortChange"
        @filter-change="handleFilterChange"
        @expand-change="handleExpandChange"
      >
        <slot></slot>
      </el-table>
      <div
        class="pagination-panel"
        ref="paginationPanel"
        v-if="isShowPagination"
      >
        <el-row
          type="flex"
          :justify="paginationJustify"
        >
          <el-pagination
            small
            :disabled="loading"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="pagination.page"
            :page-sizes="pageSizes"
            :page-size="pagination.pageSize"
            :pager-count="pagerCount"
            layout="total, sizes, prev, pager, next, jumper"
            :total="pagination.total"
          ></el-pagination>
        </el-row>
      </div>
    </div>
    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      :width="dialogWidth"
      :before-close="handleDialogClose"
      :close-on-click-modal="false"
      :top="dialogTop"
      @open="handleDialogOpen"
    >
      <slot name="dialogContent"></slot>
      <span
        slot="footer"
        class="dialog-footer"
        v-if="isShowFooter"
      >
        <!-- <span
        slot="footer"
        class="dialog-footer"
       
      > -->
        <el-button @click="handleDialogCancel">取 消</el-button>
        <el-button
          v-if='exportText'
          @click="handleDialogExport"
        >{{exportText}}</el-button>
        <el-button
          type="primary"
          @click="handleDialogSubmit('ruleForm')"
        >保存</el-button>
      </span>
    </el-dialog>
  </el-main>
</template>
<script>
import Sortable from 'sortablejs'
export default {
  name: 'AtTable',
  props: {
    data: Array,
    showHeader: {
      type: Boolean,
      default: true
    },
    defaultQuerys: {
      type: Array,
      default() {
        return []
      }
    },
    pageResult: {
      type: Object,
      default: () => {
        return {page: 1, pageSize: 50, total: 0}
      }
    },
    paginationJustify: {
      type: String,
      default: 'end',
      validator: function(value) {
        return (
          ['start', 'end', 'center', 'space-around', 'space-between'].indexOf(
            value
          ) !== -1
        )
      }
    },
    pageSizes: {
      type: Array,
      default: () => {
        return [10, 20, 50, 100, 200, 300, 500]
      }
    },
    pagerCount: {
      type: Number,
      default: 11
    },
    defaultSorter: {
      type: Array,
      default() {
        return []
      }
    },
    dialogTitle: {
      type: String,
      default: '添加'
    },
    dialogVisible: {
      type: Boolean,
      default: false
    },
    dialogTop: {
      type: String,
      default: '8vh'
    },
    isDrag: {
      type: Boolean,
      default: false
    },
    isShowFooter: {
      type: Boolean,
      default: true
    },
    dialogWidth: {
      type: String,
      default: '1000px'
    },
    stripe: {
      type: Boolean,
      default: true
    },
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    isShowPagination: {
      type: Boolean,
      default: true
    },
    expandRowKeys: {
      type: Array,
      default: () => {
        return []
      }
    },
    isSortLoad: {
      type: Boolean,
      default: true
    },
    exportText: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      filters: {},
      querys: [],
      sorter: null,
      tableMaxHeight: 400,
      pagination: {...this.pageResult},
      loading: false,
      selection: []
    }
  },
  mounted() {
    this.calcTableHeight()
    this.$root.$on('resize', () => {
      this.calcTableHeight(500)
    })
    this.$bus.$on('reHeight', () => {
      this.calcTableHeight()
    })
    this.load()
    if (this.isDrag) {
      this.rowDrop()
    }
    this.$watch('pageResult', (n, o) => {
      if (n !== o) {
        this.pagination = {...n}
      }
    })
  },
  computed: {
    calDefaultQuerys: function() {
      let calQuerys = []
      let query = {
        group: 'defaultQueryGroup',
        operation: 'EQUAL',
        relation: 'AND'
      }
      this.defaultQuerys.forEach(c => {
        calQuerys.push({...query, ...c})
      })
      return calQuerys
    }
  },
  created() {
    this.$on('advance-search', data => this.advanceSearch(data))
  },
  methods: {
    handleClearFilter() {
      this.$refs.table.clearFilter()
      this.filters = {}
      this.clearQueryByGroupName('quick')
      this.clearQueryByGroupName('advance')
      this.load()
    },
    setClassName({row, index}) {
      // 通过自己的逻辑返回一个class或者空
      if (row.hasChildren) {
        return JSON.parse(row.hasChildren) ? '' : 'expand'
      }
    },
    tableRowClassName({row, rowIndex}) {
      if (rowIndex === 0) {
        return 'tableStyle'
      }
      return ''
    },
    handleRowClick(row, column, event) {
      this.$emit('row-click', row, column, event)
    },
    handleRowDBClick(row, column, event) {
      this.$emit('row-dblclick', row, column, event)
    },
    handleExpandChange(row) {
      this.$emit('expand-change', row)
    },
    handleTableSelect(selection, row) {
      this.selection = selection
      if (row) {
        this.$emit('select', selection, row)
      } else {
        this.$emit('select-all', selection)
      }
    },
    handleSortChange(column) {
      if (!column.order) {
        this.sorter = null
      } else {
        this.sorter = [
          {
            property: column.prop,
            direction: column.order == 'ascending' ? 'ASC' : 'DESC'
          }
        ]
      }
      if (isSortLoad) {
        this.load()
      }
      this.$emit('sort-change', column)
    },
    handleFilterChange(m) {
      this.filters = {...this.filters, ...m}
      Object.keys(this.filters).forEach(k => {
        if (!this.filters[k] || this.filters[k].length == 0) {
          delete this.filters[k]
        }
      })
      this.load()
      this.$emit('filter-change', m)
    },
    handleDialogCancel() {
      this.$emit('handleDialogCancel')
      /* 发送一个事件用于侧边栏按钮监听是否显示 */
      this.$bus.$emit('handleAsideBtn', true)
    },
    handleDialogClose(done) {
      this.$emit('handleDialogClose', done)
      /* 发送一个事件用于侧边栏按钮监听是否显示 */
      this.$bus.$emit('handleAsideBtn', true)
    },
    handleDialogExport() {
      this.$emit('handleDialogExport')
      /* 发送一个事件用于侧边栏按钮监听是否显示 */
      this.$bus.$emit('handleAsideBtn', true)
    },
    handleDialogSubmit(formName) {
      this.$emit('handleDialogSubmit', formName)
    },
    handleDialogOpen() {
      this.$emit('handleDialogOpen')
      /* 发送一个事件用于侧边栏按钮监听是否显示 */
      this.$bus.$emit('handleAsideBtn', false)
    },
    advanceSearch(data) {
      if (this.loading || !this.showAdvancedSearch) {
        return
      }
      this.clearQueryByGroupName('quick')
      this.clearQueryByGroupName('advance')
      data &&
        data.forEach(d => {
          let query = {
            property: d.prop,
            value: d.value,
            group: 'advance',
            relation: d.relation,
            operation: d.operation
          }
          query.value && this.querys.push(query)
        })
      this.load()
    },
    load(doNotResetPage) {
      this.loading = true
      // 默认重置页码为第一页
      if (!doNotResetPage) {
        this.pagination.page = 1
      }
      let param = {
        pageBean: this.pagination
      }
      if (this.sorter && this.sorter.length > 0) {
        param.sorter = this.sorter
      }
      // 处理排序字段
      if (this.defaultSorter.length > 0) {
        if (!param.sorter) {
          param.sorter = []
        }
        this.defaultSorter.forEach(item => {
          param.sorter.remove(item)
        })
        param.sorter = param.sorter.concat(this.defaultSorter)
      }
      // 处理过滤条件
      this.handleFilters()
      if (this.querys && this.querys.length > 0) {
        param.querys = this.querys
      }

      // 处理查询条件
      if (this.calDefaultQuerys.length > 0) {
        if (!param.querys) {
          param.querys = []
        }
        this.calDefaultQuerys.forEach(item => {
          param.querys.remove(item)
        })
        param.querys = param.querys.concat(this.calDefaultQuerys)
      }

      const me = this
      // 防止外部没有回调，设置10秒后自动取消加载中的状态
      const finalTickCB = setTimeout(function() {
        me.loading = false
      }, 10000)

      if (this.nopagination) {
        param.pageBean = {}
      }
      this.$emit('load', {...param}, () => {
        // 外部已经回调的情况下，取消倒计时
        clearTimeout(finalTickCB)
        me.loading = false
        this.isReset = false
        setTimeout(() => {
          me.$refs.quickSearch &&
            me.$refs.quickSearch.$children[0].$el.children[0].focus()
        })
      })
    },
    // 通过分组名称清除对应查询条件
    clearQueryByGroupName(groupName) {
      // 待删除的查询条件
      let toDelete = []
      this.querys &&
        this.querys.forEach(query => {
          if (query.group == groupName) {
            toDelete.push(query)
          }
        })
      toDelete.forEach(d => {
        this.querys.remove(d)
      })
    },
    handleFilters() {
      this.clearQueryByGroupName('filter')
      // 将过滤条件添加查询参数数组中
      if (this.filters && Object.keys(this.filters).length > 0) {
        Object.keys(this.filters).forEach(k => {
          const filter = this.filters[k]
          let query = {
            property: k,
            value: filter[0],
            group: 'filter',
            relation: 'AND'
          }
          if (filter.length == 1) {
            query.operation = 'EQUAL'
            this.querys.push(query)
          } else if (filter.length > 1) {
            query.operation = 'IN'
            query.value = filter
            this.querys.push(query)
          }
        })
      }
    },
    handleSizeChange(pageSize) {
      this.pagination = {...this.pagination, pageSize}
      this.load()
    },
    handleCurrentChange(page) {
      this.pagination = {...this.pagination, page}
      // 翻页时不重置页码
      this.load(true)
    },
    //行拖拽
    rowDrop() {
      const tbody = document
        .getElementById('AtTable')
        .querySelector('.el-table__body-wrapper tbody')
      const _this = this
      Sortable.create(tbody, {
        onEnd({newIndex, oldIndex}) {
          const currRow = _this.data.splice(oldIndex, 1)[0]
          _this.data.splice(newIndex, 0, currRow)
        }
      })
    },
    doLayout() {
      this.$refs.table.doLayout()
    },
    calcTableHeight(delay) {
      // 动态计算表格的高度，自适应当前容器
      setTimeout(() => {
        if (!this.$refs.tablePanel) {
          return
        }
        let tablePanelHeight
        const tabPanHeight = this.$parent.$parent.$el.clientHeight
        if (tabPanHeight) {
          tablePanelHeight = tabPanHeight
        } else {
          tablePanelHeight = this.$refs.tablePanel.$el.clientHeight
        }

        const toolbarPanelHeight = this.$refs.toolbarPanel.clientHeight || 0
        const searchPanelHeight =
          this.$refs.searchPanel && this.$refs.searchPanel.clientHeight
            ? this.$refs.searchPanel.clientHeight
            : 0
        const paginationPanelHeight =
          (this.$refs.paginationPanel &&
            this.$refs.paginationPanel.clientHeight) ||
          0
        this.tableMaxHeight =
          tablePanelHeight -
          (searchPanelHeight > 0 ? 45 : 5) -
          toolbarPanelHeight -
          searchPanelHeight -
          paginationPanelHeight
      }, delay || 0)
    },
    clearSelection() {
      this.$refs.table.clearSelection()
    },
    toggleRowSelection(row, selected) {
      this.$refs.table.toggleRowSelection(row, selected)
    },
    getSelection () {
      return this.$refs.table.selection
    }
  }
}
</script>
<style lang="scss" scoped>
// @import '@/assets/css/common.scss';
.box {
  padding: 0;
}
.search-form-box {
  display: flex;
  justify-content: space-between;
  background-color: #fff;
  overflow: hidden;
  border-radius: 5px;
  margin-bottom: 10px;
}
.operation-btn {
  display: flex;
  margin-bottom: 10px;
}
.pagination-panel {
  display: flex;
  justify-content: flex-end;
  margin-top: 5px;
}
/* 内容部分样式 */
.content {
  background-color: #fff;
  padding: 10px;
  overflow: hidden;
  border-radius: 5px;
  box-sizing: border-box;
}
/* 表格头部样式 */
/deep/ .tableStyle th {
  color: #000;
  background-color: rgba($color: rgb(239, 239, 239), $alpha: 0.8);
  border-color: rgb(216, 214, 214);
}
/deep/ .el-dialog__header {
  border-bottom: 1px solid #ccc;
}
/deep/ .el-table__column-filter-trigger i {
  color: #000 !important;
}
.expend .el-table__expand-icon {
  visibility: hidden;
}
/deep/ .el-dialog__title{
  font-weight: bold;
}
</style>
