<template>
  <div class="ai-table" :class="[isShowBorder ? 'ai-table__border' : 'ai-table__noborder']">
    <el-table :data="tableData"
              header-cell-class-name="ai-table__header"
              cell-class-name="ai-table__cell"
              row-class-name="ai-table__row"
              :class="{'ai-header__border': isShowBorder}"
              :ref="refName"
              :size="tableSize"
              :stripe="stripe"
              :tooltip-effect="tooltipEffect"
              @selection-change="handleSelectionChange"
              v-on="$listeners"
              v-bind="$attrs"
              v-loading="loading">
      <template v-for="colConfig in colConfigs.filter(e=>!e.hide)">
        <slot v-if="colConfig.slot && colConfig.slot !== 'options'" :name="colConfig.slot"/>
        <component
            :key="colConfig.id"
            v-else-if="colConfig.component"
            :is="colConfig.component"
            :col-config="colConfig">
        </component>
        <el-table-column v-else-if="colConfig.type" v-bind="colConfig" :width="colConfig.width||80" align="center"/>
        <el-table-column v-else v-bind="colConfig">
          <template slot-scope="{row,$index}">
            <span v-if="colConfig.dict" :style="{color:colConfig.color||dict.getColor(colConfig.dict, row[colConfig.prop])}" v-text="dict.getLabel(colConfig.dict, row[colConfig.prop])"/>
            <render-slot v-else-if="colConfig.render" :render="colConfig.render" :row="row" :index="$index" :column="colConfig"/>
            <el-input v-else-if="colConfig.edit" v-model="row[colConfig.prop]" size="small" placeholder="请输入" clearable/>
            <el-input v-else-if="colConfig.num" v-model.number="row[colConfig.prop]" size="small" placeholder="请输入" clearable/>
            <ai-select v-else-if="colConfig.select" v-model="row[colConfig.prop]" v-bind="colConfig.select"/>
            <ai-uploader v-else-if="colConfig.upload" v-model="row[colConfig.prop]" :limit="1" v-bind="colConfig.upload"/>
            <ai-open-data v-else-if="colConfig.openType" :type="colConfig.openType" :openid="row[colConfig.prop]"/>
            <span v-else>{{ getValue(colConfig, row) }}</span>
          </template>
        </el-table-column>
      </template>
      <slot class="table-options" name="options"/>
      <template #empty>
        <slot v-if="$scopedSlots.empty" name="empty"/>
        <div v-else class="no-data" style="height:160px;"/>
      </template>
    </el-table>
    <div class="pagination newPagination" v-if="isShowPagination">
      <el-pagination
          background
          :current-page="page.current"
          :total="page.total"
          :page-size="page.size"
          v-bind="$attrs"
          :page-sizes="pageSizes"
          :layout="layout"
          :pager-count="page.pagerCount"
          @size-change="handleSizeChange"
          @current-change="handleChange">
        <div class="paginationPre">
          <el-checkbox v-if="isHasPaginationBtnsSlot" :disabled="!tableData.length" :indeterminate="isIndeterminate"
                       :value="checkAll" @click.native="toggleAllSelection">全选
          </el-checkbox>
          <slot name="pagination"/>
          <div class="pagination-btns">
            <slot name="paginationBtns"></slot>
          </div>
          <div class="paginationPre-total" :style="{marginLeft: isHasPaginationBtnsSlot ? '24px' : 0}">共<label class="color-primary">{{ page.total }}</label>条记录
          </div>
        </div>
      </el-pagination>
    </div>
  </div>
</template>

<script>
import moment from 'dayjs'
import dict from "../../lib/js/dict"
import AiUploader from "./AiUploader.vue";

export default {
  name: 'AiTable',
  model: {
    prop: "tableData",
    event: "change"
  },
  props: {
    colConfigs: {type: Array, required: true},
    tableData: {type: Array, required: true, default: () => []},
    current: {default: 1},
    size: {default: 10},
    isShowPagination: {type: Boolean, default: true},
    total: Number,
    layout: {type: String, default: 'slot,->, prev, pager, next, sizes, jumper'},
    stripe: {type: Boolean, default: true},
    loading: {type: Boolean, default: false},
    tooltipEffect: String,
    tableSize: String,
    tableRef: String,
    dict: {default: () => dict},
    pagerCount: {default: 5},
    pageSizes: {default: () => [10, 20, 50, 100]},
    pageConfig: Object
  },
  data() {
    return {
      name: '',
      chooseList: [],
      defaultPage: {}
    }
  },
  components: {
    AiUploader,
    renderSlot: {
      functional: true,
      props: {
        row: Object,
        render: Function,
        index: Number,
        column: {type: Object, default: null},
      },
      render: (h, data) => {
        const params = {
          row: data.props.row,
          index: data.props.index
        }
        if (data.props.column) {
          params.column = data.props.column
        }
        return data.props.render(h, params)
      }
    }
  },
  computed: {
    refName: v => v.tableRef || `aiTable${new Date().getTime()}`,
    isShowBorder: v => !!v.$attrs.border || v.$attrs.border === '',
    isHasPaginationBtnsSlot: v => v.$scopedSlots.paginationBtns,
    isIndeterminate: v => v.chooseList.length > 0 && v.chooseList.length < v.tableData.length,
    checkAll: v => v.chooseList.length == v.tableData.length && v.tableData !== 0,
    page() {
      return {
        current: this.current,
        size: this.size,
        total: this.total,
        pagerCount: this.pagerCount,
        ...this.pageConfig
      }
    },
  },
  methods: {
    handleChange(current) {
      this.$emit('update:current', current)
      this.$emit('update:pageConfig', {...this.pageConfig, current})
      this.$nextTick(() => {
        this.$emit('getList')
      })
    },
    handleSizeChange(size) {
      this.$emit('update:size', size)
      this.$emit('update:pageConfig', {...this.pageConfig, size})
      this.$nextTick(() => {
        this.$emit('getList')
      })
    },
    handleSelectionChange(e) {
      this.chooseList = e
      this.$emit('handleSelectionChange', e)
    },
    getValue(colConfig, row) {
      if (typeof colConfig.format === 'function') {
        return colConfig.format.call(this, row[colConfig.prop], row)
      }
      if (colConfig.dateFormat) {
        return moment(row[colConfig.prop]).format(colConfig.dateFormat)
      }

      return row[colConfig.prop] === 0 || row[colConfig.prop] ? row[colConfig.prop] : '-'
    },
    /**
     * 表格方法代理
     */
    clearSelection() {
      this.$refs[this.refName].clearSelection()
    },
    toggleRowSelection() {
      this.$refs[this.refName].toggleRowSelection(...arguments)
    },
    toggleAllSelection() {
      this.$refs[this.refName].toggleAllSelection()
    },
    toggleRowExpansion() {
      this.$refs[this.refName].toggleRowExpansion(...arguments)
    },
    setCurrentRow() {
      this.$refs[this.refName].setCurrentRow(...arguments)
    },
    clearSort() {
      this.$refs[this.refName].clearSort()
    },
    clearFilter() {
      this.$refs[this.refName].clearFilter(...arguments)
    },
    doLayout() {
      this.$refs[this.refName].doLayout()
    },
    sort() {
      this.$refs[this.refName].sort(...arguments)
    },
  }
}
</script>

