<template>
  <div class="dataTable">
    <div v-if="toolMenuFlag"
         class='headTitle'>
      <slot name="headForm">
      </slot>
      <auth-button :label="$t('common.create')"
                   v-if="btnCreate"
                   type="primary"
                   size=""
                   :menuCode="menuCode"
                   :perms="createPerms"
                   icon="el-icon-plus"
                   @click="showCreate"></auth-button>
      <auth-button :label="$t('common.dels')"
                   v-if="btnDels"
                   type="danger"
                   size=""
                   :menuCode="menuCode"
                   :perms="delsPerms"
                   icon="el-icon-delete"
                   @click="showDels"></auth-button>
      <span v-if="headTitle !== ''">{{headTitle}}</span>
      <div class="headButton"
           v-if="IsRight">
        <slot name="headButton">
        </slot>
      </div>
      <slot name="headButton"
            v-else>
      </slot>
      <el-button-group v-if="menuFlag"
                       style="float:right">
        <el-tooltip effect="dark"
                    :content="showHandleFlag ? $t('common.fold') : $t('common.open')"
                    placement="top">
          <el-button :icon="showHandleFlag ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"
                     @click="showHandleFlag = !showHandleFlag"></el-button>
        </el-tooltip>
        <!-- <el-tooltip effect="dark" content="刷新" placement="bottom">
          <el-button  icon="el-icon-refresh" @click="loadTableData"></el-button>
        </el-tooltip> -->
        <el-dropdown :hide-on-click="false"
                     trigger="click"
                     style="margin-left:1px">
          <el-button>
            <i class="el-icon-more"></i>
          </el-button>
          <el-dropdown-menu slot="dropdown">
            <template v-for="(column, index) in columns">
              <el-dropdown-item :key="index">
                <el-checkbox v-model="columnMenus[column.prop]">{{column.label}}</el-checkbox>
              </el-dropdown-item>
            </template>
          </el-dropdown-menu>
        </el-dropdown>
      </el-button-group>
    </div>

    <el-table :data="tableDatas"
              v-loading="vLoading"
              :element-loading-text="elementLoadingText"
              element-loading-spinner="el-icon-loading"
              element-loading-background="rgba(255, 255, 255, 1)"
              @selection-change="selectionChange"
              :border="border"
              @row-click="rowClick"
              :row-key="rowKey"
              v-bind="$attrs"
              highlight-current-row
              tooltip-effect="dark"
              ref="vueTable"
              :style="currentStyle"
              :default-sort="defaultSort"
              :span-method="spanMethod"
              cell-class-name="common-table-cell"
              header-cell-class-name="common-table-header">
      <el-table-column v-if="showSelection"
                       :type="type"
                       align="center"
                       :label="typeLabel"
                       :selectable="selectTable"
                       width="55"></el-table-column>
      <slot name="index"></slot>
      <template v-for="(column,index) in columns">
        <el-table-column v-if="columnMenus[column.prop]"
                         :key="index"
                         :align="column.align"
                         header-align="center"
                         :label="column.label"
                         :prop="column.prop"
                         :width="column.width"
                         :sortable="column.sortable"
                         :show-overflow-tooltip="column.showOverflowTooltip">
          <template slot-scope="scope">
            <!-- 如果有格式化，处理格式化数据 -->
            <span v-if="columnMenus[column.prop] ">{{column.format?column.format(scope.row):scope.row[column.prop]}}</span>
          </template>
          <template v-if="column.child">
            <template v-for="(columnChild, ind) in column.child">
              <el-table-column :align="columnChild.align"
                               :key="ind"
                               header-align="center"
                               :label="columnChild.label"
                               :prop="columnChild.prop"
                               :width="columnChild.width">
                <template slot-scope="scope">
                  <!-- 处理child里面的格式化数据，如果有格式化，处理格式化数据 -->
                  <span>{{columnChild.format?columnChild.format(scope.row):scope.row[columnChild.prop]}}</span>
                </template>
              </el-table-column>
            </template>
          </template>

        </el-table-column>
      </template>
      <slot>
      </slot>
      <el-table-column v-if="operateBtnLayout.indexOf('V') > -1 || operateBtnLayout.indexOf('E') > -1 ||  operateBtnLayout.indexOf('R') > -1 || operateBtnLayout.indexOf('D') > -1 || operateBtnLayout.indexOf('U') > -1"
                       fixed="right"
                       align="center"
                       label="操作"
                       :width="operatWidth">
        <template slot-scope="scope">
          <operateGroup :menuCode="menuCode"
                        :viewPerms="viewPerms"
                        :editPerms="editPerms"
                        :reviewPerms="reviewPerms"
                        :uploadPerms="uploadPerms"
                        :delPerms="delPerms"
                        :deleteApi="deleteApi"
                        :autoDel="autoDel"
                        :operateColLayout="operateColLayout(scope.row)"
                        :rowData="scope.row"
                        :rowIndex="scope.$index"
                        @operateBtnClick="operateBtnClick">
            <template slot="button"
                      slot-scope="obj">
              <slot name="button"
                    :row="obj.row"
                    :index="obj.index">
              </slot>
            </template>
          </operateGroup>
        </template>
      </el-table-column>
    </el-table>
    <div v-if="showPage && !vLoading"
         class="pagination-container "
         :style="paginationStyle">
      <el-pagination @size-change="handleSizeChange"
                     @current-change="handleCurrentChange"
                     :current-page.sync="queryParas.pageIndex"
                     :page-sizes="pageSizes"
                     :page-size="queryParas.pageSize"
                     :layout="pageLayout"
                     prev-text="上一页"
                     next-text="下一页"
                     :page-count="pageCount"
                     :total="currentTotal">
        <span style="text-align: center">{{queryParas.pageIndex}}</span>
      </el-pagination>

    </div>
  </div>
