# TableColumnControl 集成指南

## 概述
`TableColumnControl` 是一个通用的表格列显隐控制组件，可以为任何表格页面添加列显示/隐藏和排序功能。

## 集成步骤

### 1. 导入必要的依赖

```typescript
import { ref, computed, onMounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
import { Menu } from '@element-plus/icons-vue'
```

### 2. 定义表格列配置

```typescript
// 表格列配置
const tableColumns = [
  { prop: 'schoolYear', label: '学年' },
  { prop: 'schoolTerm', label: '学期' },
  { prop: 'title', label: '标题' },
  { prop: 'author', label: '作者' },
  { prop: '操作', label: '操作', alwaysShow: true, fixed: true }
]

// 列配置映射（用于图标，可选）
const columnConfigMap: Record<string, { icon: any }> = {
  schoolYear: { icon: Calendar },
  schoolTerm: { icon: Clock },
  title: { icon: Document },
  author: { icon: User }
}
```

### 3. 添加状态变量

```typescript
const route = useRoute()
const columnControlRef = ref<any>()

// 当前显示的列
const visibleColumns = ref<string[]>([])
// 列排序顺序
const columnOrder = ref<string[]>([])
```

### 4. 添加配置加载和保存逻辑

```typescript
// 立即从 localStorage 加载配置
const loadSavedConfig = () => {
  const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
  const storageKey = `table-columns-${routePath}`
  const saved = localStorage.getItem(storageKey)
  
  if (saved) {
    try {
      const savedColumns = JSON.parse(saved)
      const validColumns = tableColumns
        .filter(col => !col.alwaysShow && !col.fixed)
        .map(col => col.prop || col.label)
      const filteredSaved = savedColumns.filter((col: string) => validColumns.includes(col))
      
      visibleColumns.value = filteredSaved.length > 0 ? filteredSaved : validColumns
    } catch (e) {
      console.error('解析列配置失败:', e)
      visibleColumns.value = tableColumns
        .filter(col => !col.alwaysShow && !col.fixed)
        .map(col => col.prop || col.label)
    }
  } else {
    visibleColumns.value = tableColumns
      .filter(col => !col.alwaysShow && !col.fixed)
      .map(col => col.prop || col.label)
  }
  
  // 加载列排序配置
  const orderKey = `${storageKey}-order`
  const savedOrder = localStorage.getItem(orderKey)
  if (savedOrder) {
    try {
      const parsedOrder = JSON.parse(savedOrder)
      const validColumns = tableColumns
        .filter(col => !col.alwaysShow && !col.fixed)
        .map(col => col.prop || col.label)
      columnOrder.value = parsedOrder.filter((key: string) => validColumns.includes(key))
      
      validColumns.forEach(key => {
        if (!columnOrder.value.includes(key)) {
          columnOrder.value.push(key)
        }
      })
    } catch (e) {
      console.error('解析列排序失败:', e)
      columnOrder.value = tableColumns
        .filter(col => !col.alwaysShow && !col.fixed)
        .map(col => col.prop || col.label)
    }
  } else {
    columnOrder.value = tableColumns
      .filter(col => !col.alwaysShow && !col.fixed)
      .map(col => col.prop || col.label)
  }
}

// 立即加载保存的配置
loadSavedConfig()
```

### 5. 添加排序后的表格列计算属性

```typescript
// 排序后的表格列
const sortedTableColumns = computed(() => {
  const columns = tableColumns.filter(col => {
    const key = col.prop || col.label
    return col.alwaysShow || col.fixed || visibleColumns.value.includes(key)
  })
  
  if (columnOrder.value.length > 0) {
    const orderedColumns: typeof tableColumns = []
    const unorderedColumns: typeof tableColumns = []
    
    columnOrder.value.forEach(key => {
      const col = columns.find(c => (c.prop || c.label) === key)
      if (col) {
        orderedColumns.push(col)
      }
    })
    
    columns.forEach(col => {
      const key = col.prop || col.label
      if (!columnOrder.value.includes(key)) {
        unorderedColumns.push(col)
      }
    })
    
    return [...orderedColumns, ...unorderedColumns]
  }
  
  return columns
})
```

