update at 2025-10-14 21:52:11

This commit is contained in:
douboer
2025-10-14 21:52:11 +08:00
parent ac3ed480ab
commit 4f5eea604e
40 changed files with 15231 additions and 126 deletions

539
CHAT_IMPLEMENTATION.md Normal file
View File

@@ -0,0 +1,539 @@
# 聊天对话模块实现文档
## 📅 实现日期
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*