<template>
  <el-row>
    <el-col>
      <el-table :data="data" border :height="height" @selection-change="toSelect">
        <el-table-column type="selection" width="55" v-if="select"> </el-table-column>
        <template v-for="f in fields" :key="f.model">
          <el-table-column v-if="f.custom" :label="f.label" :prop="f.model" align="center" v-bind="f.options">
            <template v-slot="{ row }">
              <slot :name="f.model" v-bind="{ f, row }"></slot>
            </template>
          </el-table-column>
          <el-table-column v-else :label="f.label" :prop="f.model" align="center" :formatter="toFormatter"></el-table-column>
        </template>
        <el-table-column :label="$t('common.opera')" align="center" v-if="opera.length > 0">
          <template v-slot="{ row, $index }">
            <slot v-bind="{ row }">
              <template v-for="f in opera">
                <template v-if="display(f, row)">
                  <el-link :key="f.method" :type="f.type || 'primary'" size="small" :underline="false" class="link" v-method="f.method" @click="handleOpera(f, row, $index)">
                    {{ f.label }}
                  </el-link>
                </template>
              </template>
            </slot>
          </template>
        </el-table-column>
      </el-table>
    </el-col>
  </el-row>
  <el-row justify="end">
    <el-pagination
      background
      layout="total, prev, pager, next"
      :page-sizes="[10, 20, 50, 100, 200]"
      :total="total"
      :page-size="limit"
      v-model:current-page="currentPage"
      @current-change="changePage"
      @size-change="sizeChange"
    >
    </el-pagination>
  </el-row>
</template>
<script setup>
import { isFunction, get, isString, cloneDeep } from 'lodash-es'
const props = defineProps({
  data: { type: Array, default: () => [] },
  height: { type: String, default: '60vh' },
  fields: { type: Array, default: () => [] },
  opera: { type: Array, default: () => [] },
  total: { type: Number, default: 0 },
  limit: { type: Number, default: 10 },
  select: { type: Boolean, default: false }
})
const emit = defineEmits(['query', 'toSelect'])
const toSelect = (val) => {
  emit(`toSelect`, val)
}

const handleOpera = (field, data, index) => {
  let { method, confirm = false, methodZh, label, confirmWord } = cloneDeep(field)
  if (isFunction(methodZh)) methodZh = methodZh(data)
  else if (isString(methodZh)) {
    methodZh = label
  }
  if (confirm) {
    let word = methodZh ? methodZh : `您确认${label}该数据?`
    if (confirmWord) word = confirmWord
    ElMessageBox.confirm(word, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
      .then(() => {
        emit(method, cloneDeep(data), index)
      })
      .catch(() => {})
  } else emit(method, cloneDeep(data), index)
}

/**
 * 根据field中的 format函数 格式化该单元格数据
 * @param {Object} row 本行数据
 * @param {Object} column 本列实例
 * @param {any} cellValue 该单元格原数据
 */
const toFormatter = (row, column, cellValue) => {
  // 先找到field
  const fields = get(props, 'fields')
  if (!fields) return cellValue
  let this_field = fields.find((fil) => fil.model === column.property)
  if (!this_field) return cellValue
  // 再找field中format函数
  let format = get(this_field, `format`, false)
  if (!format) return cellValue
  if (isFunction(format)) {
    const formatResult = format(cellValue, row, this_field)
    return formatResult
  }
}
const display = (field, row) => {
  let display = get(field, `display`, true)
  if (display === true) return true
  else {
    let res = display(row)
    return res
  }
}
const currentPage = ref(1)
// 分页
const changePage = (page = currentPage.value) => {
  emit('query', { skip: (page - 1) * props.limit, limit: props.limit })
}
</script>
<style scoped>
.el-row {
  padding-top: 20px;
}
.link {
  padding: 0 5px 0 0;
}
.page {
  margin: 10px 0 0 0;
}
</style>
