<template>
  <div class="table-box">
    <div
      v-if="tableTopButton.length > 0 || isNeedCustomcolumn"
      class="need-btn-line"
    >
      <!-- 列定制按钮 -->
      <el-button
        v-if="isNeedCustomcolumn"
        type="primary"
        size="small"
        @click="handlecustomcolumnOpen"
      >列定制</el-button>
      <!-- 自定义按钮 -->
      <el-button
        v-for="(value, i) in tableTopButton"
        :key="'$' + i"
        :style="{ fontSize: fontSize + 'px' }"
        size="small"
        :type="value.type || 'text'"
        :icon="value.icon"
        :class="value.class"
        @click="value.callback(value)"
      >{{ value.text }}</el-button>
    </div>
    <el-table
      ref="tableData"
      v-loading="loading"
      size="default"
      :row-key="rowKey"
      :style="{ width: '100%', fontSize: fontSize + 'px' }"
      :show-header="showHeader"
      :data="tableData"
      :height="tableHeight"
      :cell-style="cellStyle"
      :cell-class-name="tableCellClassName"
      :span-method="arraySpanMethod"
      :border="border"
      :highlight-current-row="highlightCurrentRow"
      v-bind="tableInfo"
      :stripe="isStripe"
      :tree-props="{
        children: treePropsChildren,
        hasChildren: treePropshasChildren,
      }"
      v-on="events"
      @selection-change="handleSelectionChange"
      @select-all="handleSelectionAllChange"
    >
      <slot name="expand" />
      <!-- 多选 -->
      <el-table-column
        v-if="needSelect"
        type="selection"
        width="30"
        :reserve-selection="isReserve"
      />
      <!-- 序号 -->
      <el-table-column
        v-if="hasIndex"
        label="序号"
        width="50"
        type="index"
      />

      <template v-for="(item, index) in tableColumn">
        <el-table-column
          :key="'%' + index"
          :show-overflow-tooltip="!item.notTooltip"
          v-bind="item"
          v-on="events"
        >
          <!-- 头部 -->
          <template
            slot="header"
            slot-scope="scope"
          >
            <i
              v-if="item.tableTopColumnIcon"
              :class="item.tableTopColumnIcon"
              @click="handleTableTopColumnIconClick(item,index)"
            />
            {{ item.label }}
            <span v-if="item.tableTopColumnCheck">
              <el-checkbox
                v-model="item.tableTopColumnCheckValue"
                :v-bind="item.tableTopColumnCheckValue"
                :indeterminate="false"
                @change="(val)=>
                  handleTableTopColumncheckChange(item,index,val)"
              />
            </span>

          </template>

          <template slot-scope="scope">
            <!-- render 函数式 -->
            <template v-if="item.render">
              <ex-slot
                :render="item.render"
                :index="scope.$index"
                :row="scope.row"
                :column="item"
                :class="item.prop"
                :default-value="item.defaultValue"
              />
            </template>

            <!-- progress 进度条 -->
            <template v-else-if="item.progress">
              <el-progress :percentage="parseFloat(scope.row[item.prop])" />
            </template>

            <!-- formatter 自定义 -->
            <template v-else-if="item.formatter">
              <span v-html="item.formatter(scope.row, item)" />
            </template>

            <!-- checkbox -->
            <template v-else-if="item.tableTopColumnCheck">
              <el-checkbox
                v-model="scope.row[item.prop]"
                @change="(val)=>
                  handleTableTopColumnRowcheckChange(scope,index,val)"
              />
            </template>

            <!-- 正常列 -->
            <template v-else>
              <span>
                {{ scope.row[item.prop] }}
              </span>
            </template>
          </template>

        </el-table-column>
      </template>
      <!-- 操作 -->
      <el-table-column
        v-if="hasOperation"
        label="操作"
        :min-width="operationWidth"
        :fixed="operationFixed ? 'right' : false"
        align="center"
      >
        <template
          v-if="btnButton.length"
          slot-scope="{ row, column, $index }"
        >
          <el-button
            v-for="(value, i) in btnButton"
            :key="'$' + i"
            :style="{ fontSize: fontSize + 'px' }"
            size="small"
            :type="value.type || 'text'"
            :icon="value.icon"
            :class="value.class || 'el-text-color'"
            @click="value.callback(row, column, $index)"
          >{{ value.text }}</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <div
      v-if="isNeedPagination"
      :style="{
        display: 'flex',
        justifyContent: operatedString ? 'space-between' : 'flex-end',
        alignItems: 'center',
        width: '100%',
      }"
    >
      <div
        v-if="operatedString"
        class="operated"
      >{{ operatedString }}</div>
      <el-pagination
        ref="pagination"
        class="no-border-top"
        :page-sizes="pageSizes"
        :page-size.sync="computedPageSize"
        :hide-on-single-page="isSinglePageHide"
        layout="total, sizes, prev, pager, next, jumper"
        :current-page.sync="computedCurrentPage"
        :total="total"
        :small="small"
        :pager-count="pagerCount"
        @current-change="currentChange"
        @size-change="sizeChange"
      />
    </div>
    <el-drawer
      title="数据列"
      :visible.sync="drawer"
      direction="rtl"
      :before-close="handlecustomcolumnClose"
    >
      <div
        v-for="(item, index) in tableData"
        :key="index"
        class="drawer-custom"
      >
        <el-checkbox v-model="item.check">{{ item.label }}</el-checkbox>
      </div>
      <div class="drawer-footer">
        <el-button
          size="mini"
          class="drawer-footer-confirm-btn"
          type="primary"
          @click="handlecustomcolumnConfirm"
        >确定</el-button>
        <el-button
          size="mini"
          class="drawer-footer-cancel-btn"
          @click="handlecustomcolumnCancel"
        >取 消</el-button>
      </div>
    </el-drawer>
  </div>