<style lang="scss" scoped>
.ai-table {
  .color-primary {
    color: $primaryColor;
  }

  :deep( .ai-header__border .ai-table__header ) {
    border-bottom: 1px solid $borderColor !important;
    border-right: 1px solid $borderColor !important;
  }

  :deep( .el-table--border ) {
    border: 1px solid $borderColor;
    border-right: none;
    border-bottom: none;
  }

  :deep( .el-table ) {
    color: #222;

    .caret-wrapper {
      height: 24px;

      .ascending {
        top: 1px;
      }

      .descending {
        bottom: 1px;
      }
    }

    thead {
      color: #555
    }
  }

  :deep( .cell ) {
    line-height: 24px;
  }

  :deep( .el-table__header ) {
    th {
      padding: 8px 0;
    }

    tr {
      .cell {
        font-weight: 700;
      }

      th:first-child {
        .cell {
          padding-left: 40px !important;
        }
      }
    }
  }

  :deep( .el-table__body ) {
    tr td:first-child .cell {
      padding-left: 40px !important;
    }

    .uploader {
      .el-upload-list__item {
        width: 100px;
        height: 32px;
        margin: unset;

        & > img {
          width: unset;
          margin-left: 50%;
          transform: translateX(-50%);
        }
      }

      .uploaderBox {
        width: 100px !important;
        height: 32px !important;
        flex-direction: row !important;
        gap: 4px;

        .iconfont {
          font-size: 24px !important;
        }
      }
    }
  }

  :deep( .el-table__fixed-right ) {
    .el-table__body {
      tr td:first-child .cell {
        padding-left: 0 !important;
        padding-right: 0;
      }
    }
  }

  :deep( .ai-table__header ) {
    border-bottom: none;
    background: #F3F4F5;
  }

  :deep(.el-pager ) {
    li.active + li {
      border-left: 1px solid $borderColor;
    }
  }

  .newPagination {
    width: 100%;
    display: flex;
    align-items: center;
    height: 64px;
    padding: 0 40px !important;

    .el-pagination {
      width: 100%;
      padding: 0;
    }

    .paginationPre {
      display: flex;
      height: 28px;
      line-height: 1;
      font-size: 14px;
      font-weight: normal;
      align-items: center;

      .pagination-btns {
        display: flex;
        align-items: center;
        gap: 8px;
        color: $primaryColor !important;

        :deep( span), :deep( div ) {
          font-size: 12px;
          cursor: pointer;
          color: $primaryColor !important;

          &:hover {
            opacity: 0.8;
          }
        }
      }

      .paginationPre-total {
        font-size: 12px;
        color: #555;

        label {
          padding: 0 2px;
          font-weight: 700;
        }
      }

      & > * + * {
        margin-left: 24px;
      }

      :deep( .el-pagination button), .el-pagination span:not([class*=suffix]) {
        line-height: 1 !important;
      }

      :deep(.el-checkbox ) {
        display: flex;
        align-items: center;

        .el-checkbox__input, .el-checkbox__inner {
          width: 14px;
          height: 14px;
          min-width: 0 !important;
          line-height: 1 !important;
        }

        .el-checkbox__label {
          font-size: 12px;
          color: #222222;
          height: auto !important;
          line-height: 1 !important;
          padding-left: 3px !important;
        }
      }
    }
  }
}

.ai-table__noborder {
  :deep( .el-table td), :deep( .el-table th.is-center ) {
    border: none;
  }

  .el-table::before {
    display: none;
  }

  :deep( .el-table--striped .el-table__body tr.el-table__row--striped td ) {
    background: #F5F6F9;
  }

  :deep( .el-table__fixed-right::before), :deep( .el-table__fixed::before ) {
    display: none;
  }
}
</style>
