merge code pull

This commit is contained in:
2026-01-26 11:07:16 +08:00
parent b99d181d85
commit dde24adf2c
79 changed files with 11876 additions and 5017 deletions

View File

@@ -53,6 +53,7 @@ import { Menu, Rank } from '@element-plus/icons-vue'
import type { TableInstance } from 'element-plus'
import { useTableColumns, type ColumnConfig } from '/@/composables/useTableColumns'
import Sortable from 'sortablejs'
import { getUserTableConfig, saveUserTableConfig, updateUserTableConfig, getAllTableConfigsFromLocal, saveAllTableConfigsToLocal } from '/@/api/admin/usertable'
const slots = useSlots()
const route = useRoute()
@@ -189,35 +190,64 @@ const getAllColumns = (): string[] => {
}
// 初始化选中的列
const initCheckedColumns = () => {
const initCheckedColumns = async () => {
// 如果 actualColumns 为空,无法初始化
if (actualColumns.value.length === 0) {
return
}
// 优先从 localStorage 读取配置
const storageKey = getStorageKey()
const saved = localStorage.getItem(storageKey)
if (saved) {
try {
const savedColumns = JSON.parse(saved)
// 优先从本地缓存获取配置
try {
const allConfigs = getAllTableConfigsFromLocal()
const currentConfig = allConfigs[storageKey]
if (currentConfig && currentConfig.visibleColumns) {
const savedColumns = currentConfig.visibleColumns
const allSelectableColumns = actualColumns.value
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label)
// 验证保存的列是否仍然存在
const validColumns = savedColumns.filter((col: string) => allSelectableColumns.includes(col))
// 使用保存的列配置(即使数量少于所有列,也使用保存的配置)
// 但确保包含固定列和 alwaysShow 列
const fixedAndAlwaysShow = actualColumns.value
.filter(col => col.alwaysShow || !!col.fixed)
.map(col => col.prop || col.label)
checkedColumns.value = [...new Set([...savedColumns, ...fixedAndAlwaysShow])]
checkedColumns.value = [...new Set([...validColumns, ...fixedAndAlwaysShow])]
// 同步到外部 modelValue
emit('update:modelValue', checkedColumns.value)
return // 已从 localStorage 加载,直接返回
} catch (e) {
// 如果解析失败,继续使用其他方式初始化
return // 已从API加载,直接返回
}
} catch (error) {
// API失败回退到localStorage
}
// 回退到本地统一存储读取配置
const allConfigs = getAllTableConfigsFromLocal()
const currentConfig = allConfigs[storageKey]
if (currentConfig && currentConfig.visibleColumns) {
const savedColumns = currentConfig.visibleColumns
const allSelectableColumns = actualColumns.value
.filter(col => !col.alwaysShow && !col.fixed)
.map(col => col.prop || col.label)
// 验证保存的列是否仍然存在
const validColumns = savedColumns.filter((col: string) => allSelectableColumns.includes(col))
// 使用保存的列配置(即使数量少于所有列,也使用保存的配置)
// 但确保包含固定列和 alwaysShow 列
const fixedAndAlwaysShow = actualColumns.value
.filter(col => col.alwaysShow || !!col.fixed)
.map(col => col.prop || col.label)
checkedColumns.value = [...new Set([...validColumns, ...fixedAndAlwaysShow])]
// 同步到外部 modelValue
emit('update:modelValue', checkedColumns.value)
return // 已从本地存储加载,直接返回
}
// 如果 localStorage 中没有保存的配置,使用其他方式初始化
@@ -265,8 +295,8 @@ const initColumnVisibleMap = () => {
}
// 初始化列排序顺序
const initColumnOrder = () => {
const storageKey = getOrderStorageKey()
const initColumnOrder = async () => {
const storageKey = getStorageKey()
// 先获取所有可排序的列(不依赖 sortedColumns computed
const allSortableColumns = actualColumns.value.filter(col => {
@@ -275,34 +305,100 @@ const initColumnOrder = () => {
})
const validColumns = allSortableColumns.map(col => col.prop || col.label)
const saved = localStorage.getItem(storageKey)
if (saved) {
try {
const savedOrder = JSON.parse(saved)
// 验证保存的列是否仍然存在
columnOrder.value = savedOrder.filter((key: string) => validColumns.includes(key))
// 添加新列到排序列表末尾
validColumns.forEach(key => {
if (!columnOrder.value.includes(key)) {
columnOrder.value.push(key)
}
})
} catch (e) {
// 如果解析失败,使用默认顺序
columnOrder.value = [...validColumns]
}
} else {
// 首次使用,使用默认顺序
columnOrder.value = [...validColumns]
// 优先从本地缓存获取配置
try {
const allConfigs = getAllTableConfigsFromLocal()
const currentConfig = allConfigs[storageKey]
if (currentConfig && currentConfig.columnOrder) {
const savedOrder = currentConfig.columnOrder
// 验证保存的列是否仍然存在
columnOrder.value = savedOrder.filter((key: string) => validColumns.includes(key))
// 添加新列到排序列表末尾
validColumns.forEach(key => {
if (!columnOrder.value.includes(key)) {
columnOrder.value.push(key)
}
})
return // 已从API加载直接返回
}
} catch (error) {
// API失败回退到localStorage
}
// 回退到本地统一存储
const allConfigs = getAllTableConfigsFromLocal()
const currentConfig = allConfigs[storageKey]
if (currentConfig && currentConfig.columnOrder) {
const savedOrder = currentConfig.columnOrder
// 验证保存的列是否仍然存在
columnOrder.value = savedOrder.filter((key: string) => validColumns.includes(key))
// 添加新列到排序列表末尾
validColumns.forEach(key => {
if (!columnOrder.value.includes(key)) {
columnOrder.value.push(key)
}
})
} else {
// 首次使用,使用默认顺序
columnOrder.value = [...validColumns]
}
}
// 保存列排序顺序
const saveColumnOrder = () => {
const storageKey = getOrderStorageKey()
// 保存列配置(同时保存 visibleColumns 和 columnOrder
const saveColumnConfig = async () => {
const storageKey = getStorageKey()
const selectableColumns = checkedColumns.value.filter(col => {
const column = actualColumns.value.find(c => (c.prop || c.label) === col)
return column && !column.alwaysShow && !column.fixed
})
// 优先保存到API同时保存 visibleColumns 和 columnOrder
try {
await updateUserTableConfig(storageKey, {
visibleColumns: selectableColumns,
columnOrder: columnOrder.value.length > 0 ? columnOrder.value : []
})
// updateUserTableConfig 内部已经更新了本地缓存,这里不需要再操作
} catch (error) {
// API失败只保存到本地统一存储
const allConfigs = getAllTableConfigsFromLocal()
allConfigs[storageKey] = {
visibleColumns: selectableColumns,
columnOrder: columnOrder.value
}
saveAllTableConfigsToLocal(allConfigs)
}
}
// 保存列排序顺序(同时保存 visibleColumns 和 columnOrder
const saveColumnOrder = async () => {
const storageKey = getStorageKey()
const selectableColumns = checkedColumns.value.filter(col => {
const column = actualColumns.value.find(c => (c.prop || c.label) === col)
return column && !column.alwaysShow && !column.fixed
})
if (columnOrder.value.length > 0) {
localStorage.setItem(storageKey, JSON.stringify(columnOrder.value))
// 优先保存到API同时保存 visibleColumns 和 columnOrder
try {
await updateUserTableConfig(storageKey, {
visibleColumns: selectableColumns,
columnOrder: columnOrder.value
})
// updateUserTableConfig 内部已经更新了本地缓存,这里不需要再操作
} catch (error) {
// API失败只保存到本地统一存储
const allConfigs = getAllTableConfigsFromLocal()
allConfigs[storageKey] = {
visibleColumns: selectableColumns,
columnOrder: columnOrder.value
}
saveAllTableConfigsToLocal(allConfigs)
}
}
}
@@ -544,13 +640,15 @@ const handleSwitchChange = (columnKey: string, value: boolean) => {
})
updateAutoVisibleColumns(selectableValue)
} else {
// 保存到 localStorage(只保存可选择的列)
// 保存到API和本地统一存储(只保存可选择的列)
const storageKey = getStorageKey()
const selectableValue = finalValue.filter(col => {
const column = actualColumns.value.find(c => (c.prop || c.label) === col)
return column && !column.alwaysShow && !column.fixed
})
localStorage.setItem(storageKey, JSON.stringify(selectableValue))
// 异步保存到API
saveColumnConfig()
// saveColumnConfig 内部已经更新了本地缓存,这里不需要再操作
}
}
@@ -574,13 +672,15 @@ const handleColumnChange = (value: string[]) => {
})
updateAutoVisibleColumns(selectableValue)
} else {
// 保存到 localStorage(只保存可选择的列)
// 保存到API和本地统一存储(只保存可选择的列)
const storageKey = getStorageKey()
const selectableValue = finalValue.filter(col => {
const column = actualColumns.value.find(c => (c.prop || c.label) === col)
return column && !column.alwaysShow && !column.fixed
})
localStorage.setItem(storageKey, JSON.stringify(selectableValue))
// 异步保存到API
saveColumnConfig()
// saveColumnConfig 内部已经更新了本地缓存,这里不需要再操作
}
}
@@ -591,11 +691,12 @@ watch(() => props.modelValue, (newVal) => {
const currentSorted = [...checkedColumns.value].sort()
const newSorted = [...newVal].sort()
if (JSON.stringify(currentSorted) !== JSON.stringify(newSorted)) {
// 检查是否是从 localStorage 加载的配置
// 检查是否是从本地统一存储加载的配置
const storageKey = getStorageKey()
const saved = localStorage.getItem(storageKey)
const allConfigs = getAllTableConfigsFromLocal()
const currentConfig = allConfigs[storageKey]
// 如果 checkedColumns 为空,或者没有保存的配置,才使用外部传入的值
if (checkedColumns.value.length === 0 || !saved) {
if (checkedColumns.value.length === 0 || !currentConfig) {
checkedColumns.value = [...newVal]
initColumnVisibleMap()
}