<template>
  <div class="table-wrap" v-loading='loading'>
    <div class="table-page-search-wrapper" v-if="condition.length">
      <el-form :inline="true" class="demo-form-inline" label-width='80px' size="small">
        <el-row :gutter='10'>
          <el-col :span='span' v-for='v in condition' :key='v.dataIndex'>
            <el-form-item :label="layout === 'include' ? '' : v.title" style="display: flex">
              <el-input v-model='queryParam[v.dataIndex]' :placeholder="layout === 'include' ? v.title : '请输入'"
                v-if="v.type === 'input'" clearable />
              <el-date-picker v-model='queryParam[v.dataIndex]' valueFormat="YYYY-MM-DD"
                v-else-if="v.type === 'time-range'" :placeholder="layout === 'include' ? v.title : '请选择'" />
              <el-select v-model='queryParam[v.dataIndex]' :placeholder="layout === 'include' ? v.title : '请选择'"
                :default-value='v.defaultValue' v-else-if="v.type === 'select'" clearable>
                <el-option :value='v1.value' :label="v1.label" v-for='v1 in v.options' :key='v1.value'></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span='24 - condition.length % (24 / span) * span'>
            <span class="table-page-search-submitButtons">
              <el-button type="primary" @click='onQueryClick' size="small">
                查询
              </el-button>
              <el-button style="margin-left: 8px" @click='reset' size="small">
                重置
              </el-button>
              <slot name='append-btn'></slot>
            </span>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <el-table :data='tableData' style="margin: 6px 0;" v-bind="$attrs" v-on='$listeners' ref='table'>
      <el-table-column type="selection" width="55" v-if="isSelection">
      </el-table-column>
      <el-table-column v-bind='v' :prop='v.dataIndex' :label='v.title' v-for="(v, i) in columns" :key='i'>
        <template slot-scope="scope">
          <!-- 格式化函数 -->
          <span
            v-if="v.scopedSlots && v.scopedSlots.customRender && Object.prototype.toString.call(v.scopedSlots.customRender) === '[object Function]'">
            {{ v.scopedSlots.customRender(scope.row[v.dataIndex], scope.row, scope.$index) }}
          </span>
          <!-- 格式化插槽 -->
          <slot v-else-if="v.scopedSlots && v.scopedSlots.customRender" v-bind='scope' :name="v.scopedSlots.customRender">
          </slot>
          <span v-else>{{ scope.row[v.dataIndex] }}</span>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination :layout="paginationSize === 'mini' ? 'prev, pager, next' : 'total, sizes, prev, pager, next, jumper'"
      :currentPage.sync='localPagination.currentPage' :pageCount.sync='localPagination.totalPage'
      :style="paginationSize === 'mini' ? 'display: flex;justify-content: center;' : 'display: flex;justify-content: flex-end;'"
      :page-sizes="[5, 10, 20, 30, 50]" @size-change="queryTable" @current-change="queryTable" v-if='showPagination'>
    </el-pagination>
  </div>
</template>

<script>
export default {
  name: 'BaseTable',
  props: {
    columns: {
      default: () => [],
      required: true,
    },
    condition: {
      default: () => [],
      required: false
    },
    queryFunction: {
      required: false
    },
    pagination: {
      required: false,
      default: () => ({
        pageSize: 10,
      }),
    },
    paginationText: {
      required: false,
      default: () => ({
        currentPage: 'currentPage', total: 'total', totalPage: 'totalPage', data: 'data'
      }),
    },
    span: {
      required: false,
      default: 6
    },
    paginationSize: {
      required: false,
      default: 'small'
    },
    layout: {
      required: false,
      default: 'normal'
    },
    // 无需查询的静态数据
    injectData: {
      required: false,
      default: null
    },
    isSelection: {
      required: false,
      default: false
    },
    rowKey: {
      required: false,
      default: 'id'
    },
  },
  data() {
    return {
      tableData: [],
      queryParam: {}, // 暂存
      confirmParam: {}, // 点击查询键后赋值

      localPagination: Object.assign({
        currentPage: 1,
        total: 10
      }, this.pagination),
      loading: false,

      selectedRows: [],
      selectedRowKeys: [],

      showPagination: true
    };
  },
  async created() {
    this.condition.forEach(v => {
      v.defaultValue && this.$set(this.queryParam, v.dataIndex, v.defaultValue)
    })
    if (this.injectData) {
      this.tableData = this.injectData
      this.showPagination = false
    } else {
      this.queryTable()
    }
  },
  watch: {
    injectData: {
      handler(v) {
        this.tableData = v
      },
      deep: true
    }
  },
  methods: {
    async submit() {
    },
    onQueryClick() {
      this.confirmParam = JSON.parse(JSON.stringify(this.queryParam))
      this.localPagination.currentPage = 1
      this.queryTable()
    },
    async queryTable() {
      this.loading = true
      try {
        const { confirmParam, paginationText, localPagination } = this
        const queryParamFilter = {}
        Object.keys(confirmParam).forEach(key => confirmParam[key] && (queryParamFilter[key] = confirmParam[key]))
        const queryResult = await this.queryFunction(
          {
            [paginationText.currentPage]: localPagination.currentPage,
            query: queryParamFilter
          }
        )
        this.tableData = queryResult[paginationText.data]
        this.localPagination = {
          currentPage: queryResult[paginationText.currentPage],
          total: queryResult[paginationText.total],
          totalPage: queryResult[paginationText.totalPage]
        }
      } finally {
        this.loading = false
      }
    },
    reset() {
      this.queryParam = {}
      this.confirmParam = {}
      this.queryTable()
    },
    /**
     * 表格重新加载方法
     * 如果参数为 true, 则强制刷新到第一页
     * @param Boolean bool
     */
    refresh(bool = false) {
      bool && (this.localPagination.currentPage = 1)
      this.queryTable()
    },
    test(v) {
      console.log(v)
    }
  },
};
</script>

<style lang="scss" scoped></style>