</template>
<script>
// 自定义组件的内容
const exSlot = {
  functional: true,
  props: {
    row: Object,
    render: Function,
    index: Number,
    column: {
      type: Object,
      default: null,
    },
  },
  render: (h, ctx) => {
    const params = {
      row: ctx.props.row,
      index: ctx.props.index,
    };
    if (ctx.props.column) params.column = ctx.props.column;
    return ctx.props.render(h, params);
  },
};

export default {
  name: 'PublicTable',
  components: {
    'ex-slot': exSlot,
  },
  props: {
    // key（唯一key值，和reserve-selection搭配使用）
    rowKey: {
      type: [Object, Function],
      default: () => ({}),
    },
    // 多选框是否记住上一页数据(必须与row-key唯一值搭配使用)
    isReserve: {
      type: Boolean,
      default: false,
    },
    // 单元格的 style 的回调方法
    cellStyle: {
      type: [Object, Function],
      default: () => ({}),
    },
    pagerCount: {
      type: Number,
      default: 7,
    },
    // 是否显示表头
    showHeader: {
      type: Boolean,
      default: true,
    },
    // 是否要高亮当前行
    highlightCurrentRow: {
      type: Boolean,
      default: true,
    },
    // 获取表格行列索引值
    tableCellClassName: {
      type: Function,
      default: () => {},
    },
    // 合并行或列
    arraySpanMethod: {
      type: Function,
      default: () => {},
    },
    // 是否需要多选
    needSelect: {
      type: Boolean,
      default: false,
    },
    // 是否需要序号
    hasIndex: {
      type: Boolean,
      default: false,
    },
    // 默认是否选中第一列
    isSetCurrentRow: {
      type: Boolean,
      default: false,
    },
    // 是否需要分页
    isNeedPagination: {
      type: Boolean,
      default: false,
    },
    // 是否需要 列定制 按钮
    isNeedCustomcolumn: {
      type: Boolean,
      default: false,
    },
    // 是否单页隐藏，默认为true
    isSinglePageHide: {
      type: Boolean,
      default: true,
    },
    // 当前页页码，支持.sync修饰符
    currentPage: {
      type: Number,
      default: 1,
    },
    // 每页数据条数, 支持.sync修饰符默认为每页10条
    pageSize: {
      type: Number,
      default: 20,
    },
    // 数据总条数
    total: {
      type: Number,
      default: 0,
    },
    // 每页多少数据
    pageSizes: {
      type: Array,
      required: false,
      default: () => [10, 20, 50, 100],
    },
    tableInfo: {
      type: Object,
      default: () => {},
    },
    // 获取数据时是否需要加载loading
    loading: {
      type: Boolean,
      default: false,
    },
    tableData: {
      type: Array,
      default: () => [],
    },
    // 表格展示数据
    tableColumn: {
      type: Array,
      default: () => [],
    },
    // 是否需要操作列
    hasOperation: {
      type: Boolean,
      default: true,
    },
    // 是否需要边框
    border: {
      type: Boolean,
      default: false,
    },
    // 操作 自定义按钮
    btnButton: {
      type: Array,
      default: () => [],
    },
    // 表格顶部自定义按钮
    tableTopButton: {
      type: Array,
      default: () => [],
    },
    // 操作列宽度
    operationWidth: {
      type: String,
      default: '60px',
    },
    // 固定操作栏
    operationFixed: {
      type: [Boolean, String],
      default: false,
    },
    // 表格方法
    events: {
      type: Object,
      default: () => {},
    },
    // 是否为斑马纹 table
    isStripe: {
      type: Boolean,
      default: true,
    },
    // 树结构(树结构必须有rowKey)
    treePropsChildren: {
      type: String,
      default: 'children',
    },
    // 树结构(树结构必须有rowKey)
    treePropshasChildren: {
      type: String,
      default: 'hasChildren',
    },
    // 点击图标计算的值
    operatedString: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      fontSize: sessionStorage.getItem('fontSize') || '',
      drawer: false,
      checked: false,
    };
  },
  computed: {
    computedCurrentPage: {
      get() {
        return this.currentPage;
      },
      set(val) {
        this.$emit('update:currentPage', val);
      },
    },
    computedPageSize: {
      get() {
        return this.pageSize;
      },
      set(val) {
        this.$emit('update:pageSize', val);
      },
    },
    tableHeight() {
      return this.tableInfo?.tableHeight ? this.tableInfo?.tableHeight : !this.isNeedPagination ? '100%' : 'calc(100% - 47px)';
    },
  },
  watch: {
  },
  mounted() {
    if (this.isSetCurrentRow) {
      setTimeout(() => {
        this.$refs.tableData.setCurrentRow(this.tableData[0]);
      }, 500);
    }
  },
  methods: {
    getTableRef() {
      return this.$refs.tableData;
    },
    currentChange(val) {
      this.$emit('currentChange', val);
    },
    sizeChange(val) {
      this.$emit('sizeChange', val);
    },
    handlecustomcolumnOpen() {
      this.drawer = true;
    },
    handlecustomcolumnClose(done) {
      done();
    },
    handlecustomcolumnCancel() {
      this.drawer = false;
    },
    handlecustomcolumnConfirm() {
      this.drawer = false;
      this.$emit('customColumnChange', this.tableData);
    },
    handleTableTopColumnIconClick(item, index) {
      this.$emit('handleTableTopColumnIconClick', item, index);
    },
    handleTableTopColumncheckChange(item, index, val) {
      this.$emit('handleTableTopColumncheckChange', item, index, val);
    },
    handleTableTopColumnRowcheckChange(item, index, val) {
      this.$emit('handleTableTopColumnRowcheckChange', item, index, val);
    },
    handleSelectionChange(row) {
      this.$emit('handleSelectionChange', row);
    },
    handleSelectionAllChange(row) {
      this.$emit('handleSelectionAllChange', row);
    },
  },
};
</script>
<style lang="scss" scoped>
.table-box {
  margin-top: 12px;
  background-color: #fff;
  border: 1px solid #dfe6ec;
}

.need-btn-line {
  padding: 8px;
}

::v-deep .el-table td {
  padding: 0;
  height: 40px;
}

// // table选中行高亮
// ::v-deep .el-table__body tr.current-row {
//   .flex_div {
//     background: rgba(21, 91, 212, 0.3) !important;
//   }
//   td {
//     background: rgba(21, 91, 212, 0.3) !important;
//   }
//   td {
//     background: rgba(21, 91, 212, 0.2) !important;
//   }
// }

::v-deep .el-pagination {
  margin-right: 8px;
}

.drawer-custom {
  padding: 8px 16px;
}
.drawer-footer {
  position: absolute;
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 60px;
  .drawer-footer-confirm-btn,
  .drawer-footer-cancel-btn {
    margin-right: 12px;
  }
}
.operated {
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 12px;
  width: 50%;
}
</style>
