<!-- 封装数据表格组件 -->
<template>
  <div>

    <el-table
      size="small"
      ref="tableRef"
      :data="tableList"
      :border="border"
      :stripe="stripe"
      v-loading="loading"
      element-loading-text="数据加载中..."
      :highlight-current-row="highlightCurrentRow"
      :row-class-name="tableRowClassName"
      @selection-change="handleSelectionChange"
      @row-click="rowClick"
      style="width: 100%">
      <el-table-column type="selection" width="50" align="center" v-if="dataSelection"></el-table-column>
      <el-table-column type="index" label="序号" width="55" align="center" v-if="dataIndex"></el-table-column>

      <!-- 表格数据列：插槽 -->
      <slot></slot>
    </el-table>
    <!-- 分页 -->
    <div class="block" v-if="!dataNoPage">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :layout="layout"
        prev-text="上一页"
        next-text="下一页"
        :total="total"
        :current-page="tablePage.page"
        :page-size="tablePage.limit"
        :page-sizes="pageSizes">
      </el-pagination>
    </div>

  </div>
</template>

<script>
  export default {
    name: 'data-table',
    props: {
      //数据主键列
      dataPkColumn: {
        type: String,
        required: true,
        default: function() {
          return 'id';
        }
      },
      //是否显示多选按钮列
      dataSelection: {
        type: Boolean,
        default: true
      },
      //是否显示序号列
      dataIndex: {
        type: Boolean,
        default: true
      },
      //表格url
      dataUrl: {
        type: String,
        default: function() {
          return '';
        }
      },
      //表格数据
      tableData: {
        type: Array,
        default: function() {
          return [];
        }
      },

      //加载进度
      vLoading: {
        type: Boolean,
        default: false
      },

      //表格边框
      border: {
        type: Boolean,
        default: true
      },
      //是否为斑马纹
      stripe: {
        type: Boolean,
        default: false
      },
      //是否要高亮当前行
      highlightCurrentRow: {
        type: Boolean,
        default: false
      },

      /**
       * 是否不需要分页
       *  true 不需要
       *  false 默认，需要
       */
      dataNoPage: {
        type: Boolean,
        default: false
      },
      //分页显示的内容
      layout: {
        type: String,
        default: function() {
          return 'sizes, total, prev, pager, next, jumper';
        }
      },
      //总数
      totalNum: {
        type: Number,
        default: function() {
          return 0;
        }
      },
      //当前页
      currentPage: {
        type: Number,
        default: function() {
          return 1;
        }
      },
      //选中每页显示数量
      pageSizes: {
        type: Array,
        default: function() {
          return [10, 20, 30, 50, 100];
        }
      },
      //每页显示数量
      pageSize: {
        type: Number,
        default: function() {
          return 20;
        }
      },
    },
    data(){
      return {
        loading: this.vLoading,    //加载进度条

        tableUrl: this.dataUrl,   //查询url
        tableList: this.tableData,  //列表数据
        total: this.totalNum,      //数据总数
        tablePage: {
          page: this.currentPage,  //当前页
          limit: this.pageSize,   //每页多少条
        },

        multipleSelection: [],    //已勾选的数据
      }
    },
    mounted(){
      this.loadTable();
    },
    //监听器
    watch: {
      dataUrl: function(val){
        this.tableUrl = val;
        this.loadTable();
      },
      tableData: function(val) {
        this.tableList = val;
        if(this.totalNum == 0){
          this.total = val.length;
        }
      },
      totalNum: function(val){
        this.total = val;
      },
      currentPage: function(val) {
        this.tablePage.page = val;
      },
      pageSize: function(val) {
        this.tablePage.limit = val;
      },
      vLoading: function(val) {
        this.loading = val;
      },
    },
    methods: {
      /**
       * 加载列表
       */
      loadTable() {
        this.loading = true;

        if(this.tableUrl){
          this.$http.get(this.tableUrl, this.tablePage).then((res) => {
            let datas = res.data;
            if(datas.code == 0){
              this.tableList = datas.data;
              this.total = datas.count;
              this.loading = false;
            }
          });
        }else{
          this.tableList = this.tableData;
          if(this.totalNum == 0){
            this.total = this.tableData.length;
          }
          this.loading = false;
        }
      },

      /**
       * 设置查询参数
       * @param {Object} name  参数名称
       * @param {Object} value 参数值
       */
      setQueryParam(name, value){
        if(!name){
          return;
        }

        if(!value){
          value = null;
        }

        this.tablePage[name] = value;
      },

      /**
       * 选择每页多少条
       */
      handleSizeChange(val) {
        this.tablePage.limit = val;
        this.$emit('size-change', val);
        this.loadTable();
      },

      /**
       * 选择第几页
       */
      handleCurrentChange(val) {
        this.tablePage.page = val;
        this.$emit('current-change', val);
        this.loadTable();
      },

      /**
       * 勾选
       */
      handleSelectionChange(val) {
        this.multipleSelection = val;
        this.$emit('selection-change', {val:val});
      },

      /**
       * 表格行选中样式
       */
      tableRowClassName({ row, rowIndex }) {
        let color = "";

        this.multipleSelection.forEach((item, i) => {
          if (item[this.dataPkColumn] == row[this.dataPkColumn]) {
            color = "selected-row";
          }
        });

        return color;
      },

      /**
       * 获取勾选的数据
       */
      getSelectionData() {
        return this.multipleSelection;
      },

      /**
       * 清空勾选的数据
       */
      clearSelectionData() {
        this.$refs['tableRef'].clearSelection();
        this.multipleSelection = [];
      },

      /**
       * 获取所有数据
       */
      getAllData() {
        return this.tableList;
      },

      /**
       * 行点击事件
       */
      rowClick(row, column, event) {
        //调用父组件的方法
        this.$emit('row-click', row, column, event);
      },

      /**
       * 用于单选表格，设定某一行为选中行
       * 参数为空，则会取消目前高亮行的选中状态
       * @param {Object} row
       */
      setCurrentRow(row){
        this.$emit('setCurrentRow', row);
      },

      /**
       * 根据主键删除
       * @param {Object} url  删除url
       * @param {Function} callback  回调函数
       */
      deleteById(url, callback){
        if(!url){
          this.$message.warning('删除URL不能为空');
          return;
        }

        var datas = this.getSelectionData();
        if(datas.length == 0){
          this.$message.warning('请至少选中一条数据');
          return;
        }

        this.loading = true;
        var arr = [];
        for (const v of datas) {
          arr.push(v[this.dataPkColumn]);
        }
        var ids = arr.join();

        this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'error'
        }).then(() => {
          var params = {
            ids: ids
          };
          this.$http.get(url, params).then((res) => {
            let datas = res.data;
            if(datas.code == 0){
              if(callback && typeof callback === 'function'){
                callback(datas);
              }else{
                this.$message.success('删除成功');
                this.loadTable();
              }
            }
            this.loading = false;
          });
        }).catch(() => {
          this.$message.info("已取消！");
          this.loading = false;
        });
      },

    },
  }
</script>

<style scoped>
  .block{
    margin-left: -10px;
    margin-bottom: 10px;
  }
</style>

<style>
  .selected-row{
    background-color: darkturquoise !important;
  }
</style>
