专家购买流程测试指南
测试日期: 2026-01-26
测试账户:user1@mbe-test.com/Test@123456
📋 测试前准备
1. 确认测试账户
普通用户账户:
- 邮箱:
user1@mbe-test.com - 密码:
Test@123456
2. 确认测试环境
- 专家市场URL:
https://mbe.hi-maker.com/ui/market - 登录URL:
https://mbe.hi-maker.com/user/login - 购买API:
POST /api/v1/expert-pool/{expert_id}/purchase
🧪 完整测试流程
测试场景1:永久购买
步骤1:访问专家市场
- 打开浏览器
- 访问:
https://mbe.hi-maker.com/ui/market - 预期结果:
- ✅ 页面正常加载
- ✅ 显示"精选专家"和"热门专家"列表
- ✅ 专家卡片显示价格信息
- ✅ 有价格的专家显示"💰 购买"按钮
步骤2:登录系统
- 如果未登录,点击"登录"按钮
- 输入邮箱:
user1@mbe-test.com - 输入密码:
Test@123456 - 点击"登录"
- 预期结果:
- ✅ 登录成功
- ✅ 跳转回专家市场页面
- ✅ 导航栏显示用户信息
步骤3:选择专家并点击购买
- 在专家列表中找到一个有价格的专家
- 确认该专家卡片显示"💰 购买"按钮
- 点击"💰 购买"按钮
- 预期结果:
- ✅ 弹出购买类型选择对话框
- ✅ 显示三种购买选项:
- 永久购买 (perpetual)
- 订阅制 (subscription)
- 按次付费 (pay_per_use)
步骤4:选择购买类型
- 在对话框中输入:
1 - 点击"确定"
- 预期结果:
- ✅ 弹出确认购买对话框
- ✅ 显示专家名称
- ✅ 显示购买类型:永久
- ✅ 显示价格(基于
pricePer1k * 1000 / 1000)
步骤5:确认购买
- 在确认对话框中点击"确定"
- 预期结果:
- ✅ 显示"购买成功!您现在可以使用该专家了。"
- ✅ 页面自动刷新
- ✅ 购买记录已保存到Redis
步骤6:验证购买记录
- 打开浏览器开发者工具(F12)
- 在Console中执行:
const token = localStorage.getItem('token'); const payload = JSON.parse(atob(token.split('.')[1])); const userId = payload.sub; fetch(`/api/v1/expert-pool/user/${userId}/purchases`, { headers: { 'Authorization': 'Bearer ' + token } }).then(r => r.json()).then(console.log); - 预期结果:
- ✅ 返回购买记录列表
- ✅ 包含刚才购买的专家
- ✅
purchase_type为"perpetual" - ✅
expires_at为null - ✅
remaining_uses为null
测试场景2:订阅制购买
步骤1-2:同场景1(访问市场、登录)
步骤3:选择专家并点击购买
- 选择一个有价格的专家
- 点击"💰 购买"按钮
步骤4:选择订阅制
- 在购买类型对话框中输入:
2 - 点击"确定"
- 预期结果:
- ✅ 弹出订阅天数输入对话框
步骤5:输入订阅天数
- 在对话框中输入:
30 - 点击"确定"
- 预期结果:
- ✅ 弹出确认购买对话框
- ✅ 显示购买类型:订阅
- ✅ 显示价格
步骤6:确认购买
- 点击"确定"
- 预期结果:
- ✅ 购买成功提示
- ✅ 页面刷新
步骤7:验证购买记录
- 使用Console查询购买记录(同场景1步骤6)
- 预期结果:
- ✅ 购买记录中
purchase_type为"subscription" - ✅
expires_at有值(购买时间 + 30天) - ✅
remaining_uses为null
- ✅ 购买记录中
测试场景3:按次付费购买
步骤1-2:同场景1(访问市场、登录)
步骤3:选择专家并点击购买
- 选择一个有价格的专家
- 点击"💰 购买"按钮
步骤4:选择按次付费
- 在购买类型对话框中输入:
3 - 点击"确定"
- 预期结果:
- ✅ 弹出使用次数输入对话框
步骤5:输入购买次数
- 在对话框中输入:
100 - 点击"确定"
- 预期结果:
- ✅ 弹出确认购买对话框
- ✅ 显示购买类型:按次
- ✅ 显示价格(
pricePer1k * 100 / 1000)
步骤6:确认购买
- 点击"确定"
- 预期结果:
- ✅ 购买成功提示
- ✅ 页面刷新
步骤7:验证购买记录
- 使用Console查询购买记录
- 预期结果:
- ✅ 购买记录中
purchase_type为"pay_per_use" - ✅
expires_at为null - ✅
remaining_uses为100
- ✅ 购买记录中
🔍 测试检查点
功能检查
购买按钮显示
- 有价格的专家显示"💰 购买"按钮
- 无价格的专家不显示购买按钮
- 按钮样式正确(绿色,带💰图标)
登录验证
- 未登录时点击购买,提示登录
- 登录后可以正常购买
购买类型选择
- 永久购买:无需额外输入
- 订阅制:需要输入订阅天数
- 按次付费:需要输入使用次数
价格计算
- 永久购买:
price = pricePer1k * 1000 / 1000 - 订阅制:
price = pricePer1k * 1000 / 1000 - 按次付费:
price = pricePer1k * useCount / 1000
- 永久购买:
API调用
- 正确调用
/api/v1/expert-pool/{expert_id}/purchase - 传递正确的参数(user_id, purchase_type, duration_days, use_count)
- 包含Authorization header
- 正确调用
购买记录
- 购买记录正确保存到Redis
- 可以通过API查询购买记录
- 购买记录包含所有必要字段
错误处理检查
未登录处理
- 点击购买时提示登录
- 登录后可以继续购买流程
无效输入处理
- 输入无效的购买类型(如4、5)→ 提示"无效的选择"
- 取消购买类型选择 → 不执行购买
- 取消确认对话框 → 不执行购买
API错误处理
- 专家不存在 → 显示错误信息
- 不是市场专家 → 显示错误信息
- 网络错误 → 显示"购买失败,请重试"
🐛 常见问题排查
问题1:看不到购买按钮
可能原因:
- 专家数据中没有
model_id或price_per_1k_tokens字段 - 价格字段为0或null
排查步骤:
- 打开浏览器开发者工具(F12)
- 查看Network标签,检查
/api/market/的响应 - 确认返回的专家数据包含:
model_id字段price_per_1k_tokens字段且值 > 0
解决方案:
- 检查市场API返回的数据结构
- 确认专家已正确发布到市场
问题2:购买时提示"获取用户信息失败"
可能原因:
- JWT Token格式不正确
- Token中缺少
sub字段
排查步骤:
- 检查
localStorage.getItem('token')是否有值 - 在Console中执行:
const token = localStorage.getItem('token'); const payload = JSON.parse(atob(token.split('.')[1])); console.log(payload); - 确认
payload.sub存在
解决方案:
- 重新登录获取新的Token
- 检查登录API返回的Token格式
问题3:购买API返回404或400错误
可能原因:
- 专家ID不正确
- 专家不是市场专家
- 购买类型无效
排查步骤:
- 检查浏览器Network标签中的API请求
- 查看请求URL和参数
- 查看响应内容
解决方案:
- 确认专家ID正确(使用
model_id而不是kb_id) - 确认专家已发布到市场(
status === 'published') - 确认购买类型为:
perpetual、subscription或pay_per_use
问题4:购买记录查询不到
可能原因:
- Redis连接问题
- 购买记录未正确保存
排查步骤:
- 检查购买API的响应,确认返回
success: true - 检查Redis连接状态
- 直接查询Redis:
docker exec -it mbe-redis redis-cli KEYS mbe:user:purchases:* GET mbe:user:purchases:{user_id}
解决方案:
- 检查Redis服务是否正常运行
- 检查购买管理器的保存逻辑
📊 测试结果记录
测试场景1:永久购买
| 步骤 | 操作 | 预期结果 | 实际结果 | 状态 |
|---|---|---|---|---|
| 1 | 访问市场 | 页面加载 | ⬜ | |
| 2 | 登录系统 | 登录成功 | ⬜ | |
| 3 | 点击购买 | 弹出选择对话框 | ⬜ | |
| 4 | 选择永久购买 | 显示确认对话框 | ⬜ | |
| 5 | 确认购买 | 购买成功 | ⬜ | |
| 6 | 验证记录 | 记录存在 | ⬜ |
测试场景2:订阅制购买
| 步骤 | 操作 | 预期结果 | 实际结果 | 状态 |
|---|---|---|---|---|
| 1-2 | 访问市场、登录 | 正常 | ⬜ | |
| 3 | 点击购买 | 弹出选择对话框 | ⬜ | |
| 4 | 选择订阅制 | 弹出天数输入 | ⬜ | |
| 5 | 输入30天 | 显示确认对话框 | ⬜ | |
| 6 | 确认购买 | 购买成功 | ⬜ | |
| 7 | 验证记录 | 记录存在,有过期时间 | ⬜ |
测试场景3:按次付费购买
| 步骤 | 操作 | 预期结果 | 实际结果 | 状态 |
|---|---|---|---|---|
| 1-2 | 访问市场、登录 | 正常 | ⬜ | |
| 3 | 点击购买 | 弹出选择对话框 | ⬜ | |
| 4 | 选择按次付费 | 弹出次数输入 | ⬜ | |
| 5 | 输入100次 | 显示确认对话框 | ⬜ | |
| 6 | 确认购买 | 购买成功 | ⬜ | |
| 7 | 验证记录 | 记录存在,剩余100次 | ⬜ |
🔧 调试工具
浏览器Console命令
检查Token:
const token = localStorage.getItem('token');
console.log('Token:', token ? '存在' : '不存在');
if (token) {
const payload = JSON.parse(atob(token.split('.')[1]));
console.log('User ID:', payload.sub);
console.log('Role:', payload.role);
}
查询购买记录:
const token = localStorage.getItem('token');
const payload = JSON.parse(atob(token.split('.')[1]));
const userId = payload.sub;
fetch(`/api/v1/expert-pool/user/${userId}/purchases`, {
headers: { 'Authorization': 'Bearer ' + token }
})
.then(r => r.json())
.then(data => {
console.log('购买记录:', data);
if (data.purchases) {
data.purchases.forEach(p => {
console.log(`专家: ${p.expert_id}, 类型: ${p.purchase_type}, 有效: ${p.expires_at ? new Date(p.expires_at) > new Date() : '永久'}`);
});
}
});
测试购买API:
const token = localStorage.getItem('token');
const payload = JSON.parse(atob(token.split('.')[1]));
const userId = payload.sub;
const expertId = 'expert_123'; // 替换为实际的专家ID
fetch(`/api/v1/expert-pool/${expertId}/purchase?user_id=${userId}&purchase_type=perpetual`, {
method: 'POST',
headers: { 'Authorization': 'Bearer ' + token }
})
.then(r => r.json())
.then(data => console.log('购买结果:', data));
✅ 测试完成标准
必须通过的项目
- 购买按钮正确显示
- 登录验证正常工作
- 三种购买类型都可以正常购买
- 购买记录正确保存
- 购买记录可以查询
- 错误处理正确
可选测试项目
- 购买后立即使用专家(验证购买有效性)
- 订阅过期后无法使用(需要等待过期时间)
- 按次付费使用后次数扣减(需要实际使用专家)
最后更新:2026-01-26
版本:v1.0
测试状态:待测试