<!--
 * @Company: 沈阳信诚科技
 * @Email: html_venustar@163.com
 * @Author: Liuqiming
 * @Description: 公共表格组件，element二次封装
 * @LastEditors: Liuqiming
 * @LastEditTime: 2024-03-29 10:26:41
 * @Date: 2024-02-01 17:17:58
-->
<template>
  <div class="els-table els-table-container">
    <!-- 根据UI样式需求特殊处理表格筛选条件展示样式 -->
    <div ref="elsTableSearch">
      <el-row v-if="searchList.length > 0 && searchList.length === 1">
        <el-col :span="12" v-if="btnList.length > 0">
          <el-button v-for="item,i in btnList" :key="`${i}-${item.label}`" :type="item.type" :link="item.link" :plain="item.plain" @click="handlerClickBtn(item.met)" v-hasPermi="[item.hasPermi]">
            <el-icon :size="14" v-if="item.icon && item.icon !== ''" style="margin-right: 6px;">
              <component class="icons" :is="item.icon" ></component>
            </el-icon>
            {{ item.label }}
          </el-button>
        </el-col>
        <el-col :span="12">
          <els-form
            ref="tableSearchForm"
            :fieldList="searchList"
            :formOption="searchOptionNoBtn"
            @ok="handlerSearch"
            @cancel="handlerSearch"
            :style="{ float: btnList.length > 0 ? 'right' : 'left'}"
            :formLoading="tableLoading"
            @formChange="formChange"
          ></els-form>
        </el-col>
      </el-row>
      <div v-if="searchList.length > 1" :style="{ marginBottom: btnList.length > 0 ? '16px' : '0' }">
        <el-row>
          <el-col :span="24">
            <els-form :fieldList="searchList" :formOption="searchOption" @ok="handlerSearch" @cancel="handlerSearch" :formLoading="tableLoading" @formChange="formChange"></els-form>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-button v-for="item,i in btnList" :key="`${i}-${item.label}`" :type="item.type" :link="item.link" :plain="item.plain" @click="handlerClickBtn(item.met)" v-hasPermi="[item.hasPermi]">
              <el-icon :size="14" v-if="item.icon && item.icon !== ''" style="margin-right: 6px;">
                <component class="icons" :is="item.icon" ></component>
              </el-icon>
              {{ item.label }}
            </el-button>
          </el-col>
        </el-row>
      </div>
      <div v-if="searchList.length <= 0" :style="{ marginBottom: btnList.length > 0 ? '16px' : '0' }">
        <el-button v-for="item,i in btnList" :key="`${i}-${item.label}`" :type="item.type" :link="item.link" :plain="item.plain" @click="handlerClickBtn(item.met)" v-hasPermi="[item.hasPermi]">
          <el-icon :size="14" v-if="item.icon && item.icon !== ''" style="margin-right: 6px;">
            <component class="icons" :is="item.icon" ></component>
          </el-icon>
          {{ item.label }}
        </el-button>
      </div>
      <div class="select-items-box" v-if="option.checkList">
        <span class="select-box-label">已选：</span>
        <el-tag v-for="tag,i in selectTag" :key="i" closable @close="handleClose(tag)" style="margin-right: 6px;">
          {{ tag[option.checkKey] }}</el-tag>
      </div>
    </div>
    <toolBar
      v-if="!option.hidToolBar"
      :columns="columnSetList"
      :title="`${route.path}-${route.name || 'route'}-${option.name || 'toolBar'}`"
      :name="`${route.path}-${route.name || 'route'}-${option.name || 'toolBar'}`"
      @columnSetting="columnSetting" :loading="tableLoading"></toolBar>
    <!-- 表格 -->
    <el-table
      ref="elsTableContainer"
      :data="tableData"
      style="width: 100%;border: 1px solid #ebeef5;"
      :stripe="option.stripe"
      :border="true"
      :max-height="option.maxHeight || tableHeight"
      :row-key="
        (row) => {
          return row[option.rowKey];
        }
      "
      :header-cell-class-name="
        ({ row, column, rowIndex, columnIndex }) => {
          let className = ''
          if (option.checkMax && option.checkMax !== 0 && columnIndex == 0) {
            className = 'header-cell-disabledCheckedAll'
          }
          return className
        }
      "
      :header-cell-style="
        ({ row, column, rowIndex, columnIndex }) => {
          let style = {
            fontFamily: 'PingFang SC',
            fontSize: '14px',
            color: '#7B828E',
          }
          if (option.checkMax && option.checkMax !== 0 && columnIndex == 0) {
            style.pointerEvents = 'none'
          }
          return style
        }
      "
      @selection-change="handleSelectionChange"
      @select="selectionChange"
      @select-all="handleSelectAll"
      :select-on-indeterminate="false"
      :row-style="rowStyle"
      :row-class-name="tableRowClassName"
      :cell-style="cellStyle"
      v-loading="tableLoading"
    >
      <!-- checkbox列 -->
      <el-table-column
        v-if="option.checkbox"
        type="selection"
        width="56"
        align="center"
        :fixed="option.fixed"
      ></el-table-column>
      <!-- 序号列 -->
      <el-table-column
        v-if="option.index"
        type="index"
        width="56"
        label="序号"
        :align="option.align"
        :fixed="option.fixed"
      ></el-table-column>
      <!-- 遍历列 -->
      <template v-if="is_update && !option.hidToolBar">
        <tableColumn v-for="item in columnSetList" :key="item.prop" :item="item"></tableColumn>
      </template>
      <template v-if="option.hidToolBar">
        <tableColumn v-for="item in columns" :key="item.prop" :item="item"></tableColumn>
      </template>
    </el-table>
    <!-- 分页 -->
    <div class="table-footer">
      <div class="footer-text">
        <!-- {{ option.footer }} -->
        <Elsfooter></Elsfooter>
      </div>
      <Pagination
        @pagination="pagination"
        :hidden="option.pageHidden"
        :total="page.total"
        :page="page.pageNum"
        :limit="page.pageSize"
        :disabled="tableLoading"
      ></Pagination>
    </div>
  </div>
