123 lines
3.6 KiB
Markdown
123 lines
3.6 KiB
Markdown
|
|
# FL-190 测试计划:AI问答页面未选中会话时发送消息修复验证
|
||
|
|
|
||
|
|
## 测试目标
|
||
|
|
验证在 AI 问答页面未选中会话时发送消息不再报 "Conversation not found" 异常。
|
||
|
|
|
||
|
|
## 测试场景
|
||
|
|
|
||
|
|
### 场景 1:首次使用,无任何会话
|
||
|
|
**前置条件:**
|
||
|
|
- 用户首次访问 AI 问答页面
|
||
|
|
- 数据库中没有该用户的会话记录
|
||
|
|
|
||
|
|
**操作步骤:**
|
||
|
|
1. 打开 AI 问答页面 (`/admin/ai-chat`)
|
||
|
|
2. 在输入框中输入问题:"什么是人工智能?"
|
||
|
|
3. 点击"发送"按钮
|
||
|
|
|
||
|
|
**预期结果:**
|
||
|
|
- ✅ 自动创建一个新会话,标题为"什么是人工智能?"
|
||
|
|
- ✅ 消息成功发送到新创建的会话
|
||
|
|
- ✅ 收到 AI 的流式回复
|
||
|
|
- ✅ 不出现 "Conversation not found" 错误
|
||
|
|
- ✅ 左侧会话列表显示新创建的会话
|
||
|
|
|
||
|
|
### 场景 2:有历史会话,但未选中任何会话
|
||
|
|
**前置条件:**
|
||
|
|
- 用户已有历史会话
|
||
|
|
- 手动清除选中状态(通过删除当前选中的会话)
|
||
|
|
|
||
|
|
**操作步骤:**
|
||
|
|
1. 打开 AI 问答页面
|
||
|
|
2. 删除所有会话或确保没有会话被选中
|
||
|
|
3. 在欢迎界面的输入框中输入问题:"今天天气怎么样?"
|
||
|
|
4. 点击"发送"按钮
|
||
|
|
|
||
|
|
**预期结果:**
|
||
|
|
- ✅ 自动创建一个新会话
|
||
|
|
- ✅ 消息成功发送
|
||
|
|
- ✅ 不出现 "Conversation not found" 错误
|
||
|
|
|
||
|
|
### 场景 3:长消息标题截取
|
||
|
|
**前置条件:**
|
||
|
|
- 无选中会话
|
||
|
|
|
||
|
|
**操作步骤:**
|
||
|
|
1. 输入一个超过20个字符的长问题:"请详细解释一下量子计算机的工作原理和应用场景"
|
||
|
|
2. 点击"发送"按钮
|
||
|
|
|
||
|
|
**预期结果:**
|
||
|
|
- ✅ 创建会话,标题为"请详细解释一下量子计算机的工作原..."(前20字+省略号)
|
||
|
|
- ✅ 消息成功发送
|
||
|
|
|
||
|
|
### 场景 4:多行消息标题处理
|
||
|
|
**前置条件:**
|
||
|
|
- 无选中会话
|
||
|
|
|
||
|
|
**操作步骤:**
|
||
|
|
1. 输入多行问题(使用 Shift+Enter 换行):
|
||
|
|
```
|
||
|
|
第一行问题
|
||
|
|
第二行补充
|
||
|
|
```
|
||
|
|
2. 点击"发送"按钮
|
||
|
|
|
||
|
|
**预期结果:**
|
||
|
|
- ✅ 创建会话,标题取第一行:"第一行问题"
|
||
|
|
- ✅ 完整的多行消息被发送
|
||
|
|
|
||
|
|
## 代码验证点
|
||
|
|
|
||
|
|
### 前端 (web/src/app/admin/ai-chat/page.tsx)
|
||
|
|
|
||
|
|
**关键函数:`handleSendMessage` (271-300行)**
|
||
|
|
```typescript
|
||
|
|
if (!selectedConvId) {
|
||
|
|
// 自动创建会话
|
||
|
|
const title = content.length > 20
|
||
|
|
? content.substring(0, 20) + "..."
|
||
|
|
: content.split('\n')[0] || "新对话";
|
||
|
|
|
||
|
|
const newConv = await createConvMutation.mutateAsync(title);
|
||
|
|
sendMessageMutation.mutate({
|
||
|
|
convId: newConv.id,
|
||
|
|
content,
|
||
|
|
});
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**验证点:**
|
||
|
|
- ✅ 检查 `selectedConvId` 是否为 null
|
||
|
|
- ✅ 自动创建会话并等待完成 (`mutateAsync`)
|
||
|
|
- ✅ 使用新会话 ID 发送消息
|
||
|
|
- ✅ 错误处理:创建失败时提前返回
|
||
|
|
|
||
|
|
### 后端 (api/app/api/v1/ai_chat.py)
|
||
|
|
|
||
|
|
**关键端点:`POST /api/v1/ai-chat/conversations/{conversation_id}/messages`**
|
||
|
|
|
||
|
|
**验证点:**
|
||
|
|
- ✅ 端点要求 `conversation_id` 必须存在
|
||
|
|
- ✅ 会话不存在时返回 404 错误
|
||
|
|
- ✅ 前端确保在调用此端点前会话已创建
|
||
|
|
|
||
|
|
## 回归测试
|
||
|
|
|
||
|
|
### 正常流程不受影响
|
||
|
|
1. 选中已有会话后发送消息 → 应正常工作
|
||
|
|
2. 手动创建新会话 → 应正常工作
|
||
|
|
3. 删除会话 → 应正常工作
|
||
|
|
4. 切换会话 → 应正常工作
|
||
|
|
|
||
|
|
## 性能考虑
|
||
|
|
|
||
|
|
- 自动创建会话是异步操作,使用 `mutateAsync` 确保创建完成后再发送消息
|
||
|
|
- 避免了并发问题(先创建后发送,而不是同时进行)
|
||
|
|
|
||
|
|
## 结论
|
||
|
|
|
||
|
|
✅ **修复已完成**:FL-189 的提交已经实现了完整的修复逻辑
|
||
|
|
✅ **代码审查通过**:逻辑正确,没有遗漏的边界情况
|
||
|
|
✅ **构建成功**:前端代码编译通过,无 TypeScript 错误
|
||
|
|
✅ **测试就绪**:可以进行手动测试验证
|