专家购买流程文档

更新日期: 2026-01-26
状态: ✅ 已实现


📋 流程概览

专家购买流程允许普通用户在专家市场中购买市场专家,支持三种购买模式:永久购买、订阅制和按次付费。


🔄 完整购买流程

1. 用户操作流程(前端)

用户访问专家市场
    ↓
浏览专家列表
    ↓
找到市场专家(source === 'market')
    ↓
点击"购买"按钮
    ↓
【步骤1】检查登录状态
    ├─ 未登录 → 提示登录 → 跳转登录页
    └─ 已登录 → 继续
    ↓
【步骤2】从JWT Token解析用户ID
    ├─ 成功 → 继续
    └─ 失败 → 提示重新登录
    ↓
【步骤3】选择购买类型
    ├─ 1. 永久购买 (perpetual)
    ├─ 2. 订阅制 (subscription) → 输入订阅天数
    └─ 3. 按次付费 (pay_per_use) → 输入使用次数
    ↓
【步骤4】确认购买
    ├─ 显示专家名称、购买类型、价格
    ├─ 用户确认 → 继续
    └─ 用户取消 → 结束
    ↓
【步骤5】调用购买API
    POST /api/v1/expert-pool/{expert_id}/purchase
    ↓
【步骤6】处理结果
    ├─ 成功 → 显示成功提示 → 刷新页面
    └─ 失败 → 显示错误信息

🎯 详细步骤说明

步骤1:访问专家市场

URL: https://mbe.hi-maker.com/ui/market

功能:

  • 显示所有可用的专家(平台专家 + 市场专家)
  • 市场专家卡片显示"购买"按钮
  • 平台专家只显示"立即使用"按钮

代码位置: src/api/ui.py - expert_market_page()


步骤2:点击购买按钮

触发函数: purchaseExpert(expertId, expertName, pricePer1k)

参数:

  • expertId: 专家ID(model_id 或 kb_id)
  • expertName: 专家名称
  • pricePer1k: 每1000 Token的价格

代码位置: src/api/ui.py (行 3851-3932)


步骤3:用户身份验证

验证逻辑:

// 1. 检查是否有Token
const token = localStorage.getItem('token');
if (!token) {
    // 提示登录
    window.location.href = '/user/login?redirect=/ui/market';
    return;
}

// 2. 从Token解析用户ID
const payload = JSON.parse(atob(token.split('.')[1]));
const userId = payload.sub;

步骤4:选择购买类型

三种购买模式:

4.1 永久购买 (perpetual)

  • 特点: 一次购买,永久使用
  • 价格计算: price = pricePer1k * 1000 / 1000(示例:¥0.01/千Token × 1000 = ¥10)
  • 有效期: 永久有效
  • 使用限制:

4.2 订阅制 (subscription)

  • 特点: 按时间段订阅
  • 需要输入: 订阅天数(如:30天)
  • 价格计算: price = pricePer1k * 1000 / 1000(基础价格)
  • 有效期: 购买时间 + 订阅天数
  • 过期后: 需要重新订阅

4.3 按次付费 (pay_per_use)

  • 特点: 按使用次数付费
  • 需要输入: 购买次数(如:100次)
  • 价格计算: price = pricePer1k * useCount / 1000
  • 有效期: 永久(直到次数用完)
  • 使用限制: 每次使用扣减1次

步骤5:确认购买

确认对话框显示:

确认购买「{专家名称}」?
类型:{永久/订阅/按次}
价格:¥{计算后的价格}

用户操作:

  • 点击"确定" → 继续购买
  • 点击"取消" → 取消购买

步骤6:调用购买API

API端点: POST /api/v1/expert-pool/{expert_id}/purchase

请求参数:

  • user_id (Query): 用户ID
  • purchase_type (Query): 购买类型(perpetual/subscription/pay_per_use)
  • duration_days (Query, 可选): 订阅天数(仅订阅制)
  • use_count (Query, 可选): 使用次数(仅按次付费)

请求示例:

POST /api/v1/expert-pool/expert_123/purchase?user_id=user_456&purchase_type=perpetual
Authorization: Bearer {token}

代码位置: src/api/expert_pool.py (行 287-337)


🔧 后端处理流程

API处理步骤

接收购买请求
    ↓
【验证1】检查专家是否存在
    ├─ 不存在 → 返回404
    └─ 存在 → 继续
    ↓
【验证2】检查是否为市场专家
    ├─ 不是市场专家 → 返回400
    └─ 是市场专家 → 继续
    ↓
【验证3】验证购买类型
    ├─ 无效类型 → 返回400
    └─ 有效类型 → 继续
    ↓
【处理】创建购买记录
    ├─ 计算价格
    ├─ 设置过期时间(订阅制)
    ├─ 设置剩余次数(按次付费)
    └─ 保存到Redis
    ↓
【返回】购买结果
    ├─ 成功 → 返回购买信息
    └─ 失败 → 返回错误信息

💾 数据存储

购买记录结构

