- Base URL:
http://localhost:5000 - 协议: HTTP/HTTPS
- 数据格式: JSON
- 字符编码: UTF-8
- 虚拟物品系统: 已从实物奖品迁移为虚拟物品,简化兑换流程
- Solana 集成: 支持 Solana 钱包连接和 SOL 代币交互
- 三状态兑换: 虚拟物品兑换采用
not_redeemed→pending→redeemed流程
系统使用 Flask Session 进行用户认证,通过 Solana 钱包签名验证用户身份。
管理员接口使用 @admin_required 装饰器,需要先通过管理员登录获取权限。
// 检查用户是否已认证
if (!session.get('authenticated')) {
return jsonify({'error': '请先连接钱包'}), 401
}端点: POST /get_nonce
描述: 获取用于钱包签名验证的随机数
请求体:
{
"wallet_address": "5o5zCSxgtJkaxrtUoN555TwzP23tF4hMa7WHZnmjqbvy"
}响应:
{
"nonce": "random_string_12345"
}使用场景: 钱包连接前获取签名用的随机数
端点: POST /verify_signature
描述: 验证 Solana 钱包签名并建立用户会话
请求体:
{
"wallet_address": "5o5zCSxgtJkaxrtUoN555TwzP23tF4hMa7WHZnmjqbvy",
"signature": "base58_encoded_signature",
"nonce": "random_string_12345"
}成功响应:
{
"success": true,
"message": "钱包连接成功",
"wallet_address": "5o5zCSxgtJkaxrtUoN555TwzP23tF4hMa7WHZnmjqbvy"
}错误响应:
{
"error": "签名验证失败"
}端点: GET /check_auth
描述: 检查用户当前认证状态
响应:
{
"authenticated": true,
"wallet_address": "5o5zCSxgtJkaxrtUoN555TwzP23tF4hMa7WHZnmjqbvy"
}端点: POST /logout
描述: 清除用户会话
响应:
{
"success": true,
"message": "已成功退出登录"
}端点: GET /api/points/balance
认证: 需要用户登录
响应:
{
"success": true,
"data": {
"total_points": 1500,
"wallet_address": "5o5zCSxgtJkaxrtUoN555TwzP23tF4hMa7WHZnmjqbvy"
}
}端点: GET /api/points/history
认证: 需要用户登录
查询参数:
page(可选): 页码,默认 1per_page(可选): 每页数量,默认 20
响应:
{
"success": true,
"data": {
"history": [
{
"id": 1,
"change_type": "earn",
"points_change": 50,
"description": "SOL池子参与奖励",
"created_at": "2025-01-16T10:30:00"
}
],
"pagination": {
"page": 1,
"pages": 5,
"per_page": 20,
"total": 100
}
}
}端点: GET /api/points/leaderboard
查询参数:
limit(可选): 返回数量,默认 10sort_by(可选): 排序方式 (total/daily/weekly),默认total
响应:
{
"success": true,
"data": [
{
"rank": 1,
"wallet_address": "5o5z...qbvy",
"total_points": 5000,
"daily_points": 100,
"weekly_points": 500
}
]
}端点: GET /api/lootbox/list
响应:
{
"success": true,
"data": [
{
"id": 1,
"name": "积分盲盒",
"description": "使用积分参与的盲盒抽奖",
"cost_points": 100,
"cost_sol": null,
"is_active": true
}
]
}端点: POST /api/lootbox/draw
认证: 需要用户登录
请求体:
{
"loot_box_id": 1
}成功响应:
{
"success": true,
"data": {
"reward": {
"type": "points",
"name": "160积分",
"value": 160,
"description": "丰厚积分奖励",
"rarity": "rare"
},
"points_spent": 100,
"remaining_points": 1400
}
}虚拟物品奖励响应:
{
"success": true,
"data": {
"reward": {
"type": "virtual_item",
"name": "0.05 SOL",
"description": "稀有SOL代币奖励",
"rarity": "legendary"
},
"points_spent": 100,
"remaining_points": 1400
}
}端点: GET /api/lootbox/history
认证: 需要用户登录
查询参数:
page(可选): 页码,默认 1per_page(可选): 每页数量,默认 20
响应:
{
"success": true,
"data": {
"history": [
{
"id": 1,
"loot_box_name": "积分盲盒",
"reward_type": "virtual_item",
"reward_name": "0.05 SOL",
"reward_value": null,
"points_spent": 100,
"created_at": "2025-01-16T10:30:00"
}
],
"pagination": {
"page": 1,
"pages": 3,
"per_page": 20,
"total": 50
}
}
}端点: GET /api/lootbox/rewards/{loot_box_id}
路径参数:
loot_box_id: 盲盒ID
响应:
{
"success": true,
"data": [
{
"reward_name": "30积分",
"reward_type": "points",
"probability": 0.5,
"rarity": "common",
"remaining_quantity": 500000
},
{
"reward_name": "0.05 SOL",
"reward_type": "virtual_item",
"probability": 0.001,
"rarity": "legendary",
"remaining_quantity": 1000
}
]
}端点: GET /api/inventory
认证: 需要用户登录
查询参数:
type(可选): 物品类型过滤 (virtual_item/points)include_redeemed(可选): 是否包含已兑换物品,默认 false
响应:
{
"success": true,
"data": {
"items": [
{
"id": 4,
"item_type": "virtual_item",
"item_name": "0.05 SOL",
"item_description": "稀有SOL代币奖励",
"rarity": "legendary",
"source_type": "admin_gift",
"obtained_at": "2025-01-16T00:11:05",
"redemption_status": "not_redeemed",
"redemption_requested_at": null,
"redemption_completed_at": null
}
]
}
}端点: GET /api/inventory/stats
认证: 需要用户登录
响应:
{
"success": true,
"data": {
"total_items": 1,
"by_type": {
"virtual_item": 1,
"points": 0
},
"by_rarity": {
"legendary": 1,
"epic": 0,
"rare": 0,
"common": 0
}
}
}端点: GET /api/inventory/{item_id}
认证: 需要用户登录
路径参数:
item_id: 背包物品ID
响应:
{
"success": true,
"data": {
"id": 4,
"item_type": "virtual_item",
"item_name": "0.05 SOL",
"item_description": "稀有SOL代币奖励",
"rarity": "legendary",
"redemption_status": "not_redeemed"
}
}端点: POST /api/virtual-item/redeem
认证: 需要用户登录
请求体:
{
"inventory_id": 4
}成功响应:
{
"success": true,
"message": "兑换请求已提交,请等待管理员处理"
}错误响应:
{
"success": false,
"error": "物品不存在或已兑换"
}使用场景: 用户在背包中点击虚拟物品的"兑换"按钮
端点: GET /api/solana/blockhash
描述: 获取最新的 Solana 区块哈希用于交易
响应:
{
"success": true,
"blockhash": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9YcTth4L"
}端点: POST /api/sol-pool/participate
认证: 需要用户登录
请求体:
{
"transaction_hash": "5j7s8K9mN2pQ3rT4uV5wX6yZ7aB8cD9eF0gH1iJ2kL3mN4oP5qR6sT7uV8wX9yZ0"
}成功响应:
{
"success": true,
"message": "SOL池子参与成功",
"points_earned": 50,
"total_points": 1550
}错误响应:
{
"success": false,
"error": "交易验证失败"
}端点: GET /api/sol-pool/status
认证: 需要用户登录
响应:
{
"success": true,
"data": {
"can_participate": true,
"participation_fee": 0.02,
"points_reward": 50,
"target_address": "3WL45x5sxzdHjhRksJEvRc3tNkFQxJwyfPctpTYk6Shi"
}
}端点: GET /api/sol-pool/daily-stats
响应:
{
"success": true,
"data": [
{
"date": "2025-01-16",
"participation_count": 5,
"total_sol": 0.1,
"total_points": 250
}
]
}端点: POST /generate_image
认证: 需要用户登录
请求体:
{
"prompt": "a beautiful sunset over the ocean"
}成功响应:
{
"success": true,
"image_url": "/static/images/generated_12345.jpg",
"points_earned": 10,
"remaining_points": 1560
}端点: POST /generate_async
认证: 需要用户登录
请求体:
{
"prompt": "a beautiful sunset over the ocean"
}响应:
{
"task_id": "task_12345",
"status": "processing"
}端点: POST /generate_video
认证: 需要用户登录
请求体:
{
"prompt": "a cat playing in the garden"
}成功响应:
{
"success": true,
"video_url": "/static/videos/generated_12345.mp4",
"points_earned": 20,
"remaining_points": 1540
}端点: POST /generate_chat_audio
认证: 需要用户登录
请求体:
{
"prompt": "What is artificial intelligence?"
}成功响应:
{
"success": true,
"text_response": "Artificial intelligence is...",
"audio_url": "/static/audio/response_12345.wav"
}端点: GET /task/{task_id}
路径参数:
task_id: 任务ID
响应:
{
"status": "completed",
"result": {
"image_url": "/static/images/generated_12345.jpg"
},
"created_at": "2025-01-16T10:30:00",
"completed_at": "2025-01-16T10:31:00"
}状态值:
processing: 处理中completed: 已完成failed: 失败
端点: POST /api/product/experience/complete
认证: 需要用户登录
请求体:
{
"product_type": "image_generation"
}成功响应:
{
"success": true,
"points_earned": 10,
"remaining_count": 2,
"total_points": 1570
}产品类型:
image_generation: 文生图 (10积分,每日最多3次)video_generation: 文生视频 (20积分,每日最多2次)
端点: POST /admin/login
请求体:
{
"username": "admin",
"password": "admin_password"
}成功响应:
{
"success": true,
"message": "登录成功",
"admin_id": 1,
"username": "admin"
}端点: GET /admin/virtual-items/pending-redemptions
认证: 需要管理员权限
响应:
{
"success": true,
"data": [
{
"id": 4,
"wallet_address": "5o5zCSxgtJkaxrtUoN555TwzP23tF4hMa7WHZnmjqbvy",
"item_name": "0.05 SOL",
"item_description": "稀有SOL代币奖励",
"rarity": "legendary",
"redemption_requested_at": "2025-01-16T00:17:55"
}
]
}端点: PUT /admin/virtual-items/complete-redemption/{inventory_id}
认证: 需要管理员权限
路径参数:
inventory_id: 背包物品ID
请求体:
{
"notes": "兑换已完成"
}成功响应:
{
"success": true,
"message": "虚拟物品兑换已完成"
}端点: PUT /admin/virtual-items/cancel-redemption/{inventory_id}
认证: 需要管理员权限
路径参数:
inventory_id: 背包物品ID
成功响应:
{
"success": true,
"message": "兑换已取消,物品状态已重置为未兑换"
}端点: GET /admin/virtual-items/redemption-stats
认证: 需要管理员权限
响应:
{
"success": true,
"data": {
"pending_count": 1,
"today_requests": 1,
"total_virtual_items": 1,
"by_status": {
"pending": 1,
"not_redeemed": 0,
"redeemed": 0
}
}
}端点: GET /admin/physical-items
认证: 需要管理员权限
查询参数:
category(可选): 分类过滤
响应:
{
"success": true,
"data": [
{
"id": 1,
"name": "0.05 SOL",
"description": "稀有SOL代币奖励",
"category": "数字货币",
"estimated_value": 50.0,
"is_active": true
}
]
}端点: GET /admin/users
认证: 需要管理员权限
查询参数:
page(可选): 页码,默认 1per_page(可选): 每页数量,默认 20
响应:
{
"success": true,
"data": {
"users": [
{
"id": 1,
"wallet_address": "5o5z...qbvy",
"total_points": 1570,
"created_at": "2025-01-15T10:00:00",
"last_active": "2025-01-16T10:30:00"
}
],
"pagination": {
"page": 1,
"pages": 5,
"per_page": 20,
"total": 100
}
}
}{
"success": false,
"error": "错误描述信息"
}| 状态码 | 说明 | 示例场景 |
|---|---|---|
| 200 | 成功 | 正常请求处理 |
| 400 | 请求错误 | 参数缺失或格式错误 |
| 401 | 未认证 | 需要登录或权限不足 |
| 404 | 资源不存在 | 物品或用户不存在 |
| 500 | 服务器错误 | 系统内部错误 |
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
| "请先连接钱包" | 用户未登录 | 调用钱包连接接口 |
| "积分不足" | 用户积分余额不够 | 提示用户获取更多积分 |
| "物品不存在或已兑换" | 物品状态异常 | 刷新背包数据 |
| "签名验证失败" | 钱包签名无效 | 重新获取nonce并签名 |
// 1. 获取 nonce
const nonceResponse = await fetch('/get_nonce', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ wallet_address: walletAddress })
});
const { nonce } = await nonceResponse.json();
// 2. 钱包签名
const signature = await wallet.signMessage(nonce);
// 3. 验证签名
const verifyResponse = await fetch('/verify_signature', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
wallet_address: walletAddress,
signature: signature,
nonce: nonce
})
});// 1. 获取盲盒列表
const lootboxes = await fetch('/api/lootbox/list');
// 2. 执行抽奖
const drawResponse = await fetch('/api/lootbox/draw', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ loot_box_id: 1 })
});
// 3. 处理奖励结果
const result = await drawResponse.json();
if (result.success) {
if (result.data.reward.type === 'virtual_item') {
// 显示虚拟物品获得提示
showVirtualItemReward(result.data.reward);
} else {
// 显示积分奖励
showPointsReward(result.data.reward);
}
}// 1. 获取用户背包
const inventory = await fetch('/api/inventory');
// 2. 找到可兑换的虚拟物品
const virtualItems = inventory.data.items.filter(
item => item.item_type === 'virtual_item' &&
item.redemption_status === 'not_redeemed'
);
// 3. 申请兑换
const redeemResponse = await fetch('/api/virtual-item/redeem', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ inventory_id: virtualItems[0].id })
});
// 4. 处理兑换结果
if (redeemResponse.ok) {
// 兑换申请成功,状态变为 pending
showMessage('兑换申请已提交,请等待管理员处理');
}- 简化流程: 从复杂的实物配送改为简单的三状态管理
- 状态流转:
not_redeemed→pending→redeemed - 管理便捷: 管理员可直接确认或取消兑换请求
- 0.05 SOL: 唯一的虚拟物品,legendary 级别,概率 0.1%
| 状态 | 描述 | 用户操作 | 管理员操作 |
|---|---|---|---|
not_redeemed |
未兑换 | 可申请兑换 | - |
pending |
待处理 | 等待处理 | 可确认或取消 |
redeemed |
已兑换 | 已完成 | 查看记录 |
| 奖励 | 概率 | 数量 | 类型 |
|---|---|---|---|
| 30积分 | 50% | 500,000次 | 积分奖励 |
| 80积分 | 30% | 300,000次 | 积分奖励 |
| 160积分 | 15% | 150,000次 | 积分奖励 |
| 320积分 | 3.9% | 39,000次 | 积分奖励 |
| 1000积分 | 1% | 10,000次 | 积分奖励 |
| 0.05 SOL | 0.1% | 1,000次 | 虚拟物品 |
- common: 普通 (30-80积分)
- rare: 稀有 (160积分)
- epic: 史诗 (320积分)
- legendary: 传说 (1000积分, 0.05 SOL)
- 参与费用: 0.02 SOL
- 目标地址:
3WL45x5sxzdHjhRksJEvRc3tNkFQxJwyfPctpTYk6Shi - 奖励积分: 50积分/次
- 网络: Solana Mainnet
系统会验证交易的真实性,包括:
- 交易哈希有效性
- 转账金额正确性
- 目标地址匹配
- 发送方地址验证
| 功能 | 积分奖励 | 每日限制 |
|---|---|---|
| 文生图 | 10积分 | 3次 |
| 文生视频 | 20积分 | 2次 |
- 在 AI 功能成功完成后自动发放
- 需要调用
/api/product/experience/complete接口 - 超过每日限制后不再发放积分
- 普通用户: 只能访问用户相关接口
- 管理员: 可访问所有
/admin/*接口
- 用户管理 (查看、调整积分)
- 虚拟物品管理 (查看、编辑)
- 兑换管理 (确认、取消)
- 盲盒管理 (查看、编辑奖励)
- 统计数据查看
- 错误处理: 始终检查 API 响应的
success字段 - 认证状态: 在页面加载时检查用户认证状态
- 实时更新: 在关键操作后刷新相关数据
- 用户体验: 提供清晰的加载状态和错误提示
- 签名验证: 严格验证 Solana 钱包签名
- 会话管理: 定期检查会话有效性
- 输入验证: 验证所有用户输入
- 权限控制: 确保管理员接口的访问控制
- 缓存策略: 合理缓存静态数据
- 分页加载: 大量数据使用分页
- 异步处理: AI 功能使用异步任务
- 资源清理: 定期清理过期任务和文件
文档版本: v2.2.0 更新时间: 2025-01-16 系统状态: 虚拟物品系统已完成迁移 联系方式: 开发团队