merge code

This commit is contained in:
2026-01-27 00:27:46 +08:00
parent 302581289f
commit 8ebb8949d8
69 changed files with 9859 additions and 12987 deletions

220
src/hooks/tableColumn.ts Normal file
View File

@@ -0,0 +1,220 @@
import { ref, computed, onMounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { getTableConfigFromLocal, saveTableConfigToLocal, updateUserTableConfig } from '/@/api/admin/usertable'
/**
* 表格列配置类型
*/
export interface TableColumn {
prop?: string
label?: string
icon?: any
width?: number | string
minWidth?: number | string
showOverflowTooltip?: boolean
align?: 'left' | 'center' | 'right'
alwaysShow?: boolean
fixed?: boolean | 'left' | 'right'
[key: string]: any
}
/**
* useTableColumnControl Hook
*
* 用于统一管理表格列的显示/隐藏和排序功能
*
* @param tableColumns 表格列配置数组
* @param options 可选配置项
* @returns 返回列控制相关的状态和方法
*
* @example
* ```ts
* const tableColumns = [
* { prop: 'name', label: '姓名', icon: User },
* { prop: 'age', label: '年龄', icon: Calendar }
* ]
*
* const {
* visibleColumns,
* visibleColumnsSorted,
* checkColumnVisible,
* handleColumnChange,
* handleColumnOrderChange
* } = useTableColumnControl(tableColumns)
* ```
*/
export function useTableColumnControl(
tableColumns: TableColumn[],
options?: {
/** 是否在挂载时自动加载配置,默认为 true */
autoLoad?: boolean
/** 自定义存储 key默认使用路由路径 */
storageKey?: string
}
) {
const route = useRoute()
const { autoLoad = true, storageKey: customStorageKey } = options || {}
// 生成存储 key
const getStorageKey = () => {
if (customStorageKey) {
return customStorageKey
}
const routePath = route.path.replace(/^\//, '').replace(/\//g, '-')
return `table-columns-${routePath}`
}
// 当前显示的列
const visibleColumns = ref<string[]>([])
// 列排序顺序
const columnOrder = ref<string[]>([])
/**
* 从本地统一存储加载配置
*/
const loadSavedConfig = () => {
const storageKey = getStorageKey()
const savedConfig = getTableConfigFromLocal(storageKey)
// 获取所有有效的列 key
const validColumns = tableColumns
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label || '')
.filter(Boolean)
// 加载可见列配置
if (savedConfig && savedConfig.visibleColumns) {
const filteredSaved = savedConfig.visibleColumns.filter((col: string) => validColumns.includes(col))
visibleColumns.value = filteredSaved.length > 0 ? filteredSaved : validColumns
} else {
visibleColumns.value = validColumns
}
// 加载列排序配置
if (savedConfig && savedConfig.columnOrder) {
columnOrder.value = savedConfig.columnOrder.filter((key: string) => validColumns.includes(key))
// 补充缺失的列
validColumns.forEach(key => {
if (!columnOrder.value.includes(key)) {
columnOrder.value.push(key)
}
})
} else {
columnOrder.value = validColumns
}
}
/**
* 列显示控制函数
* @param prop 列的 prop 或 label
* @returns 是否可见
*/
const checkColumnVisible = (prop: string): boolean => {
if (visibleColumns.value.length === 0) {
return true
}
return visibleColumns.value.includes(prop)
}
/**
* 列变化处理
* @param value 新的可见列数组
*/
const handleColumnChange = (value: string[]) => {
visibleColumns.value = value
const storageKey = getStorageKey()
// 过滤掉 alwaysShow 和 fixed 的列
const selectableColumns = value.filter(col => {
const column = tableColumns.find(c => (c.prop || c.label) === col)
return column && !column.alwaysShow && !column.fixed
})
// 保存到本地统一存储
saveTableConfigToLocal(storageKey, { visibleColumns: selectableColumns })
// 异步保存到后端
updateUserTableConfig(storageKey, { visibleColumns: selectableColumns }).catch(() => {})
}
/**
* 列排序变化处理
* @param order 新的列排序数组
*/
const handleColumnOrderChange = (order: string[]) => {
columnOrder.value = order
const storageKey = getStorageKey()
// 保存到本地统一存储
saveTableConfigToLocal(storageKey, { columnOrder: order })
// 异步保存到后端
updateUserTableConfig(storageKey, { columnOrder: order }).catch(() => {})
}
/**
* 排序后的表格列
* 根据 visibleColumns 和 columnOrder 计算最终显示的列
*/
const visibleColumnsSorted = computed(() => {
// 过滤出可见的列
const columns = tableColumns.filter(col => {
const key = col.prop || col.label || ''
return visibleColumns.value.includes(key)
})
// 如果有排序配置,按排序顺序排列
if (columnOrder.value.length > 0) {
const orderedColumns: TableColumn[] = []
const unorderedColumns: TableColumn[] = []
// 先按保存的顺序添加列
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
})
// 自动加载配置
if (autoLoad) {
loadSavedConfig()
onMounted(() => {
nextTick(() => {
if (visibleColumns.value.length === 0) {
loadSavedConfig()
}
})
})
}
return {
/** 当前可见的列 key 数组 */
visibleColumns,
/** 列排序顺序 */
columnOrder,
/** 排序后的可见列配置数组 */
visibleColumnsSorted,
/** 检查列是否可见 */
checkColumnVisible,
/** 列变化处理函数 */
handleColumnChange,
/** 列排序变化处理函数 */
handleColumnOrderChange,
/** 手动加载配置 */
loadSavedConfig
}
}