存储位置: Redis(键名:mbe:user:purchases:{user_id}

数据结构:

{
  "user_id": "uuid",
  "expert_id": "expert_123",
  "purchase_type": "perpetual",
  "purchased_at": "2026-01-26T00:00:00Z",
  "expires_at": null,
  "remaining_uses": null,
  "price_paid": 10.0
}

代码位置: src/users/expert_purchase.py


✅ 购买有效性检查

检查逻辑

永久购买:

  • ✅ 永久有效,无需检查

订阅制:

  • ✅ 检查 expires_at 是否过期
  • 当前时间 < expires_at → 有效
  • 当前时间 >= expires_at → 无效

按次付费:

  • ✅ 检查 remaining_uses 是否大于0
  • remaining_uses > 0 → 有效
  • remaining_uses <= 0 → 无效

代码位置: src/users/expert_purchase.py - ExpertPurchase.is_valid()


📊 使用专家时的检查

权限检查流程

当用户尝试使用专家时,系统会:

  1. 检查购买记录

    • 查询用户是否购买了该专家
    • 检查购买是否有效(未过期、有剩余次数)
  2. 扣减使用次数(仅按次付费)

    • 每次使用扣减 remaining_uses - 1
    • 更新Redis中的购买记录
  3. 返回结果

    • 有有效购买 → 允许使用
    • 无购买或已过期 → 拒绝使用

代码位置: src/users/expert_purchase.py - use_expert()


🔍 查看购买记录

API端点

获取用户购买记录:

GET /api/v1/expert-pool/user/{user_id}/purchases

返回数据:

{
  "purchases": [
    {
      "user_id": "uuid",
      "expert_id": "expert_123",
      "purchase_type": "perpetual",
      "purchased_at": "2026-01-26T00:00:00Z",
      "expires_at": null,
      "remaining_uses": null,
      "price_paid": 10.0
    }
  ]
}

代码位置: src/api/expert_pool.py (行 340-347)


🎨 UI界面

专家市场页面

位置: /ui/market

显示内容:

  • 专家卡片(名称、描述、价格、评分)
  • "立即使用"按钮(所有专家)
  • "购买"按钮(仅市场专家)

购买按钮显示条件:

e.source === 'market' ? `
  <button onclick="purchaseExpert(...)">购买</button>
` : ''

⚠️ 当前限制

已实现功能

  • ✅ 三种购买模式
  • ✅ 购买记录存储(Redis)
  • ✅ 购买有效性检查
  • ✅ 使用次数扣减(按次付费)
  • ✅ 购买记录查询API

待实现功能

  • 真实支付集成(微信/支付宝)

    • 当前:仅记录购买,不涉及真实支付
    • 需要:集成支付网关,处理支付回调
  • 购买记录页面

    • 当前:只能通过API查询
    • 需要:创建UI页面显示购买历史
  • 购买优惠券/折扣

    • 当前:固定价格
    • 需要:支持优惠券、批量折扣
  • 购买统计

    • 当前:无统计功能
    • 需要:购买历史统计、消费分析

🧪 测试示例

测试场景1:永久购买

  1. 登录系统(user1@mbe-test.com
  2. 访问 /ui/market
  3. 找到市场专家,点击"购买"
  4. 选择"1. 永久购买"
  5. 确认购买
  6. 验证:购买成功,可以永久使用

测试场景2:订阅制

  1. 登录系统
  2. 访问 /ui/market
  3. 找到市场专家,点击"购买"
  4. 选择"2. 订阅制"
  5. 输入订阅天数:30
  6. 确认购买
  7. 验证:购买成功,30天后过期

测试场景3:按次付费

  1. 登录系统
  2. 访问 /ui/market
  3. 找到市场专家,点击"购买"
  4. 选择"3. 按次付费"
  5. 输入购买次数:100
  6. 确认购买
  7. 验证:购买成功,剩余100次
  8. 使用专家:每次使用扣减1次

📝 API参考

POST /api/v1/expert-pool/{expert_id}/purchase

请求:

POST /api/v1/expert-pool/expert_123/purchase?user_id=user_456&purchase_type=perpetual
Authorization: Bearer {token}

响应(成功):

{
  "success": true,
  "message": "成功购买专家 法律顾问",
  "purchase": {
    "user_id": "user_456",
    "expert_id": "expert_123",
    "purchase_type": "perpetual",
    "purchased_at": "2026-01-26T00:00:00Z",
    "expires_at": null,
    "remaining_uses": null,
    "price_paid": 10.0
  }
}

响应(失败):

{
  "detail": "专家不存在"
}

🔗 相关文件

  • 前端UI: src/api/ui.py - expert_market_page(), purchaseExpert()
  • 购买API: src/api/expert_pool.py - purchase_expert()
  • 购买管理: src/users/expert_purchase.py - ExpertPurchaseManager
  • 权限检查: src/core/permissions.py - 专家权限验证

最后更新:2026-01-26
版本:v1.0
状态:已实现(基础功能)