# 聊天对话模块实现文档 ## 📅 实现日期 2025年10月14日 ## 🎯 项目概述 基于 **Cherry Studio** 的架构,完整重构了 MCP 客户端的聊天对话模块,实现了话题管理、消息流式响应、上下文管理等核心功能。 --- ## 📋 实现内容 ### 1️⃣ 类型系统 (`types/chat.ts`) #### 核心类型定义 ```typescript // 消息 interface Message { id: string role: 'user' | 'assistant' | 'system' content: string status: 'pending' | 'sending' | 'success' | 'error' timestamp: Date model?: string error?: string tokens?: { prompt: number; completion: number; total: number } } // 话题 interface Topic { id: string name: string description?: string createdAt: Date updatedAt: Date messageCount: number lastMessage?: string pinned?: boolean // 置顶 archived?: boolean // 归档 favorite?: boolean // 收藏 model?: string } // 对话 interface Conversation { id: string topicId: string messages: Message[] createdAt: Date updatedAt: Date metadata?: { model?: string temperature?: number maxTokens?: number systemPrompt?: string } } ``` --- ### 2️⃣ 聊天服务 (`services/chatService.ts`) #### 核心功能 ##### 话题管理 - ✅ **创建话题**: `createTopic(name, options)` - ✅ **获取话题列表**: `getTopics(filter)` - 支持搜索、置顶、归档、收藏过滤 - 自动排序(置顶优先,然后按更新时间) - ✅ **更新话题**: `updateTopic(topicId, updates)` - ✅ **删除话题**: `deleteTopic(topicId)` - ✅ **切换置顶**: `toggleTopicPin(topicId)` - ✅ **切换收藏**: `toggleTopicFavorite(topicId)` - ✅ **归档话题**: `archiveTopic(topicId)` ##### 消息管理 - ✅ **发送消息**: `sendMessage(options)` - 自动调用已连接的模型服务 - 支持上下文管理 - 错误处理和重试机制 - ✅ **流式发送**: `sendMessageStream(options, onChunk)` - 模拟流式输出效果 - 实时更新 UI - ✅ **删除消息**: `deleteMessage(topicId, messageId)` - ✅ **重新生成**: `regenerateMessage(topicId, messageId)` - 删除指定消息后的所有消息 - 使用最后一条用户消息重新请求 ##### 持久化 - ✅ **LocalStorage 存储** - `chat-topics`: 话题列表 - `chat-conversations`: 对话历史 - ✅ **自动加载和保存** - ✅ **Date 对象恢复** #### 技术亮点 1. **智能模型调用** ```typescript private async callModel(conversation, model?) { // 获取已连接的服务 const services = modelServiceManager.getAllServices() .filter(s => s.status === 'connected') // 准备消息历史 const messages = conversation.messages .filter(m => m.status === 'success') .map(m => ({ role: m.role, content: m.content })) // 调用 API const result = await modelServiceManager.sendChatRequest(...) // 解析响应(支持多种格式) return { content: this.parseModelResponse(result.data) } } ``` 2. **多格式响应解析** - 支持 OpenAI 格式 - 支持 Claude 格式 - 支持 Gemini 格式 - 支持自定义格式 3. **流式输出模拟** ```typescript // 模拟打字机效果 const chunkSize = 5 for (let i = 0; i < content.length; i += chunkSize) { const chunk = content.slice(i, i + chunkSize) onChunk(chunk) await new Promise(resolve => setTimeout(resolve, 30)) } ``` --- ### 3️⃣ 状态管理 (`stores/chatStore.ts`) #### 响应式状态 ```typescript interface ChatState { topics: Topic[] // 所有话题 currentTopicId: string | null // 当前选中的话题 messages: Message[] // 当前话题的消息 filter: TopicFilter // 话题过滤器 isLoading: boolean // 加载状态 isSending: boolean // 发送状态 } ``` #### Computed 属性 - `currentTopic`: 当前话题对象 - `filteredTopics`: 过滤后的话题列表 - `pinnedTopics`: 置顶话题列表 - `recentTopics`: 最近话题列表(最多10个) #### Actions ```typescript // 话题操作 createTopic(name) // 创建并切换到新话题 setCurrentTopic(topicId) // 切换话题 updateTopic(topicId, updates) // 更新话题 deleteTopic(topicId) // 删除话题 toggleTopicPin(topicId) // 切换置顶 toggleTopicFavorite(topicId) // 切换收藏 archiveTopic(topicId) // 归档话题 // 消息操作 sendMessage(content, model?) // 发送消息 sendMessageStream(content, model?, onChunk?) // 流式发送 deleteMessage(messageId) // 删除消息 regenerateMessage(messageId) // 重新生成 // 其他 setFilter(filter) // 设置过滤器 initialize() // 初始化 ``` --- ### 4️⃣ UI 组件 (`components/Chat/ChatLayout.vue`) #### 整体布局 ``` ┌────────────────────────────────────────────────┐ │ ┌──────────┐ ┌──────────────────────────┐ │ │ │ │ │ 对话头部 │ │ │ │ 话题 │ ├──────────────────────────┤ │ │ │ 列表 │ │ │ │ │ │ │ │ 消息列表 │ │ │ │ [搜索] │ │ │ │ │ │ │ │ - 用户消息 │ │ │ │ 话题1 │ │ - AI 回复 │ │ │ │ 话题2 │ │ ... │ │ │ │ 话题3 │ │ │ │ │ │ │ ├──────────────────────────┤ │ │ │ │ │ [输入框] [发送] │ │ │ └──────────┘ └──────────────────────────┘ │ └────────────────────────────────────────────────┘ ``` #### 核心功能 ##### 话题侧边栏 - ✅ 话题列表展示 - 名称、最后消息预览、消息数、时间 - 置顶话题显示在顶部 - ✅ 搜索功能 - 搜索话题名称和消息内容 - 实时过滤 - ✅ 话题操作菜单 - 置顶/取消置顶 - 重命名 - 删除 - ✅ 创建新话题 ##### 对话区域 - ✅ 空状态提示 - 引导用户创建对话 - ✅ 对话头部 - 显示话题名称和消息数 - 清空消息按钮 - ✅ 消息列表 - 用户/助手消息区分 - 头像、角色、时间显示 - 发送状态(发送中、成功、失败) - 打字机动画效果 - ✅ 消息操作 - 复制消息 - 重新生成 - 删除消息 - ✅ 输入区域 - 多行文本输入 - Shift+Enter 换行,Enter 发送 - 发送按钮 - 模型显示(可选) #### UI 特性 1. **响应式布局** - 左侧固定宽度 280px - 右侧自适应 2. **滚动优化** - 自动滚动到底部 - 平滑滚动动画 3. **状态反馈** - Loading 状态 - 发送状态标签 - 错误提示 4. **交互体验** - Hover 效果 - 选中高亮 - 快捷键支持 --- ## 🎨 样式设计 ### 颜色系统 - 使用 CSS 变量,支持主题切换 - 用户消息:主色调 - AI 消息:成功色 - 错误:错误色 ### 动画效果 - **打字机动画**: 三个跳动的圆点 ```css @keyframes typing { 0%, 60%, 100% { opacity: 0.3; } 30% { opacity: 1; } } ``` - **消息淡入**: 新消息出现动画 - **滚动动画**: 平滑滚动到底部 --- ## 🔧 技术栈 ### 核心框架 - **Vue 3**: Composition API - **TypeScript**: 完整类型支持 - **Naive UI**: UI 组件库 ### 状态管理 - **Vue Reactivity API**: `reactive`, `computed`, `ref` - **Custom Composable**: `useChatStore()` ### 数据持久化 - **LocalStorage** - `chat-topics`: 话题数据 - `chat-conversations`: 对话数据 ### 图标库 - **@vicons/tabler** --- ## 📊 数据流 ``` 用户输入 → ChatLayout ↓ 触发 sendMessage() ↓ useChatStore().sendMessageStream() ↓ chatService.sendMessageStream() ↓ 1. 创建用户消息 2. 保存到 conversation 3. 创建助手消息占位符 4. 调用 modelServiceManager 5. 流式接收响应 6. 实时更新 UI 7. 更新话题信息 ↓ 保存到 LocalStorage ``` --- ## 🚀 使用指南 ### 基本使用 1. **启动应用** ```bash npm run dev ``` 2. **配置模型服务** - 前往"模型服务"页面 - 添加并连接模型服务(如 OpenAI、Claude) 3. **开始对话** - 点击左侧菜单"聊天对话" - 自动创建默认话题 - 输入消息开始聊天 ### 功能演示 #### 创建新话题 ```typescript // 方法1:通过按钮 点击侧边栏"+"按钮 → 输入话题名称 → 确认 // 方法2:通过代码 const store = useChatStore() store.createTopic('我的新对话') ``` #### 发送消息 ```typescript const store = useChatStore() // 普通发送 await store.sendMessage('你好,请介绍一下自己') // 流式发送 await store.sendMessageStream( '请写一篇文章', undefined, (chunk) => console.log('收到:', chunk) ) ``` #### 管理话题 ```typescript // 置顶 store.toggleTopicPin(topicId) // 重命名 store.updateTopic(topicId, { name: '新名称' }) // 删除 store.deleteTopic(topicId) ``` --- ## 💡 高级特性 ### 1. 上下文管理 系统自动管理对话上下文: ```typescript // 发送消息时,自动包含历史消息 const messages = conversation.messages .filter(m => m.status === 'success') .map(m => ({ role: m.role, content: m.content })) ``` ### 2. 多格式支持 支持解析多种 AI 服务的响应格式: - OpenAI: `choices[0].message.content` - Claude: `content[].text` - Gemini: `candidates[0].content.parts[].text` - 自定义格式 ### 3. 错误处理 ```typescript try { await store.sendMessage(content) } catch (error) { // 自动显示错误信息 // 消息标记为 error 状态 // 用户可以重试或重新生成 } ``` ### 4. 流式响应 虽然当前是模拟流式,但架构已支持真实流式: ```typescript // 未来可以直接替换为真实的 SSE 或 WebSocket await this.callModelStream(conversation, model, (chunk) => { onChunk(chunk) // 实时回调 }) ``` --- ## 🔮 后续优化建议 ### 短期(本周) - [ ] 实现 Markdown 渲染 - [ ] 添加代码高亮 - [ ] 支持消息编辑 - [ ] 添加导出对话功能 ### 中期(本月) - [ ] 实现真实的流式响应(SSE) - [ ] 支持图片消息 - [ ] 添加语音输入 - [ ] 实现消息引用回复 - [ ] 添加快捷指令 ### 长期(季度) - [ ] 多模态支持(图片、文件) - [ ] 工具调用集成 - [ ] 知识库 RAG - [ ] 协作功能 - [ ] 插件系统 --- ## 📁 文件结构 ``` web/src/ ├── types/ │ └── chat.ts # 类型定义 ├── services/ │ └── chatService.ts # 聊天服务 ├── stores/ │ └── chatStore.ts # 状态管理 ├── components/ │ └── Chat/ │ └── ChatLayout.vue # 统一布局组件 └── SimpleApp.vue # 主应用(已集成) ``` --- ## 🐛 已知限制 1. **流式响应** - 当前是模拟流式,需要后端支持 SSE - 可优化为真实的流式传输 2. **Markdown 渲染** - 当前显示纯文本 - 需要集成 markdown-it 或类似库 3. **代码高亮** - 需要集成 highlight.js 或 Prism.js 4. **图片/文件支持** - 当前仅支持文本消息 5. **性能** - 大量消息时需要虚拟滚动优化 --- ## 📝 对比 Cherry Studio ### 相似点 ✅ 话题管理架构 ✅ 消息流式响应 ✅ LocalStorage 持久化 ✅ 上下文管理 ✅ 响应式状态管理 ### 简化点 - 使用单一组件代替多个子组件 - 简化的 UI 设计 - 基础的消息渲染(无 Markdown) - 模拟流式响应 ### 扩展空间 - 易于添加 Markdown 渲染 - 易于添加工具调用 - 易于集成 MCP 协议 - 架构支持未来扩展 --- ## 🎉 总结 成功实现了一个**功能完整、架构清晰、易于扩展**的聊天对话模块: ✅ 600+ 行核心服务代码 ✅ 200+ 行类型定义 ✅ 200+ 行状态管理 ✅ 600+ 行 UI 组件 ✅ 完整的 CRUD 操作 ✅ 流式响应支持 ✅ LocalStorage 持久化 ✅ 零编译错误 **现在就刷新页面试试吧!** 🚀 --- *最后更新: 2025-10-14*