</template>

<script>
const V = 'V' // 查看
const E = 'E' // 编辑
const D = 'D' // 删除
const U = 'U' // 上传
const R = 'R' // 复核
const C = 'C' // 新建
const B = 'B' // 批量删除
import operateGroup from '@/components/buttonGroup/operateGroup'
import AuthButton from '@/components/auth/authButton'
export default {
  components: {
    operateGroup,
    AuthButton
  },
  props: {
    // 所属菜单Code-->全局唯一
    menuCode: {
      type: String,
      default: null
    },
    headTitle: {
      type: String,
      default: null
    },
    IsRight: {
      type: Boolean,
      default: true
    },
    // 新增按钮权限标识，外部使用者传入
    createPerms: {
      type: String,
      default: null
    },
    // 批量删除按钮权限标识，外部使用者传入
    delsPerms: {
      type: String,
      default: null
    },
    // 显示按钮个数
    pageCount: {
      type: Number,
      default: function () {
        return 7
      }
    },
    // 查看按钮权限标识，外部使用者传入
    viewPerms: {
      type: String,
      default: null
    },
    // 编辑按钮权限标识，外部使用者传入
    editPerms: {
      type: String,
      default: null
    },
    // 复核按钮权限标识，外部使用者传入
    reviewPerms: {
      type: String,
      default: null
    },
    // 上传按钮权限标识，外部使用者传入
    uploadPerms: {
      type: String,
      default: null
    },
    // 删除按钮权限标识，外部使用者传入
    delPerms: {
      type: String,
      default: null
    },
    menuFlag: {
      type: Boolean,
      default () {
        return true
      }
    },
    sourceData: {
      type: Array,
      default: function () {
        return []
      }
    },
    handleFlag: {
      required: false,
      type: Boolean,
      default: () => true
    },
    columns: {
      type: Array,
      default: () => []
    },
    value: {
      type: Array
    },
    api: {
      type: Object
    },
    elementLoadingText: {
      type: String,
      default: function () {
        return '拼命加载中'
      }
    },
    border: {
      type: Boolean,
      default: function () {
        return true
      }
    },
    toolMenuFlag: {
      type: Boolean,
      default () {
        return true
      }
    },
    styles: {
      type: String,
      default: function () {
        return 'width: 100%'
      }
    },
    showSelection: {
      type: Boolean,
      default: function () {
        return false
      }
    },
    type: {
      type: String,
      default: function () {
        return 'selection'
      }
    },
    typeLabel: {
      type: String,
      default: function () {
        return '#'
      }
    },
    showPage: {
      type: Boolean,
      default: function () {
        return true
      }
    },
    pageAll: {
      type: Boolean,
      default () {
        return true
      }
    },
    pageSizes: {
      type: Array,
      default: function () {
        return [10, 20, 30, 40, 50]
      }
    },
    operateBtnLayout: {
      type: String,
      default: function () {
        return `${C},${B},${V},${E},${R},${D},${U}`
      }
    },
    pageIndex: {
      type: Number,
      default: function () {
        return 1
      }
    },
    pageSize: {
      type: Number,
      default: function () {
        return 10
      }
    },
    pagePosition: {
      type: String,
      validator: function (value) {
        return value === 'right' || value === 'left' || value === 'center'
      },
      default: function () {
        return 'right'
      }
    },
    queryParas: {
      type: Object,
      default: function () {
        return {
          pageIndex: 1,
          pageSize: 10,
          keys: null
        }
      }
    },
    loadCount: {
      type: Number,
      default: function () {
        return 0
      }
    },
    defaultSort: {
      type: Object,
      default: function () {
        return {}
      }
    },
    btnHandle: {
      type: String,
      default: function () {
        return ''
      }
    },
    delAlertMsg: {
      type: String,
      default: function () {
        return '此操作会删除该条数据，是否继续？'
      }
    },
    // 分页查询调用的api字符串
    loadPage: {
      type: String,
      default: function () {
        return 'getPage'
      }
    },
    // 控制合并行和列的方法
    spanMethod: {
      type: Function,
      default: function () {
        return function ({ row, column, rowIndex, columnIndex }) {
          return null
        }
      }
    },
    rowKey: {
      type: [Function, String],
      require: false
    },
    deleteApi: {
      type: Object
    },
    operatWidth: {
      type: [String]
    },
    autoDel: {
      type: Boolean,
      default () {
        return true
      }
    },
    reviewFun: {
      type: Function,
      default () {
        return null
      }
    },
    doReviewFun: {
      type: Boolean,
      default () {
        return false
      }
    },
    lastModifyUserId: {
      type: Boolean,
      default: function () {
        return false
      }
    },
    delStatus: {
      type: Boolean,
      default: function () {
        return true
      }
    },
    // 控制选择框禁用条件的方法
    selectTable: {
      type: Function,
      default: function () {
        return function ({ row, index }) {
          return true
        }
      }
    },
    // 是否禁止全选按钮
    disabledAll: {
      type: Boolean,
      default: function () {
        return false
      }
    }
  },
  data () {
    return {
      currentTotal: 0,
      tableDatas: this.sourceData,
      vLoading: false,
      columnMenus: {},
      selectionData: [],
      tableData: [],
      setDatasource: this.sourceData && this.sourceData.length > 0
    }
  },
  mounted () {
    this.disabledAllCheck() // 禁止全选按钮
  },
  created: function () {
    this.columns.forEach(it => {
      this.$set(this.columnMenus, it.prop, true)
    })
  },
  computed: {
    dropdownMenus: function () {
      this.columns.forEach(it => {
        this.columnMenus[it.prop] = true
      })
      return this.columnMenus
    },
    btnCreate: function () {
      let layout = this.operateBtnLayout
      return layout !== null && layout !== '' && layout.indexOf(C) !== -1
    },
    btnDels: function () {
      let layout = this.operateBtnLayout
      return layout !== null && layout !== '' && layout.indexOf(B) !== -1
    },
    showHandleFlag: {
      get: function () {
        return this.handleFlag
      },
      set: function (value) {
        this.$emit('update:handleFlag', value)
      }
    },
    operateBtn: function () {
      return this.btnCreate || this.btnDels
    },
    currentStyle: function () {
      return this.styles
    },
    paginationStyle: function () {
      return { 'text-align': this.pagePosition }
    },
    pageLayout () {
      return this.pageAll
        ? 'total, sizes, prev, pager, next, jumper'
        : 'sizes, prev, slot, next'
    }
  },
  watch: {
    sourceData: {
      deep: true,
      handler (value, old) {
        if (!this.UtilJs.isEmpty(this.currentTotal)) {
          this.buildTableData(value, this.currentTotal)
        } else {
          this.buildTableData(value)
        }
      }
    },
    loadCount: function (value) {
      try {
        if (this.queryParas.pageIndex !== 1) {
          this.queryParas.pageIndex = 1
        }
        this.loadTableData()
      } finally {
        this.$emit('update:loadCount', value)
      }
    }
  },
  methods: {
    operateColLayout (column) {
      if (this.operateBtnLayout.indexOf('R') > -1) {
        if (this.UtilJs.isFunction(this.reviewFun) && this.doReviewFun) {
          return this.reviewFun(column)
        }
        if (column.addUserId !== this.$store.getters.userId) {
          let layout = this.operateBtnLayout.split(',')
          return layout
            .filter(it => {
              return it !== 'R'
            })
            .join(',')
        }
        if (
          column.reviewStatus === 0 ||
          column.reviewStatus === '0' ||
          (column.reviewStatus === 90 || column.reviewStatus === '90') ||
          (column.returnBridgeStatus === 90 ||
            column.returnBridgeStatus === '90')
        ) {
          let layout = this.operateBtnLayout.split(',')
          return layout
            .filter(it => {
              return it !== 'R'
            })
            .join(',')
        } else {
          return this.operateBtnLayout
        }
      } else {
        return this.operateBtnLayout
      }
    },
    rowClick (row, column, event) {
      this.$emit('onMouseOver', row, column, event)
    },
    loadTableData: function () {
      let $this = this
      $this.vLoading = true
      if (this.setDatasource) {
        this.buildTableData(this.sourceData)
        $this.vLoading = false
        return
      }
      if (!this.api) {
        $this.vLoading = false
        return
      }
      if (this.showPage) {
        this.api[this.loadPage](this.queryParas)
          .then(res => {
            if (res.success) {
              if (res.data && res.data.datas) {
                if (
                  $this.operateBtnLayout.indexOf('R') > -1 &&
                  res.data.datas.length > 0
                ) {
                  this.currentTotal = res.data.totalRow
                  $this.buildTableData(res.data.datas, res.data.totalRow)
                  $this.$emit('getTableData', res.data.datas)
                  $this.vLoading = false
                } else {
                  $this.buildTableData(res.data.datas, res.data.totalRow)
                  $this.$emit('getTableData', res.data.datas)
                  $this.vLoading = false
                }
              } else {
                $this.vLoading = false
              }
            } else {
              $this.error(res.errmsg || '获取数据失败')
              $this.vLoading = false
            }
          })
          .catch(function () {
            $this.vLoading = false
          })
      } else {
        this.api
          .getList(this.queryParas)
          .then(res => {
            if (res.success) {
              if (
                $this.operateBtnLayout.indexOf('R') > -1 &&
                res.data.length > 0
              ) {
                $this.buildTableData(res.data)
                $this.$emit('getTableData', res.data)
                $this.vLoading = false
              } else {
                $this.buildTableData(res.data)
                $this.$emit('getTableData', res.data)
                $this.vLoading = false
              }
            } else {
              $this.error(res.errmsg || '获取数据失败')
              $this.vLoading = false
            }
          })
          .catch(function () {
            $this.vLoading = false
          })
      }
    },
    selectionChange: function (selection) {
      this.selectionData = selection
      this.$emit('update:selectedRows', selection)
      this.$emit('selectRowChange', selection)
      this.disabledAllCheck()
    },
    buildTableData: function (data, total = null) {
      this.disabledAllCheck()
      if (!data || data.length < 0) {
        return
      }
      this.currentTotal = total || data.length
      this.tableDatas = data
      if (this.value && this.value.length > 0 && this.currentTotal > 0) {
        let $this = this
        this.tableDatas.forEach(function (item) {
          if (item && item.id) {
            this.value.forEach(v => {
              if (v && v.id && v.id === item.id) {
                $this.$refs.vueTable.toggleRowSelection(item, item.sysStatus)
              }
            })
          }
        }, this)
      }
      // 不显示delStatus为1的数据
      if (!this.delStatus) {
        this.tableDatas = this.tableDatas.filter(item => {
          if (item.delStatus === undefined) {
            return true
          } else {
            return item.delStatus !== '1'
          }
        })
      }
      this.$emit('update:sourceData', data)
    },
    handleSizeChange: function (value) {
      this.queryParas.pageSize = value
      this.queryParas.pageIndex = 1
      this.loadTableData()
    },
    handleCurrentChange: function (value) {
      this.queryParas.pageIndex = value
      this.loadTableData()
    },
    showCreate: function () {
      this.$emit('onCreateRow')
    },
    showDels: function () {
      let $this = this
      if (this.selectionData.length === 0) {
        $this.warning(`请先勾选要删除的数据!`)
        return
      }
      $this
        .$confirm('此操作会删除选中数据，是否继续？', '提示', {
          type: 'warning'
        })
        .then(() => {
          $this.$emit('onDelsRow', this.selectionData)
        })
    },
    handleFilter: function () {
      this.loadCount = this.loadCount + 1
    },
    operateBtnClick (returnData) {
      this.$emit(
        'onEditRow',
        returnData.rowIndex,
        returnData.rowData,
        returnData.clickType
      )
    },
    toggleSelection (rows) {
      let $this = this
      if (rows) {
        this.$nextTick(function () {
          rows.forEach(row => {
            $this.$refs.vueTable.toggleRowSelection($this.tableDatas[row])
          })
        })
      } else {
        this.$refs.vueTable.clearSelection()
      }
    },
    disabledAllCheck () {
      // 是否禁止全选按钮
      if (this.disabledAll) {
        this.$nextTick(() => {
          document.getElementsByClassName('el-checkbox__input')[0].classList.add('is-disabled')
          document.getElementsByClassName('el-checkbox__original')[0].disabled = true
          document.getElementsByClassName('common-table-header')[0].addEventListener('click', function () {
            event.stopImmediatePropagation()
          }, true)
        })
      }
    }
  }
}
</script>
<style scoped>
.dataTable .headTitle {
  margin: 4px 0;
  height: 40px;
  line-height: 40px;
  text-align: left;
  clear: both;
  position: relative;
}
.dataTable .btnLeft {
  float: left;
}
.dataTable .headButton {
  position: absolute;
  top: 0;
  right: 0;
}
</style>