</template>

<script setup lang="jsx">
import tableColumn from './tableColumn'
import toolBar from './toolBar'
import { computed, nextTick, watch } from 'vue';
const route = useRoute();
const props = defineProps({
  // 按钮列参数
  btnList: {
    type: Array,
    default: () => []
  },
  // 查询条件表单配置
  searchOption: {
    type: Object,
    default: () => {
      return {
        inline:true,
        labelWidth: '80px',
        scrollToError: false,
        btn: ['search', 'reset']
      }
    }
  },
  // 查询条件配置
  searchList: {
    type: Array,
    default: () => []
  },
  // 表格列
  columns: {
    type: Array,
    default: () => [],
  },
  // 表格数据
  tableData: {
    type: Array,
    default: () => [],
  },
  // option　表格配置项
  option: {
    type: Object,
    default: () => {
      return {
        checkbox: true, // 是否展示多选框
        checkList: false, // 是否展示多选框选中数据
        checkKey: 'castTimesNo', // 展示多选框选中数据绑定的字段
        index: true, // 是否展示序号
        fixed: "left", // 是否将多选框及序号列固定在最左侧
        stripe: true, // 是否斑马纹表格
        border: true, // 是否表格边框
        pageHidden: false, // 是否隐藏分页
        maxHeight: '70vh', // 表格最大高度
        name: 'name', // 当一个路由地址下有多个表格组件，须传name字段，并保证name字段在项目中唯一
        hidToolBar: true, //是否隐藏自定义列按钮
      };
    },
  },
  // 页码设置
  pageSet: {
    type: Object,
    default: () => {
      return {
        pageNum: 1,
        pageSize: 10,
        total:0
      }
    }
  },
  // 加载状态
  tableLoading: {
    type: Boolean,
    default: false
  }
});
const { proxy } = getCurrentInstance();
const emit = defineEmits();
const searchData = ref({})
const selectTag = ref([])
const selectionList = ref([])
const elsTableContainer = ref(null)
const page = computed(() => props.pageSet)
const columnSetList = ref([])
const is_update = ref(true)
const tableHeight = ref('50vh')
// 如果表格筛选条件只有一个的话，隐藏搜索重置按钮
const searchOptionNoBtn = computed(() => {
  return  {
    ...props.searchOption.value,
    btn: []
  }
})
const Elsfooter = () => {
  const render = props.option?.slotFooter ? props.option?.slotFooter : function() { return <span></span> }
  return render()
}
watch(()=>[props.tableData,props.columns,props.option], ([tableDataVal,columnsVal,optionVal])=>{
  if(tableDataVal && tableDataVal.length){
    tableDataVal.forEach(ele => {
      selectTag.value.forEach(item => {
        if (ele[optionVal.rowKey] === item[optionVal.rowKey]) {
          nextTick(()=>{
            elsTableContainer.value?.toggleRowSelection(ele, true)
          })
        }
      })
    })
    columnSetList.value = columnSetList.value.length ? columnSetList.value : columnsVal
  }
},{deep:true, immediate:true})
// @desc 列设置按钮事件
const columnSetting = (val) => {
  is_update.value = false
  val = val.map((item,i) => ({...item, col_sort: i}))
  let list = []
  val.forEach(col => {
    columnSetList.value.forEach(item => {
      if (col.prop === item.prop) {
        list.push({
          ...item,
          checkBoxDisabled: col.checkBoxDisabled,
          hidden: col.hidden,
          col_sort: col.col_sort
        })
      }
    })
  })
  columnSetList.value = list
  // 解决列表排序数据更新但列表不更新的问题
  nextTick(() => {
    is_update.value = true
  })
}
// @desc 复选框高亮样式侦听
const tableRowClassName = ({ row, rowIndex }) => {
  let color = ''
  selectTag.value.forEach(item => {
    if (item[props.option.rowKey] === row[props.option.rowKey]) {
      color = 'table-SelectedRow-bgcolor'
    }
  })
  return props.option?.checkList ? color : ''
}
// @desc 复选框选中事件
const selectionChange = (selection, row) => {
  // console.log(selection, row)
  let selected = selection.length && selection.indexOf(row) !== -1;
  if (selected) {
    if (props.option.checkMax && selectTag.value.length < props.option.checkMax) {
      selectTag.value.push(row)
    } else if(!props.option.checkMax){
      selectTag.value.push(row)
    }
    if (props.option.checkMax && selectionList.value.length >= props.option.checkMax) {
      elsTableContainer.value?.toggleRowSelection(row, false)
      proxy.$modal.msgWarning(props.option.checkMaxMsg ? props.option.checkMaxMsg : '最多选择' + props.option.checkMax + '条数据')
    } else {
      selectionList.value.push(row)
    }
  } else {
    selectTag.value = selectTag.value.filter(item => item[props.option.rowKey] !== row[props.option.rowKey])
    selectionList.value = selectionList.value.filter(item => item[props.option.rowKey] !== row[props.option.rowKey])
  }
  emit('selectionChange', {selection, row}, (fn) => { fn() })
}
// @desc 复选框list变更事件
const handleSelectionChange = (val) => {
  emit('handleSelectionChange', val)
}
// @desc 关闭选中内容
const handleClose = (item) => {
  if (item) {
    selectTag.value.splice(selectTag.value.indexOf(item), 1)
    selectionList.value.splice(selectionList.value.indexOf(item), 1)
    props.tableData?.forEach(ele => {
      if (ele[props.option.rowKey] === item[props.option.rowKey]) {
        elsTableContainer.value?.toggleRowSelection(ele, false)
      }
    })
  }
}
// @desc 全选
const handleSelectAll = (selection) => {
  emit('selectAll', selection)
  // if (selection.length > props.option.checkMax) {
  //   proxy.$modal.msgWarning('无法使用全选功能，所选数据条数超出最大数量限制！')
  // }
  // if (props.option.checkMax && props.option.checkMax != 0) {
  //   elsTableContainer.value?.clearSelection()
  //   selectTag.value = []
  //   selectionList.value = []
  // }
}
// @desc 行样式回调
const rowStyle = (val) => {
  let style = {}
  emit('rowStyle', val, (data) => {
    style = data
  })
  return style
}
// @desc 单元格样式回调
const cellStyle = (val) => {
  let style = {}
  emit('cellStyle', val, (data) => {
    style = data
  })
  style.borderRight = 'none !important'
  return style
}
// @desc 分页函数
const pagination = (val) => {
  searchData.value.pageNum = val.page
  searchData.value.pageSize = val.limit
  page.value.pageNum = val.page
  page.value.pageSize = val.limit
  getTableData(searchData.value)
}
// @desc 查询按钮点击
const handlerSearch = (val) => {
  searchData.value = { pageSize: searchData.value.pageSize || 10 }
  Object.keys(val.value).forEach(item => {
    searchData.value[item] = val.value[item]
  })
  searchData.value.pageNum = 1
  searchData.value.pageSize = searchData.value.pageSize || 10
  getTableData(searchData.value)
}
// @desc 重获表格数据
const getTableData = (searchData) => {
  emit('getTableData', searchData)
}
// 表单元素变更事件
const formChange = (data) => {
  emit('formChange', data)
}
// 按钮组点击事件
const handlerClickBtn = (met) => {
  emit(met)
}
</script>

<style lang="scss" scoped>
.els-table-container{
  .select-items-box{
    width: 100%;
    min-height: 26px;
    padding: 16px 20px;
    margin-bottom: 20px;
    border-radius: 4px;
    background: #F5F7F9;
    .select-box-label{
      font-size: 14px;
      color: #7B828E;
      line-height: 26px;
    }
  }
  .el-table{
    border: none !important;
    :deep(.header-cell-disabledCheckedAll){
      .cell{
        display: none;
      }
    }
  }
  :deep(.table-SelectedRow-bgcolor){
    background: #E6EFFC !important;
    .el-table-fixed-column--left{
      background: transparent !important;
    }
    .el-table__cell{
      background: transparent !important;
    }
  }
  .table-footer{
    display: flex;
    justify-content: space-between;
    .footer-text{
      padding: 14px 0;
    }
    >div{
      width: 50%;
    }
  }
}

</style>
