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 |
验证方式¶
- 设置列宽 → 检查 localStorage 应有
<uid>:table:columns:width:extMapMerchant这个 key - 老用户升级:本来有
table:columns:width:extMapMerchant→ 升级后第一次打开应自动迁到新 key,老 key 被删 - 切账号验证 A/B 不互相覆盖
如何避免再犯¶
- 任何 user-scoped 数据(设置 / 个性化 / 自定义 view)都要按 uid 隔离
- 三个 hook 同源功能应共用 key 前缀逻辑(提个 helper 函数)
- 加新 storage key 时填一个 checklist:是否 user-scoped?是否需要迁移?是否清理时机?
相关问题¶
- 无