mirror of
https://github.com/shy3130/tick-stock-panel.git
synced 2026-11-02 10:26:13 +00:00
用户反馈系统设置里部分配置保存后重新打开又变回之前的状态。 根因不是保存逻辑坏了, 而是存储位置错。系统设置页有 9 项只写浏览器 localStorage: 通知弹窗开关/最大弹窗个数/声效开关/声效选择/语音播报 开关/音色/语速/个股外链模板/界面缩放。而浏览器按 origin (协议+主机+ 端口) 隔离 localStorage, 桌面版启动时用 _find_free_port(3018) 从 3018 起取第一个空闲端口再以 http://127.0.0.1:{port} 打开窗口 —— 端口一变, 对这个应用就是另一个站点, 此前存的设置全部读不到。走 preferences.json 的那些设置一直正常, 所以现象是「有些配置会丢」。 修复: 后端权威副本 + localStorage 本地缓存的双写方案。 - preferences.py 新增 ui_prefs: 9 个键的白名单、只接受 JSON 标量、 null 表示删除、16KB 上限; - 新增 PUT /api/settings/preferences/ui-prefs, GET /preferences 带上 ui_prefs; - 新增 lib/uiPrefs.ts: setUiPref 写本地后 300ms 合并上推后端, hydrateUiPrefs 启动时从后端回填; - 系统设置页 7 处 localStorage 直写、外链模板、界面缩放改走 setUiPref; - main.tsx 启动触发回填并重放一次缩放。 保留 localStorage 而非全部搬到后端, 是因为通知/语音/缩放等模块在非 React 路径 (SSE 回调、index.html 首帧脚本) 同步取值, 不能等网络。 回填规则为本地优先: 本地已有值上推后端, 不被启动时的旧副本覆盖; 只有 本地缺失的键才用后端值补 —— 升级用户首次启动即完成迁移。 验证: 端到端模拟「清空 localStorage 换端口」后重载, 三项设置在 ~330ms 内全部恢复且稳定, UI 正确反映 (弹窗数 5 / 语音开启 / 缩放 110%); 后端 test_ui_prefs 8 passed (stash 实现后 8 个全失败, 确认用例有效); tsc --noEmit 与 pnpm build 通过; ruff 告警数与基线持平。 Signed-off-by: shy3130 <shy3130@qq.com>