diff --git a/src/components/TableColumnControl/index.vue b/src/components/TableColumnControl/index.vue index c8032ac..2b566d3 100644 --- a/src/components/TableColumnControl/index.vue +++ b/src/components/TableColumnControl/index.vue @@ -150,31 +150,57 @@ const initCheckedColumns = () => { if (props.modelValue && props.modelValue.length > 0) { checkedColumns.value = [...props.modelValue] } else if (props.tableRef && autoVisibleColumns.value.length > 0) { - // 使用自动提取的可见列,但需要确保包含所有列(包括固定列) - // 合并已保存的可见列和固定列/alwaysShow列 - const fixedAndAlwaysShow = actualColumns.value - .filter(col => col.alwaysShow || !!col.fixed) + // 使用自动提取的可见列 + const allSelectableColumns = actualColumns.value + .filter(col => !col.alwaysShow && !col.fixed) .map(col => col.prop || col.label) - checkedColumns.value = [...new Set([...autoVisibleColumns.value, ...fixedAndAlwaysShow])] + + // 如果保存的列数量少于所有列,默认全部选中 + if (autoVisibleColumns.value.length < allSelectableColumns.length) { + const fixedAndAlwaysShow = actualColumns.value + .filter(col => col.alwaysShow || !!col.fixed) + .map(col => col.prop || col.label) + checkedColumns.value = [...new Set([...allSelectableColumns, ...fixedAndAlwaysShow])] + } else { + // 使用保存的列,但确保包含固定列和 alwaysShow 列 + const fixedAndAlwaysShow = actualColumns.value + .filter(col => col.alwaysShow || !!col.fixed) + .map(col => col.prop || col.label) + checkedColumns.value = [...new Set([...autoVisibleColumns.value, ...fixedAndAlwaysShow])] + } } else if (props.storageKey) { // 从 localStorage 读取 const saved = localStorage.getItem(props.storageKey) if (saved) { try { const savedColumns = JSON.parse(saved) - // 确保固定列和 alwaysShow 列始终在选中列表中 - const fixedAndAlwaysShow = actualColumns.value - .filter(col => col.alwaysShow || !!col.fixed) + const allSelectableColumns = actualColumns.value + .filter(col => !col.alwaysShow && !col.fixed) .map(col => col.prop || col.label) - checkedColumns.value = [...new Set([...savedColumns, ...fixedAndAlwaysShow])] + + // 如果保存的列数量少于所有列,默认全部选中 + if (savedColumns.length < allSelectableColumns.length) { + const fixedAndAlwaysShow = actualColumns.value + .filter(col => col.alwaysShow || !!col.fixed) + .map(col => col.prop || col.label) + checkedColumns.value = [...new Set([...allSelectableColumns, ...fixedAndAlwaysShow])] + } else { + // 使用保存的列,但确保包含固定列和 alwaysShow 列 + const fixedAndAlwaysShow = actualColumns.value + .filter(col => col.alwaysShow || !!col.fixed) + .map(col => col.prop || col.label) + checkedColumns.value = [...new Set([...savedColumns, ...fixedAndAlwaysShow])] + } } catch (e) { // 如果解析失败,使用默认值(所有列) checkedColumns.value = getAllColumns() } } else { + // 首次使用,默认全部选中 checkedColumns.value = getAllColumns() } } else { + // 没有 storageKey,默认全部选中 checkedColumns.value = getAllColumns() } } @@ -201,9 +227,22 @@ watch(actualColumns, (newColumns) => { watch(visible, (newVal) => { console.log('[TableColumnControl] 弹窗状态变化:', newVal) if (newVal) { - // 弹窗打开时,确保选中状态正确初始化 + // 弹窗打开时,确保选中状态正确初始化(但不重置用户已保存的设置) if (actualColumns.value.length > 0) { - initCheckedColumns() + // 只有在 checkedColumns 为空时才初始化,避免覆盖用户已保存的设置 + if (checkedColumns.value.length === 0) { + initCheckedColumns() + } else { + // 如果已有选中状态,只确保固定列和 alwaysShow 列在选中列表中 + const fixedAndAlwaysShow = actualColumns.value + .filter(col => col.alwaysShow || !!col.fixed) + .map(col => col.prop || col.label) + const currentChecked = checkedColumns.value + const missingFixed = fixedAndAlwaysShow.filter(col => !currentChecked.includes(col)) + if (missingFixed.length > 0) { + checkedColumns.value = [...currentChecked, ...missingFixed] + } + } } } if (newVal && props.tableRef) { diff --git a/src/composables/useTableColumns.ts b/src/composables/useTableColumns.ts index 7e45962..2f3347c 100644 --- a/src/composables/useTableColumns.ts +++ b/src/composables/useTableColumns.ts @@ -31,6 +31,8 @@ export function useTableColumns( ) { const columns = ref([]) const visibleColumns = ref([]) + const isInitialized = ref(false) // 标记是否已经初始化过(用户是否操作过) + const hasInitializedVisibleColumns = ref(false) // 标记是否已经初始化过可见列(避免重复初始化) // 获取表格实例的辅助函数 const getTableInstance = (): TableInstance | null => { @@ -379,25 +381,42 @@ export function useTableColumns( columns.value = Array.from(map.values()) } - // 初始化可见列 - if (storageKey) { - const saved = localStorage.getItem(storageKey) - if (saved) { - try { - visibleColumns.value = JSON.parse(saved) - // 验证保存的列是否仍然存在 - const validColumns = columns.value - .filter(col => !col.alwaysShow && col.fixed === undefined) - .map(col => col.prop || col.label) - visibleColumns.value = visibleColumns.value.filter(col => validColumns.includes(col)) - } catch (e) { + // 初始化可见列(只在第一次初始化时执行,避免后续刷新时重置用户设置) + if (!hasInitializedVisibleColumns.value) { + if (storageKey) { + const saved = localStorage.getItem(storageKey) + if (saved) { + try { + const savedColumns = JSON.parse(saved) + // 验证保存的列是否仍然存在 + const validColumns = columns.value + .filter(col => !col.alwaysShow && col.fixed === undefined) + .map(col => col.prop || col.label) + const filteredSaved = savedColumns.filter((col: string) => validColumns.includes(col)) + + // 如果保存的列数量少于所有列,说明是旧数据,默认显示所有列 + if (filteredSaved.length < validColumns.length) { + visibleColumns.value = validColumns + isInitialized.value = false // 旧数据,视为未初始化 + } else { + visibleColumns.value = filteredSaved + isInitialized.value = true // 有保存的数据,视为已初始化 + } + } catch (e) { + initDefaultVisibleColumns() + isInitialized.value = false + } + } else { + // 首次使用,默认显示所有列 initDefaultVisibleColumns() + isInitialized.value = false } } else { + // 没有 storageKey,默认显示所有列 initDefaultVisibleColumns() + isInitialized.value = false } - } else { - initDefaultVisibleColumns() + hasInitializedVisibleColumns.value = true } } else { console.warn('[useTableColumns] initColumns: 提取失败,未设置 columns.value') @@ -406,24 +425,12 @@ export function useTableColumns( // 初始化默认可见列 const initDefaultVisibleColumns = () => { - const defaultHidden = options?.defaultHidden || [] - // 默认显示所有列(除了默认隐藏的列和固定列/alwaysShow列) + // 默认显示所有可选择的列(除了固定列和 alwaysShow 列) // 注意:固定列和 alwaysShow 列不需要在 visibleColumns 中,因为它们始终显示 + // 默认全部选中,展示所有列 visibleColumns.value = columns.value - .filter(col => { - const key = col.prop || col.label - return !col.alwaysShow && - !col.fixed && - !defaultHidden.includes(key) - }) + .filter(col => !col.alwaysShow && !col.fixed) .map(col => col.prop || col.label) - - // 如果所有列都被隐藏了,至少显示所有非固定列 - if (visibleColumns.value.length === 0 && columns.value.length > 0) { - visibleColumns.value = columns.value - .filter(col => !col.alwaysShow && !col.fixed) - .map(col => col.prop || col.label) - } } // 判断列是否可见 @@ -447,11 +454,17 @@ export function useTableColumns( return true } - // 如果可见列列表为空,默认显示所有列(初始状态) - if (visibleColumns.value.length === 0) { + // 如果还未初始化(用户未操作过),默认显示所有列 + if (!isInitialized.value) { return true } + // 如果已经初始化,严格按照可见列列表判断 + // 如果可见列列表为空,说明用户取消了所有列,应该隐藏所有非固定列 + if (visibleColumns.value.length === 0) { + return false + } + // 检查是否在可见列列表中 return visibleColumns.value.includes(propOrLabel) } @@ -459,6 +472,7 @@ export function useTableColumns( // 更新可见列 const updateVisibleColumns = (newColumns: string[]) => { visibleColumns.value = newColumns + isInitialized.value = true // 标记已经初始化(用户已操作) if (storageKey) { localStorage.setItem(storageKey, JSON.stringify(newColumns)) } diff --git a/src/views/professional/teacherbase/index.vue b/src/views/professional/teacherbase/index.vue index da98869..c6a1249 100644 --- a/src/views/professional/teacherbase/index.vue +++ b/src/views/professional/teacherbase/index.vue @@ -2076,37 +2076,37 @@ command: 'export', label: '导出', icon: Download, - visible: permissions.value.professional_teacherbase_export + visible: () => permissions.value.professional_teacherbase_export }, { command: 'personnel-transfer', label: '人员调动', icon: Switch, - visible: permissions.value.professional_teacherbase_status_lock + visible: () => permissions.value.professional_teacherbase_status_lock }, { command: 'party-transfer', label: '党员调动', icon: Switch, - visible: permissions.value.professional_teacherbase_status_lock + visible: () => permissions.value.professional_teacherbase_status_lock }, { command: 'allow-inout', label: '允许进出', icon: CircleCheck, - visible: permissions.value.professional_teacherbase_inout && row.inoutFlag == '0' + visible: () => permissions.value.professional_teacherbase_inout && row.inoutFlag == '0' }, { command: 'forbid-inout', label: '禁止进出', icon: CircleClose, - visible: permissions.value.professional_teacherbase_inout && row.inoutFlag == '1' + visible: () => permissions.value.professional_teacherbase_inout && row.inoutFlag == '1' }, { command: 'reset-password', label: '重置密码', icon: Refresh, - visible: permissions.value.professional_teacherbase_resetpw + visible: () => permissions.value.professional_teacherbase_resetpw } ] }