跳转至

title: [ISSUE-0014] 列宽 / 列序 storage key 未按账号隔离 description: "列宽 / 列序 storage key 漏 uid 前缀,多账号污染" tags: [issue] created: 2026-05-26 updated: 2026-05-26 type: issue status: fixed severity: medium


[ISSUE-0014] 列宽 / 列序 storage key 未按账号隔离

相关源码src/hooks/cache/use-table-columns-config.tsx 发现途径:v0.10.19 代码审查

用户感知的现象

同一台浏览器多账号场景: - A 账号自定义了列宽 / 列序 - 切到 B 账号 → B 看到 A 的列宽 / 列序 - A 再登录 → A 的设置已被 B 覆盖

根因分析

use-table-columns-config.tsx

// useTableColumnsConfig — 有 uid 前缀 ✅
const STORAGE_KEY = `${uid}:table:columns:${tableName}`;

// useTableColumnsWidth — 无 uid 前缀 ❌
const STORAGE_KEY = `table:columns:width:${tableName}`;

// useTableColumnsList — 无 uid 前缀 ❌
const STORAGE_KEY = `table:columns:list:${tableName}`;

宽度和列序 hook 漏了 uid 前缀。

修复方案

加 uid 前缀,同时做一次性迁移(老 key → 新 key,迁完删老 key)让老用户无感升级。

const uid = localStorage.getItem('orgId') || '';
const NEW_KEY = `${uid}:table:columns:width:${tableName}`;
const OLD_KEY = `table:columns:width:${tableName}`;

// 一次性迁移
useEffect(() => {
  const newVal = localStorage.getItem(NEW_KEY);
  const oldVal = localStorage.getItem(OLD_KEY);
  if (!newVal && oldVal) {
    localStorage.setItem(NEW_KEY, oldVal);
    localStorage.removeItem(OLD_KEY);
  }
}, []);

改动文件

文件 改了什么
src/hooks/cache/use-table-columns-config.tsx width / list 加 uid 前缀 + 一次性迁移老 key

验证方式

  1. 设置列宽 → 检查 localStorage 应有 <uid>:table:columns:width:extMapMerchant 这个 key
  2. 老用户升级:本来有 table:columns:width:extMapMerchant → 升级后第一次打开应自动迁到新 key,老 key 被删
  3. 切账号验证 A/B 不互相覆盖

如何避免再犯

  • 任何 user-scoped 数据(设置 / 个性化 / 自定义 view)都要按 uid 隔离
  • 三个 hook 同源功能应共用 key 前缀逻辑(提个 helper 函数)
  • 加新 storage key 时填一个 checklist:是否 user-scoped?是否需要迁移?是否清理时机?

相关问题