<template>
  <div id="data-table">
    <el-table
      ref="table"
      row-key="id"
      :data="data"
      border
      stripe
      size="small"
      :max-height="height !== null ? height : ''"
      @select="handleSelectionChange"
      @select-all="handleSelectAll"
    >
      <el-table-column type="selection" width="55" v-if="select" prop="id" :reserve-selection="true"> </el-table-column>
      <template v-for="(item, index) in fields">
        <template v-if="item.custom">
          <el-table-column :key="index" align="center" :label="item.label" v-bind="item.options">
            <template v-slot="{ row, $index }">
              <slot name="custom" v-bind="{ item, row, $index }"></slot>
            </template>
          </el-table-column>
        </template>
        <template v-else>
          <el-table-column :key="index" align="center" :label="item.label" :prop="item.prop" :formatter="toFormatter" sortable v-bind="item.options">
          </el-table-column>
        </template>
      </template>
      <template v-if="opera.length > 0">
        <el-table-column label="操作" align="center">
          <template v-slot="{ row, $index }">
            <template v-for="(item, index) in opera">
              <template v-if="display(item, row)">
                <template v-if="item.icon">
                  <el-tooltip :key="index" effect="dark" :content="item.label" placement="bottom">
                    <el-button
                      :key="index"
                      type="text"
                      :icon="item.icon || ''"
                      size="mini"
                      @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)"
                    ></el-button>
                  </el-tooltip>
                </template>
                <template v-else>
                  <el-button :key="index" type="text" size="mini" @click="handleOpera(row, item.method, item.confirm, item.methodZh, item.label, $index)">
                    {{ item.label }}
                  </el-button>
                </template>
              </template>
            </template>
          </template>
        </el-table-column>
      </template>
    </el-table>
  </div>
</template>

<script>
import _ from 'lodash';
export default {
  name: 'data-table',
  props: {
    fields: { type: Array, required: true },
    data: { type: Array, required: true },
    opera: { type: Array, default: () => [] },
    toFormat: null,
    height: null,
    select: { type: Boolean, default: false },
    selected: { type: Array, default: () => [] },
  },
  components: {},
  data: () => ({
    pageSelected: [],
    selectFirst: true,
  }),
  created() {},
  computed: {},
  methods: {
    toFormatter(row, column, cellValue, index) {
      let this_fields = this.fields.filter(fil => fil.prop === column.property);
      if (this_fields.length > 0) {
        let format = _.get(this_fields[0], `format`, false);
        if (format) {
          let res;
          if (_.isFunction(format)) {
            res = format(cellValue);
          } else {
            res = this.toFormat({
              model: this_fields[0].prop,
              value: cellValue,
            });
          }
          return res;
        } else return cellValue;
      }
    },
    handleOpera(data, method, confirm = false, methodZh, label, index) {
      if (!method) return;
      let self = true;
      if (_.isFunction(methodZh)) {
        methodZh = methodZh(data);
      } else if (!_.isString(methodZh)) {
        methodZh = label;
        self = false;
      }
      if (confirm) {
        this.$confirm(self ? methodZh : `您确认${methodZh}该数据?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
          .then(() => {
            this.$emit(method, { data, index });
          })
          .catch(() => {});
      } else {
        this.$emit(method, { data, index });
      }
    },
    handleSelectionChange(selection, row) {
      // console.log(selection);
      // console.log(row);
      //根据row是否再pageSelected中,判断是添加还是删除
      let res = [];
      if (this.pageSelected.find(i => i.id === row.id)) {
        res = this.pageSelected.filter(f => f.id !== row.id);
      } else {
        this.pageSelected.push(row);
        res = this.pageSelected;
      }
      this.$set(this, `pageSelected`, res);
      this.$emit(`handleSelect`, _.uniqBy(res, 'id'));
    },
    handleSelectAll(selection) {
      //处于没全选状态,选择之后一定是全选,只有处于全选状态时,才会反选(全取消)
      // console.log(selection);
      let res = [];
      if (selection.length > 0) {
        //全选
        res = _.uniqBy(this.pageSelected.concat(selection), 'id');
      } else {
        //全取消
        res = _.differenceBy(this.pageSelected, this.data, 'id');
      }
      this.$set(this, `pageSelected`, res);
      this.$emit(`handleSelect`, res);
    },
    initSelection() {
      this.$nextTick(() => {
        this.$refs.table.clearSelection();
        this.selected.forEach(info => {
          let d = this.data.filter(p => p.id === info.id);
          if (d.length > 0) this.$refs.table.toggleRowSelection(d[0]);
        });
      });
    },
    selectReset() {
      this.$refs.table.clearSelection();
    },
    display(item, row) {
      let display = _.get(item, `display`, true);
      if (display === true) return true;
      else {
        let res = display(row);
        return res;
      }
    },
  },
  watch: {
    selected: {
      handler(val) {
        if (val.length > 0) {
          this.pageSelected = val;
          this.initSelection();
        }
      },
      immediate: true,
    },
    data: {
      handler(val, oval) {
        if (this.select) {
          this.initSelection();
        }
      },
    },
  },
};
</script>

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