# UX 走查 — 设置域与全局交互 (2026-10-03) > 只读勘察,零代码改动。路径均相对 `src/`。已排除:UX token 化、settings.css 三防线、上传端点纵排、信任目录文案重叠、Ctrl+I 徽章、9-28#17 图片上传外域。 > 复现栏仅写关键步骤;修法一句话供派工参考。 ## P1 (2) ### 1. Escape 在分离窗口任意位置按下即关闭整窗(含输入中) - 现象:ai-detached 分离窗口内,按 Esc(想关技能联想浮层/取消编辑/仅 blur)→ 整个分离窗口直接关闭。 - 根因:`components/AiChat.vue:362-368` window 级 keydown 对 Esc 无 target 守卫,`props.detached` 分支直接 `store.closeDetachedWindow()`;`components/ai/ChatInput.vue:680-695` 各 Esc 分支只 `preventDefault()` 不 `stopPropagation()`,照常冒泡到 window;`composables/ai/useAiWindow.ts:247-265` 关窗前不校验未发送内容(beforeunload 守卫对原生 close 不保证触发)。 - 复现:分离窗口 → 输入框打字 → 按 Esc → 窗口消失,输入内容丢失。 - 严重度:P1 - 修法:window Esc 分支加输入控件 target 守卫,且 ChatInput Esc 消费分支补 `stopPropagation()`。 ### 2. 「测试连接」重拉模型列表静默清空用户已配 enabled/weight - 现象:拉取模型→关掉部分模型/调权重→保存→再点「测试连接」→ 全部模型复位为 enabled + weight 50。 - 根因:`components/settings/ProviderPanel.vue:484-493` 探测合并仅保留 `probe_source==='user_set'` 的 modalities/capabilities,`enabled`/`weight` 一律取新探测值,旧记录(`old`)只用于判 isManual。 - 复现:AI 模型页 → 编辑 provider → 测试连接 → 调 weight/关模型 → 再点测试连接 → 设置全丢(无任何提示)。 - 严重度:P1 - 修法:合并时对已存在的 model_id 保留 `old.enabled`/`old.weight`,仅新增模型用探测默认值。 ## P2 (6) ### 3. 全局快捷键无输入焦点守卫(Ctrl+I 及同族 Ctrl+N/R/L/B/K) - 现象:任意输入框打字时按 Ctrl+I → AI 面板被关闭/最大化;Ctrl+B → 会话侧栏被关;Ctrl+L → 弹清空对话确认。 - 根因:`App.vue:153-158` handleKeydown 不检查 e.target;`components/AiChat.vue:321-355` Ctrl+N/R/L/B/K 同样无守卫。 - 复现:焦点在设置搜索框/聊天输入框 → 按 Ctrl+I → 面板模式跳变。 - 严重度:P2 - 修法:各全局 handler 首行判 `e.target` 为 input/textarea/contenteditable(且无修饰需求)即 return。 ### 4. 主题「跟随系统」不监听系统切换 - 现象:选 system 档后,OS 深浅色切换应用不跟随,需重启或重选档位。 - 根因:`components/settings/AppearanceSection.vue:68-78` 与 `App.vue:145-148` 均只 `matchMedia(...).matches` 取值一次,全仓无 `addEventListener('change')`。 - 复现:主题=跟随系统 → Windows 切深→浅 → 应用不变。 - 严重度:P2 - 修法:applyTheme 时对 matchMedia 挂 change 监听,theme==='system' 时重算 data-theme。 ### 5. 顶栏点 provider 名「切换」实为静默改写全局默认 provider - 现象:聊天顶栏点 provider bar 循环切换(toast 仅"已切换"),但后端互斥写 DB `is_default` — 与设置页「设为默认」同一 IPC `ai_set_provider`(`src-tauri/src/commands/ai/commands/provider.rs:252-273`)。设置页默认徽标随之漂移,新会话/负载均衡默认全被改。 - 根因:`components/ai/TopBar.vue:542-554` → `composables/ai/useAiPanel.ts:178-183` setProvider 直写默认;会话级 active 与 DB default 两概念共用一条 IPC。 - 复现:双 provider → 聊天顶栏点一下切到 B → 设置页 AI 模型列表:默认徽标已移到 B。 - 严重度:P2 - 修法:拆分 active(会话级,不落 is_default)与 default 两条命令,顶栏只改 active。 ### 6. 关窗即隐入托盘,首次无任何解释 - 现象:无运行会话时点主窗 X → 窗口无声消失,进程驻留托盘;用户以为已退出(托盘通知气泡只在"有会话运行"且每进程一次时出现)。 - 根因:`src-tauri/src/lib.rs:524-544` 一律 prevent_close+hide;`App.vue:227-233` tray-hide-notice 仅 running>0 才弹。 - 复现:无会话 → 点 X → 桌面无窗口、任务栏无项、无任何提示。 - 严重度:P2 - 修法:首次关窗也 emit 一次"已最小化到托盘"气泡,或设置页提供关窗行为开关(退出/托盘)。 ### 7. Provider 表单脏态拦截只盖 Cancel 按钮,切分类/离开即丢 - 现象:编辑 provider(或调模型列表)后点左侧任一分类/路由离开 → 表单连同未保存修改无确认直接销毁。 - 根因:`components/settings/ProviderPanel.vue:649-658` 已暴露 isFormDirty 但注释自认"Settings.vue 未接入 nav 拦截";`views/Settings.vue:25-34` v-else-if 切 activeCategory 即卸载面板。 - 复现:AI 模型页 → 改 baseUrl 不保存 → 点「性能」→ 回来全丢。 - 严重度:P2 - 修法:Settings.vue 在切分类/卸载前查 providerPanelRef.isFormDirty 走 confirmDialog。 ### 8. 池权重 debounce 单计时器跨 provider 互踩,先改的静默丢 - 现象:连续给 A、B 两个 provider 改权重(间隔<300ms),A 的保存 IPC 被 clearTimeout 吞掉,视图值与库值漂移。 - 根因:`components/settings/ProviderPanel.vue:603,631-641` `_poolTimer` 为全面板单例,A 乐观更新后计时被 B 的变更清掉。 - 复现:改 A 权重→立即改 B 权重→刷新:A 仍是旧值。 - 严重度:P2 - 修法:timer 按 provider id 建 Map,或新变更先 flush 前一待发。 ## P3 (10) ### 9. API 密钥输入无显隐切换,编辑态"留空=不改"无提示 - `ProviderPanel.vue:95`(type=password 恒定无眼睛钮)、`:394`(编辑清空 apiKey 但表单无 hint)。修法:加显隐 toggle + "留空保持原密钥" hint。 ### 10. 表单校验只 toast 不定位字段;测试连接禁用无原因 - `ProviderPanel.vue:534-537`/`ConnectionPanel.vue:177-186` 缺哪个字段无高亮;`ProviderPanel.vue:120` 按钮禁用态无 tooltip 说明缺 baseUrl 还是 key。修法:字段级 inline 错误 + 禁用原因 title。 ### 11. 「已保存」假成功族(反馈先于持久化结果) - `AppearanceSection.vue:9-39,86-89` markSaved 不等 set 结果;`PerformanceSection.vue:118-128` debounce IPC 失败仅 console,前面已显"已保存";`views/Settings.vue:44-50` anthropicCache 开关无任何反馈。修法:反馈挂 await/IPC 结果,失败改 error toast。 ### 12. 日志级别"已保存"但运行时生效链路存疑 - `AdvancedSection.vue:229-236` 注释自认运行时是否读该值未知,UI 仍显"已保存"。修法:desc 注明生效时机或补齐热生效。 ### 13. 连接表单 Cancel 无脏确认,保存无成功反馈 - `ConnectionPanel.vue:37` 直接关表单(对比 ProviderPanel L19 有确认);`:176-209` saveConn 成功无 toast(删除反有)。修法:对齐脏确认+成功 toast。 ### 14. 数值输入越界不拦:temperature/并发上限 - `ProviderPanel.vue:549-552` temperature 仅判 isFinite,手输 99 照存(min/max 只限步进);`PerformanceSection.vue:112` 并发无上界。修法:保存前 clamp + 提示修正值。 ### 15. i18n 残留硬编码中文 / 假环境信息 - `App.vue:230` 后台运行气泡;`src-tauri/src/tray.rs:28-29,65-70` 托盘菜单;`components/ai/TopBar.vue:487` osInfo 恒 'Windows 11 / PowerShell'(非事实)。修法:入 i18n;osInfo 用 Tauri os 插件取真值。 ### 16. 双全局 toast 同位重叠 - `App.vue:317-327` df-toast 与 df-toast--info 都 fixed bottom:24px 居中,错误+托盘提示同现互相压盖。修法:合并进同一纵向堆叠容器。 ### 17. 设置搜索每键强制跳分类 - `SettingsNav.vue:131-144` 输入即改 activeCategory+滚动,浏览 A 类打字被拽到 B 类。修法:输入只高亮,Enter/点击才跳转定位。 ### 18. 无首次使用引导/空态引导单薄 - 全仓无 onboarding;provider 未配置仅 AI 顶栏一行红字(`i18n/zh-CN/aiChat.ts:63`),Dashboard/AiHome 无引导卡。修法:provider 为空时主界面一次性引导卡(直达设置)。