# 停止生成功能修复总结
## 🎯 问题
1. **按钮点击无效** - 确认/停止按钮点击后没有响应
2. **停止逻辑不生效** - 即使调用了停止方法,AI 回复仍在继续生成
## ✅ 解决方案
参考 **Cherry Studio** 的 **PAUSED** 状态设计,实现完整的停止生成逻辑。
## 📝 修改清单
### 1. 修复按钮事件绑定 (`ChatLayout.vue`)
**原问题代码:**
```vue
@click="store.state.isSending ? handleStopGeneration : handleSendMessage"
```
**问题分析:**
- 这个三元表达式在编译时求值,而不是运行时
- 导致点击时总是执行同一个函数引用
**修复代码:**
```vue
@click="handleButtonClick"
```
```typescript
const handleButtonClick = () => {
if (store.state.isSending) {
handleStopGeneration()
} else {
handleSendMessage()
}
}
```
### 2. 添加 PAUSED 状态 (`types/chat.ts`)
```typescript
// 新增 paused 状态
export type MessageStatus = 'pending' | 'sending' | 'success' | 'error' | 'paused'
// 新增 paused 事件
export interface StreamEvent {
type: 'start' | 'delta' | 'end' | 'error' | 'paused'
// ...
}
```
### 3. 优化停止时的错误处理 (`chatService.ts`)
```typescript
catch (error) {
const isAborted = error instanceof Error && error.name === 'AbortError'
if (isAborted) {
// 用户主动停止 - 标记为 paused,保留内容
assistantMessage.status = 'paused'
assistantMessage.error = undefined
onChunk({ type: 'paused', messageId: assistantMessage.id })
} else {
// 真实错误 - 标记为 error
assistantMessage.status = 'error'
assistantMessage.error = error instanceof Error ? error.message : '发送失败'
onChunk({ type: 'error', error: assistantMessage.error })
}
}
```
### 4. 在流读取中检查中止信号 (`modelServiceManager.ts`)
**关键修复:**
```typescript
while (true) {
// ⚠️ 关键:每次读取前检查中止信号
if (signal?.aborted) {
console.log('🛑 检测到中止信号,停止读取流')
reader.cancel() // 取消流读取
throw new DOMException('用户中止操作', 'AbortError')
}
const { done, value } = await reader.read()
if (done) break
// 处理数据...
}
```
**优化 catch 块:**
```typescript
catch (error) {
if (timeoutId) clearTimeout(timeoutId)
// 正确处理 AbortError,不改写为"超时"
if (error instanceof Error && error.name === 'AbortError') {
throw error // 直接抛出,保留原始错误
}
if (error instanceof DOMException && error.name === 'AbortError') {
throw error
}
throw error
}
```
### 5. UI 显示优化 (`ChatLayout.vue`)
```vue