### 6. 添加列显示控制函数

```typescript
// 列显示控制函数
const checkColumnVisible = (prop: string): boolean => {
  if (visibleColumns.value.length === 0) {
    return true
  }
  return visibleColumns.value.includes(prop)
}
```

### 7. 添加事件处理函数

```typescript
// 监听列变化
const handleColumnChange = (columns: string[]) => {
  visibleColumns.value = columns
  const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
  const storageKey = `table-columns-${routePath}`
  const selectableColumns = columns.filter(col => {
    const column = tableColumns.find(c => (c.prop || c.label) === col)
    return column && !column.alwaysShow && !column.fixed
  })
  localStorage.setItem(storageKey, JSON.stringify(selectableColumns))
}

// 监听列排序变化
const handleColumnOrderChange = (order: string[]) => {
  columnOrder.value = order
  const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
  const storageKey = `table-columns-${routePath}-order`
  localStorage.setItem(storageKey, JSON.stringify(order))
}
```

### 8. 在模板中添加 TableColumnControl 组件

在 `right-toolbar` 组件内添加：

```vue
<right-toolbar  
  v-model:showSearch="showSearch" 
  class="ml10" 
  style="float: right;"
  @queryTable="getDataList">
  <TableColumnControl
    ref="columnControlRef"
    :columns="tableColumns"
    v-model="visibleColumns"
    trigger-type="default"
    trigger-circle
    @change="handleColumnChange"
    @order-change="handleColumnOrderChange"
  >
    <template #trigger>
      <el-tooltip class="item" effect="dark" content="列设置" placement="top">
        <el-button circle style="margin-left: 0;">
          <el-icon><Menu /></el-icon>
        </el-button>
      </el-tooltip>
    </template>
  </TableColumnControl>
</right-toolbar>
```

### 9. 修改表格列渲染方式

将原来的静态 `el-table-column` 替换为动态渲染：

```vue
<el-table-column type="index" label="序号" width="60" align="center">
  <template #header>
    <el-icon><List /></el-icon>
  </template>
</el-table-column>
<template v-for="col in sortedTableColumns" :key="col.prop || col.label">
  <el-table-column 
    v-if="checkColumnVisible(col.prop || '')"
    :prop="col.prop" 
    :label="col.label" 
    show-overflow-tooltip>
    <template #header>
      <el-icon><component :is="columnConfigMap[col.prop]?.icon || Calendar" /></el-icon>
      <span style="margin-left: 4px">{{ col.label }}</span>
    </template>
    <!-- 特殊列的模板可以在这里添加 -->
    <template v-if="col.prop === 'schoolTerm'" #default="scope">
      <el-tag size="small" type="primary" effect="plain">
        {{ scope.row.schoolTerm === 1 ? '上学期' : scope.row.schoolTerm === 2 ? '下学期' : scope.row.schoolTerm }}
      </el-tag>
    </template>
  </el-table-column>
</template>
<el-table-column label="操作" align="center" fixed="right">
  <!-- 操作列内容 -->
</el-table-column>
```

### 10. 在 onMounted 中确保配置已加载

```typescript
onMounted(() => {
  // 其他初始化代码...
  
  // 确保配置已同步
  nextTick(() => {
    if (visibleColumns.value.length === 0) {
      loadSavedConfig()
    }
  })
})
```

## 注意事项

1. **列配置中的 prop 必须与 el-table-column 的 prop 属性一致**
2. **操作列应该标记为 `alwaysShow: true` 和 `fixed: true`**
3. **序号列（type="index"）不需要添加到 tableColumns 中**
4. **localStorage 的 key 会根据路由自动生成，确保每个页面都有独立的配置**

## 示例

参考 `src/views/stuwork/weekPlan/index.vue` 和 `src/views/stuwork/classroomhygienemonthly/index.vue` 的完整实现。

