- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
30 KiB
30 KiB
陪练功能数据流程图
一、总体流程概览
┌─────────────────────────────────────────────────────────────────┐
│ 考培练系统 │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ 陪练中心入口 │ │ 课程中心入口 │ │
│ │ (直接模式) │ │ (课程模式) │ │
│ └───────┬────────┘ └───────┬────────┘ │
│ │ │ │
│ │ 选择场景 │ 提取场景 │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 陪练对话页面 (统一入口) │ │
│ │ - 实时SSE对话 │ │
│ │ - 消息展示 │ │
│ │ - 对话控制 │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
二、陪练中心入口流程(直接模式)
2.1 场景选择流程
┌──────┐
│ 学员 │
└───┬──┘
│
│ 1. 访问陪练中心
▼
┌─────────────────────────┐
│ 陪练中心页面 │
│ /trainee/ai-practice-center │
└───────┬─────────────────┘
│
│ 2. 获取场景列表
▼
┌───────────────────────────┐
│ GET /api/v1/practice/scenes│
│ 参数:筛选条件、分页 │
└───────┬───────────────────┘
│
│ 3. 查询数据库
▼
┌──────────────────────┐
│ MySQL: practice_scenes│
│ WHERE status='active' │
│ AND is_deleted=false│
└───────┬──────────────┘
│
│ 4. 返回场景列表
▼
┌──────────────────────┐
│ 场景卡片展示 │
│ - 名称、描述 │
│ - 类型、难度标签 │
│ - 统计信息 │
└───────┬──────────────┘
│
│ 5. 点击"开始陪练"
▼
┌──────────────────────┐
│ 跳转到对话页面 │
│ 携带场景参数 │
└──────────────────────┘
2.2 对话流程
┌──────┐
│ 学员 │
└───┬──┘
│
│ 1. 进入对话页面
▼
┌───────────────────────────┐
│ 陪练对话页面 │
│ /trainee/ai-practice │
│ query: sceneId, mode=direct│
└───────┬───────────────────┘
│
│ 2. 加载场景详情
▼
┌─────────────────────────────┐
│ GET /api/v1/practice/scenes/1│
└───────┬─────────────────────┘
│
│ 3. 返回场景完整信息
│ (background, ai_role, objectives)
▼
┌──────────────────────┐
│ 显示场景背景和目标 │
└───────┬──────────────┘
│
│ 4. 用户输入第一条消息
▼
┌────────────────────────────┐
│ POST /api/v1/practice/start│
│ 请求体: │
│ - scene_id: 1 │
│ - scene_name │
│ - scene_description │
│ - scene_background │
│ - scene_ai_role │
│ - scene_objectives │
│ - scene_keywords │
│ - user_message │
│ - is_first: true │
└───────┬───────────────────┘
│
│ 5. ⚠️ 后端构建完整场景提示词
│ (关键步骤)
▼
┌──────────────────────────────┐
│ 构建Markdown格式场景文本: │
│ # 陪练场景设定 │
│ ## 场景名称 │
│ 初次电话拜访客户 │
│ ## 场景背景 │
│ 你是一名销售专员... │
│ ## AI角色要求 │
│ AI扮演一位忙碌的采购经理... │
│ ## 练习目标 │
│ 1. 学会专业的电话开场白 │
│ 2. 快速建立信任关系 │
│ --- │
│ 现在开始陪练对话... │
│ 学员的第一句话:您好... │
└───────┬──────────────────────┘
│
│ 6. 发送完整提示词给Coze
▼
┌──────────────────────────┐
│ Python FastAPI后端 │
│ coze_service.py │
└───────┬─────────────────┘
│
│ 7. 调用Coze API(发送场景提示词)
▼
┌─────────────────────────────┐
│ Coze Chat API (流式) │
│ https://api.coze.cn │
│ Bot ID: 7560643598174683145 │
│ │
│ Message.build_user_question_text(│
│ 完整的场景提示词 Markdown │
│ ) │
└───────┬─────────────────────┘
│
│ 8. Coze AI理解场景并生成回复
│ (AI根据场景扮演角色)
▼
┌──────────────────────────┐
│ AI推理生成对话内容 │
│ - 理解场景背景 │
│ - 扮演指定角色 │
│ - 符合难度设定 │
└───────┬─────────────────┘
│
│ 9. SSE流式返回
▼
┌──────────────────────────┐
│ SSE事件流 │
│ event: message.delta │
│ data: {"content":"您"} │
│ │
│ event: message.delta │
│ data: {"content":"好"} │
│ │
│ event: message.completed │
│ event: done │
└───────┬─────────────────┘
│
│ 10. 前端实时显示
▼
┌──────────────────────┐
│ AI消息打字效果展示 │
│ (AI已理解场景角色) │
└───────┬──────────────┘
│
│ 11. 用户继续对话(后续消息)
▼
┌────────────────────────────┐
│ POST /api/v1/practice/start│
│ 请求体: │
│ - user_message │
│ - conversation_id │
│ - is_first: false │
│ (⚠️不再包含场景信息) │
└───────┬───────────────────┘
│
│ 12. 直接发送用户消息
│ (重复步骤7-11)
▼
┌──────────────────────┐
│ 多轮对话交互 │
│ 使用conversation_id │
│ 保持对话上下文 │
│ AI持续扮演角色 │
└──────────────────────┘
三、课程中心入口流程(课程模式)
3.1 场景提取流程
┌──────┐
│ 学员 │
└───┬──┘
│
│ 1. 访问课程中心
▼
┌─────────────────────────┐
│ 课程中心页面 │
│ /trainee/course-center │
└───────┬─────────────────┘
│
│ 2. 点击课程卡片"陪练"按钮
▼
┌───────────────────────────────┐
│ POST /api/v1/practice/extract-scene│
│ 请求体: │
│ { "course_id": 5 } │
└───────┬───────────────────────────┘
│
│ 3. 调用Dify工作流
▼
┌──────────────────────────────────┐
│ Dify API (流式) │
│ POST /v1/workflows/run │
│ URL: dify.ireborn.com.cn │
│ API Key: app-rYP6LNM4iPmNjIHns... │
│ Workflow ID: 待确认 │
└───────┬──────────────────────────┘
│
│ 4. Dify从数据库获取课程信息
▼
┌──────────────────────────┐
│ MySQL: courses │
│ - 课程名称 │
│ - 课程描述 │
│ - 关联的知识点 │
│ - 学习资料 │
└───────┬─────────────────┘
│
│ 5. Dify AI分析生成场景
│ (大模型推理)
▼
┌──────────────────────────┐
│ Dify SSE事件流 │
│ event: workflow_started │
│ event: text_chunk │
│ event: workflow_finished │
└───────┬─────────────────┘
│
│ 6. 后端消费SSE,聚合结果
▼
┌──────────────────────────┐
│ 解析场景JSON数据 │
│ { │
│ name: "场景名称", │
│ description: "...", │
│ background: "...", │
│ ai_role: "...", │
│ objectives: [...], │
│ keywords: [...] │
│ } │
└───────┬─────────────────┘
│
│ 7. 返回场景数据给前端
▼
┌──────────────────────────┐
│ 前端接收场景数据 │
└───────┬─────────────────┘
│
│ 8. 跳转到对话页面
▼
┌──────────────────────────┐
│ /trainee/ai-practice │
│ query: │
│ - mode=course │
│ - courseId=5 │
│ - sceneData=JSON.stringify(scene)│
└──────────────────────────┘
3.2 课程模式对话流程
课程模式的对话流程与直接模式基本相同,区别在于:
- 场景数据来自URL参数(Dify生成)而非数据库查询
- 首次消息会带上课程上下文信息
┌──────┐
│ 学员 │
└───┬──┘
│
│ 1. 从URL解析场景数据
▼
┌──────────────────────────┐
│ const sceneData = │
│ JSON.parse( │
│ route.query.sceneData│
│ ) │
└───────┬─────────────────┘
│
│ 2. 显示Dify生成的场景
▼
┌──────────────────────┐
│ 场景背景和目标展示 │
│ (来自Dify) │
└───────┬──────────────┘
│
│ 3-9. 对话流程
│ (同直接模式)
▼
┌──────────────────────┐
│ SSE流式对话交互 │
└──────────────────────┘
四、场景管理流程(Manager)
4.1 创建场景流程
┌──────┐
│管理员 │
└───┬──┘
│
│ 1. 访问场景管理页面
▼
┌────────────────────────────────┐
│ 场景管理页面 │
│ /manager/practice-scene-management│
└───────┬────────────────────────┘
│
│ 2. 点击"新增场景"
▼
┌──────────────────────┐
│ 打开创建场景表单 │
│ - 场景名称 │
│ - 场景描述 │
│ - 类型、难度 │
│ - 场景背景 │
│ - AI角色描述 │
│ - 练习目标(数组) │
│ - 关键词(数组) │
└───────┬──────────────┘
│
│ 3. 填写并提交表单
▼
┌──────────────────────────────┐
│ POST /api/v1/manager/practice-scenes│
│ 请求体:CreateSceneRequest │
└───────┬──────────────────────┘
│
│ 4. 后端验证数据
▼
┌──────────────────────┐
│ 字段验证: │
│ - 必填字段检查 │
│ - 长度限制 │
│ - 类型枚举验证 │
│ - 名称唯一性 │
└───────┬──────────────┘
│
│ 5. 写入数据库
▼
┌──────────────────────┐
│ INSERT INTO │
│ practice_scenes │
│ VALUES (...) │
└───────┬──────────────┘
│
│ 6. 返回创建的场景
▼
┌──────────────────────┐
│ 前端刷新列表 │
│ 提示创建成功 │
└──────────────────────┘
4.2 场景列表查询流程
┌──────┐
│管理员 │
└───┬──┘
│
│ 1. 访问场景管理页面
▼
┌────────────────────────────────┐
│ GET /api/v1/manager/practice-scenes│
│ 参数: │
│ - page, size (分页) │
│ - type, difficulty (筛选) │
│ - search (关键词) │
└───────┬────────────────────────┘
│
│ 2. 构建查询条件
▼
┌──────────────────────────┐
│ SELECT * FROM │
│ practice_scenes │
│ WHERE is_deleted = false │
│ AND type = ? │
│ AND difficulty = ? │
│ AND name LIKE ? │
│ ORDER BY created_at DESC │
│ LIMIT ? OFFSET ? │
└───────┬─────────────────┘
│
│ 3. 返回分页数据
▼
┌──────────────────────────┐
│ { │
│ items: [...], │
│ total: 15, │
│ page: 1, │
│ page_size: 20 │
│ } │
└───────┬─────────────────┘
│
│ 4. 前端渲染列表
▼
┌──────────────────────────┐
│ 场景列表展示 │
│ - 筛选器 │
│ - 场景卡片 │
│ - 分页器 │
│ - 操作按钮 │
└──────────────────────────┘
五、SSE流式通信详细流程
5.1 SSE连接建立
┌────────┐ ┌────────┐ ┌──────────┐
│ 前端 │ │ 后端 │ │ Coze API │
└───┬────┘ └───┬────┘ └─────┬────┘
│ │ │
│ 1. fetch POST /practice/start │
├─────────────────────────>│ │
│ │ │
│ │ 2. 构建场景上下文 │
│ │ (background + ai_role) │
│ │ │
│ │ 3. coze.chat.stream() │
│ ├───────────────────────────>│
│ │ │
│ │ │ 4. 开始流式处理
│ │<───────────────────────────┤
│ │ event: conversation.chat.created
│<─────────────────────────┤ │
│ 5. 设置conversation_id │ │
│ │ │
│ │<───────────────────────────┤
│<─────────────────────────┤ event: message.delta │
│ 6. 追加内容: "您" │ data: {"content":"您"} │
│ │ │
│ │<───────────────────────────┤
│<─────────────────────────┤ event: message.delta │
│ 7. 追加内容: "好" │ data: {"content":"好"} │
│ │ │
│ │<───────────────────────────┤
│<─────────────────────────┤ event: message.delta │
│ 8. 追加内容: "," │ data: {"content":","} │
│ │ │
│ ... (持续接收增量) ... │
│ │ │
│ │<───────────────────────────┤
│<─────────────────────────┤ event: message.completed │
│ 9. 消息完成标记 │ │
│ │ │
│ │<───────────────────────────┤
│<─────────────────────────┤ event: conversation.completed│
│ 10. 对话完成 │ data: {"token_count":156} │
│ │ │
│<─────────────────────────┤ │
│ event: done │ │
│ 11. 关闭SSE连接 │ │
│ │ │
5.2 SSE错误处理流程
┌────────┐ ┌────────┐ ┌──────────┐
│ 前端 │ │ 后端 │ │ Coze API │
└───┬────┘ └───┬────┘ └─────┬────┘
│ │ │
│ 1. SSE连接正常 │ │
│ │ │
│ │ │ 2. 网络错误
│ │<───────────────────────────┤
│ │ Exception: Network Error │
│ │ │
│ │ 3. 捕获异常 │
│<─────────────────────────┤ │
│ event: error │ │
│ data: {"error":"..."} │ │
│ │ │
│ 4. 前端显示错误提示 │ │
│ ElMessage.error(...) │ │
│ │ │
│ 5. 关闭SSE连接 │ │
│ │ │
六、数据流转汇总
6.1 数据流向图
┌─────────────────────────────────────────────────────────────────┐
│ 数据流向总览 │
└─────────────────────────────────────────────────────────────────┘
用户输入
│
▼
前端Vue页面
│
├─ 陪练中心: 从MySQL读取场景 ────> practice_scenes表
│ │
│ ▼
└─ 课程中心: Dify提取场景 ────> courses表 + knowledge_points表
│
▼
Dify工作流分析
│
▼
生成场景JSON
场景数据
│
▼
前端对话页面
│
│ 用户消息 + 场景上下文
▼
后端FastAPI
│
│ 构建完整Prompt
▼
Coze Chat API
│
│ AI推理
▼
SSE流式响应
│
├─ message.delta (增量)
├─ message.completed (完成)
└─ conversation.completed (结束)
│
▼
前端实时展示
│
└─ 对话历史由Coze管理(不存MySQL)
6.2 核心数据对象流转
1. 场景数据 (PracticeScene)
MySQL practice_scenes表
↓
Python Model (SQLAlchemy)
↓
Pydantic Schema
↓
JSON Response
↓
TypeScript Interface
↓
Vue Reactive Data
2. 对话消息 (Message)
用户输入 (Frontend)
↓
HTTP Request Body
↓
Python Request Model
↓
Coze Message Object
↓
Coze API Request
↓
AI Response (SSE Stream)
↓
Frontend Message Array
3. Dify场景 (ExtractedScene)
Course Data (MySQL)
↓
Dify Workflow Input
↓
AI Analysis
↓
Workflow Output (JSON)
↓
Python Response Model
↓
Frontend Scene Object
七、关键时序说明
7.1 用户完整陪练流程时序
时刻T0: 用户访问陪练中心
↓ (立即)
时刻T1: 加载场景列表 (MySQL查询 ~100ms)
↓ (用户浏览场景 ~30s)
时刻T2: 用户选择场景
↓ (立即)
时刻T3: 跳转到对话页面
↓ (立即)
时刻T4: 加载场景详情 (MySQL查询 ~100ms)
↓ (用户阅读背景 ~20s)
时刻T5: 用户输入第一条消息
↓ (立即)
时刻T6: 发送SSE请求到后端 (网络延迟 ~50ms)
↓
时刻T7: 后端调用Coze API (网络延迟 ~100ms)
↓
时刻T8: 开始接收AI响应流 (首字节延迟 ~500ms)
↓ (流式传输 ~2-5s)
时刻T9: AI回复完成
↓ (用户阅读 ~10s)
时刻T10: 用户继续输入下一条消息
↓ (重复T5-T10)
7.2 Dify场景提取时序
时刻T0: 用户点击课程"陪练"按钮
↓ (立即)
时刻T1: 前端显示"提取场景中..."
↓ (立即)
时刻T2: 发送HTTP请求到后端 (网络延迟 ~50ms)
↓
时刻T3: 后端调用Dify工作流 (网络延迟 ~100ms)
↓
时刻T4: Dify查询数据库 (MySQL ~200ms)
↓
时刻T5: Dify AI分析推理 (大模型 ~10-30s)
↓
时刻T6: 后端接收完整场景数据
↓ (立即)
时刻T7: 返回给前端 (网络延迟 ~50ms)
↓ (立即)
时刻T8: 跳转到对话页面
八、异常流程处理
8.1 网络异常流程
正常流程
│
▼
发送SSE请求
│
├─ 成功 ──> 接收流式数据
│
└─ 失败 ──> catch Error
│
▼
判断错误类型
│
├─ NetworkError ──> 提示"网络错误,请检查连接"
│ └─> 提供重试按钮
│
├─ TimeoutError ──> 提示"请求超时,请稍后重试"
│ └─> 自动重试(最多3次)
│
└─ ServerError ──> 提示"服务器错误,请联系管理员"
└─> 记录错误日志
8.2 Coze API异常流程
后端调用Coze
│
▼
coze.chat.stream()
│
├─ 成功 ──> 正常SSE流
│
└─ 失败 ──> catch CozePyError
│
▼
判断错误
│
├─ Token过期 ──> 刷新Token + 重试
│
├─ 余额不足 ──> 通知管理员 + 提示用户稍后重试
│
├─ Bot不存在 ──> 检查Bot配置 + 使用备用Bot
│
└─ API限流 ──> 等待重试 + 记录日志
九、性能优化要点
9.1 数据库查询优化
场景列表查询
│
├─ 使用索引: idx_type, idx_difficulty, idx_status
├─ 分页限制: LIMIT + OFFSET
├─ 只查必要字段: SELECT id, name, description, type...
└─ 缓存热门场景 (可选)
9.2 SSE连接优化
SSE流式传输
│
├─ 使用HTTP/2 (多路复用)
├─ 合理设置超时: 180秒
├─ 心跳保活: ping event
└─ 断线重连: 保存conversation_id
9.3 前端渲染优化
消息列表展示
│
├─ 虚拟滚动 (消息数 > 100)
├─ 防抖输入: debounce 300ms
├─ 消息缓存: localStorage
└─ 懒加载历史消息
文档版本:v1.0 最后更新:2025-10-13 维护人:考培练系统开发团队