# P0 问题修复报告 > **日期**: 2026-03-16 > **状态**: 已完成 --- ## 一、问题概述 在系统上线前验证过程中发现以下 P0 级别问题: | 问题 ID | 描述 | 严重程度 | |---------|------|----------| | P0-1 | Agent 对话回复内容重复 | P0 阻塞 | | P0-2 | Tab 切换后对话内容消失 | P0 阻塞 | | P0-3 | 团队等 Tab 操作后内容消失 | P0 阻塞 | --- ## 二、根因分析 ### P0-1: 消息内容重复 **根本原因**: - 双重流式回调 - `sendMessage` 的 `onDelta` 和 `initStreamListener` 都在更新同一条消息 - 两个回调同时追加 delta,导致内容重复 **涉及文件**: - `desktop/src/store/chatStore.ts` - `desktop/src/components/ChatArea.tsx` ### P0-2: Tab 切换后内容消失 **根本原因**: - `chatStore.messages` 未持久化 - 只持久化了 `conversations` 和 `currentModel` - Tab 切换时 `messages` 状态被重置为空数组 **涉及文件**: - `desktop/src/store/chatStore.ts` ### P0-3: 团队状态丢失 **根本原因**: - `teamStore` 使用普通 Zustand,没有 persist 中间件 - `activeTeam` 状态未被持久化 **涉及文件**: - `desktop/src/store/teamStore.ts` --- ## 三、修复方案 ### 3.1 P0-1 修复: 消息重复 **修改文件**: `desktop/src/store/chatStore.ts` **修改内容**: ```typescript // 移除 sendMessage 中的 onDelta 回调,让 initStreamListener 统一处理 // 修改前 onDelta: (delta: string) => { set((state) => ({ messages: state.messages.map((m) => m.id === assistantId ? { ...m, content: m.content + delta } : m ), })); }, // 修改后 onDelta: () => { /* Handled by initStreamListener to prevent duplication */ }, ``` ### 3.2 P0-2 修复: 消息持久化 **修改文件**: `desktop/src/store/chatStore.ts` **修改内容**: ```typescript // 修改前 partialize: (state) => ({ conversations: state.conversations, currentModel: state.currentModel, }), // 修改后 partialize: (state) => ({ conversations: state.conversations, currentModel: state.currentModel, messages: state.messages, // 新增 currentConversationId: state.currentConversationId, // 新增 }), ``` ### 3.3 P0-3 修复: 团队状态持久化 **修改文件**: `desktop/src/store/teamStore.ts` **修改内容**: ```typescript // 修改前 import { create } from 'zustand'; export const useTeamStore = create((set, get) => ({ /* ... */ })); // 修改后 import { create } from 'zustand'; import { persist } from 'zustand/middleware'; export const useTeamStore = create()( persist( (set, get) => ({ /* ... */ }), { name: 'zclaw-teams', partialize: (state) => ({ teams: state.teams, activeTeam: state.activeTeam, }), } ) ); ``` --- ## 四、验证步骤 ### 4.1 手动验证清单 - [ ] 启动应用,- [ ] 发送消息,- [ ] 验证消息内容不重复 - [ ] 切换到团队 Tab - [ ] 切换回聊天 Tab - [ ] 验证消息仍然存在 - [ ] 刷新页面 (F5) - [ ] 验证消息历史恢复 - [ ] 创建团队 - [ ] 切换到其他 Tab - [ ] 验证团队仍然选中 ### 4.2 自动化测试建议 ```typescript // tests/desktop/state-persistence.test.ts describe('State Persistence', () => { it('should persist messages across tab switches', async () => { // 1. 发送消息 // 2. 切换 tab // 3. 切换回来 // 4. 验证消息存在 }); it('should not duplicate message content', async () => { // 1. 发送消息 // 2. 等待流式响应完成 // 3. 验证内容不重复 }); it('should persist activeTeam across tab switches', async () => { // 1. 选择团队 // 2. 切换 tab // 3. 切换回来 // 4. 验证团队仍然选中 }); }); ``` --- ## 五、后续工作 1. **执行用户旅程验证** - 按计划的 10 个用户旅程进行端到端测试 2. **编写回归测试** - 为状态持久化添加自动化测试 3. **问题追踪** - 发现新问题时记录到问题池 4. **回归验证** - 修复后重新验证相关功能 --- ## 六、风险评估 | 风险 | 影响 | 缓解措施 | |------|------|----------| | localStorage 容量 | 消息过多可能超出限制 | 限制消息历史长度 | | 性能影响 | 持久化增加 IO | 使用 debounce 优化 | | 数据一致性 | 多 Tab 数据同步 | 添加 storage 事件监听 | --- ## 七、结论 P0 问题已修复,系统可以进行用户旅程验证。建议: 1. 立即进行 J1-J3 核心聊天功能验证 2. 修复发现的新问题 3. 完成全部 10 个用户旅程验证后生成最终报告