feat(wallet): 钱包系统替代配额系统,新增支付与退款机制

- 新增钱包余额管理、充值、扣费、退款完整流程
- 新增支付网关抽象层(支持手动/支付宝/微信)
- 用量计费从配额系统迁移到钱包余额扣费
- 新增管理员钱包管理与支付订单管理页面
- 新增用户钱包中心页面
- 移除独立 Key 锁定机制,统一由钱包余额控制
- 新增相关 API 路由、序列化器与数据库迁移
- 新增钱包、支付、退款相关测试
This commit is contained in:
LewisPen
2026-03-08 00:05:48 +08:00
committed by fawney19
parent 9cdcce1b5f
commit 783f654953
108 changed files with 13152 additions and 3372 deletions

View File

@@ -33,6 +33,7 @@ from src.services.system.stats_aggregator import (
query_time_series,
)
from src.services.system.time_range import TimeRangeParams
from src.services.wallet import WalletService
from src.utils.cache_decorator import cache_result
router = APIRouter(prefix="/api/dashboard", tags=["Dashboard"])
@@ -102,7 +103,7 @@ async def get_dashboard_stats(request: Request, db: Session = Depends(get_db)) -
- `users`: 用户统计total, active
**返回字段(普通用户)**:
- `stats`: 统计卡片数组,包含 API 密钥、本月请求、配额使用、总Token 等信息
- `stats`: 统计卡片数组,包含 API 密钥、本月请求、钱包状态、总Token 等信息
- `today`: 今日统计
- `token_breakdown`: Token 详细分类
- `cache_stats`: 缓存统计信息
@@ -770,20 +771,18 @@ class UserDashboardStatsAdapter(DashboardAdapter):
int(usage_stats.today_cache_read_tokens or 0) if usage_stats else 0
)
# 配额状态
if user.quota_usd is None:
quota_value = "无限制"
quota_change = f"已用 ${user.used_usd:.2f}"
quota_high = False
elif user.quota_usd > 0:
percent = min(100, int((user.used_usd / user.quota_usd) * 100))
quota_value = f"${user.quota_usd:.0f}"
quota_change = f"已用 ${user.used_usd:.2f}"
quota_high = percent > 80
wallet = WalletService.get_wallet(db, user_id=user.id)
billing = WalletService.serialize_wallet_summary(wallet)
wallet_balance = float(billing["balance"])
wallet_consumed = float(billing["total_consumed"])
if bool(billing["unlimited"]):
wallet_value = "无限制"
wallet_change = f"累计消费 ${wallet_consumed:.2f}"
wallet_high = False
else:
quota_value = "$0"
quota_change = f"已用 ${user.used_usd:.2f}"
quota_high = True
wallet_value = f"${wallet_balance:.2f}"
wallet_change = f"累计消费 ${wallet_consumed:.2f}"
wallet_high = wallet_balance <= 0
return {
"stats": [
@@ -804,10 +803,10 @@ class UserDashboardStatsAdapter(DashboardAdapter):
"icon": "Activity",
},
{
"name": "配额使用",
"value": quota_value,
"change": quota_change,
"changeType": "increase" if quota_high else "neutral",
"name": "钱包状态",
"value": wallet_value,
"change": wallet_change,
"changeType": "increase" if wallet_high else "neutral",
"icon": "TrendingUp",
},
{