<template>
  <div>
    <div class="flex">
      <el-table :data="tableObject.tableList" border style="flex: 1">
        <slot></slot>
      </el-table>
      <el-button
        ref="ColumnSetting"
        plain
        style="writing-mode: vertical-lr; height: 100px; letter-spacing: 2px"
        @click="clickSetting"
        >表格列控制</el-button
      >
      <el-popover
        ref="TableColumnPop"
        :virtual-ref="ColumnSetting"
        placement="left"
        width="120px"
        trigger="click"
        virtual-triggering
      >
        <el-checkbox-group v-model="checkedColumns" @change="confirm">
          <draggable
            v-model="allColumns"
            item-key="field"
            ghost-class="draggable-ghost"
            :animation="400"
            @end="onDragEnd"
          >
            <template #item="{ element: item }">
              <el-checkbox :key="item.field" :label="item.field">
                {{ item.label }}
              </el-checkbox>
            </template>
          </draggable>
        </el-checkbox-group>
      </el-popover>
    </div>
    <!-- 分页 -->
    <Pagination
      v-model:limit="pageSize"
      v-model:page="currentPage"
      :total="tableObject.total"
      @pagination="getList"
    />
  </div>
</template>

<script setup>
import draggable from 'vuedraggable'
import { useUserStore } from '@/store/modules/user'
import { useRoute } from 'vue-router'
import cache from '@/plugins/cache'

const props = defineProps({
  tableObject: { type: Object, default: () => ({ tableList: [] }) },
  tableColumns: { type: Array, default: () => [] }
})

const emit = defineEmits(['update:tableObject', 'getList', 'getCheckedColumns'])
const route = useRoute()
const { id: userId } = useUserStore().user //取用户ID

const currentPage = ref(props.tableObject?.currentPage || 1)

const pageSize = ref(props.tableObject?.pageSize || 20)

const ColumnSetting = ref()
const TableColumnPop = ref()
// 展示在设置里的所有表格列，由于会排序，所以使用新属性，不直接修改原值
const allColumns = ref({})
// 已勾选的选项
const checkedColumns = ref([])

// 调用获取数据的接口,分页时需要使用
function getList({ page, limit }) {
  emit('update:tableObject', { ...props.tableObject, currentPage: page, pageSize: limit })
  nextTick(() => {
    emit('getList')
  })
}

// 点击"表格列控制"按钮，出现设置页面
const clickSetting = () => {
  unref(TableColumnPop).TableColumnPop?.delayHide?.()
}

// 获取所有的表格列，注意如果本地有缓存使用缓存数据，因为用户可能已对表格列排序，并且不依赖网络请求，可更快渲染表头
function getAllColumns() {
  // 1. 先获取缓存表头
  const localData = getColumn('TableColumnAll')[route.name] || []
  // 2. 如果有缓存的表头，直接使用，并将新增的标题加入，如果没有缓存，那就得用获取到的表头
  if (localData && localData) {
    const newColumns = props.tableColumns.filter(
      (item) => !localData.some((it) => it.field == item.field)
    )
    allColumns.value = [...localData, ...newColumns]
  } else {
    allColumns.value = [...props.tableColumns]
  }
}
// 获取缓存的表头
function getColumn(name = 'shitTable') {
  return cache.local.get(`${name}-${userId}`) || {}
}
// 设置表头缓存
function setColumn(val, name = 'shitTable') {
  cache.local.set(`${name}-${userId}`, val)
}
// 获取用户已勾选的表头
function getUserCheckedColumns() {
  // 1. 先获取缓存
  const localData = getColumn('shitTable')[route.name]
  // 2. 如果有缓存，使用缓存表头，否则使用默认的所有表头
  if (localData && localData.length) {
    checkedColumns.value = localData
  } else {
    checkedColumns.value = allColumns.value.map((it) => it.field)
  }
  // 3. 回显到表格中
  emitColumns()
}

// 表格列排序
function onDragEnd() {
  const obj = getColumn('TableColumnAll')
  obj[route.name] = allColumns.value
  // 1. 设置缓存
  setColumn(obj, 'TableColumnAll')
  // 2. 表格回显
  emitColumns()
}

// 勾选确认
function confirm() {
  const obj = getColumn()
  obj[route.name] = checkedColumns.value
  setColumn(obj, 'shitTable')
  emitColumns()
}

// 将表头数据返回至父组件
function emitColumns() {
  const arr = allColumns.value.filter((item) => checkedColumns.value.includes(item.field))
  emit('getCheckedColumns', arr)
}

getAllColumns()
getUserCheckedColumns()

defineExpose({ getUserCheckedColumns })
</script>

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