# 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` 的完整实现。
