feat(compute): 归户闭环——relay 透传用户PAT + 用户用量/余额接口

- relay /v1 转发优先透传客户端 Authorization(用户算力PAT→compute归户), 无则回落 COMPUTE_RELAY_TOKEN(匿名)
- compute_client: user_balance/user_usage(取该用户一枚PAT鉴权查 /api/user/self|self/usage)
- rbac_opc 新增 /opc/compute/usage(本月按模型) + /opc/compute/balance
This commit is contained in:
Pine
2026-08-25 14:38:23 +08:00
parent 6685d80600
commit e5e9d265bf
3 changed files with 56 additions and 4 deletions
+30
View File
@@ -136,6 +136,36 @@ async def list_user_tokens(username: str) -> dict:
return (data.get("data") or {}).get("items") or []
async def _user_key(username: str) -> str:
"""取该引擎用户一枚有效 PAT(用作 /api/user/self* 鉴权)。"""
items = await list_user_tokens(username)
for it in items or []:
k = it.get("key") or it.get("token")
if k:
return k
return ""
async def user_balance(username: str) -> dict:
"""用户余额(PAT 鉴权)。"""
key = await _user_key(username)
if not key:
return {"quota": 0, "used_quota": 0, "balance": 0}
data = await _request(method="GET", path="/api/user/self",
headers={"Authorization": f"Bearer {key}"})
return data.get("data") or {}
async def user_usage(username: str) -> dict:
"""本月按模型用量/费用(PAT 鉴权)。"""
key = await _user_key(username)
if not key:
return {"items": [], "cost_quota": 0, "input_tokens": 0, "output_tokens": 0}
data = await _request(method="GET", path="/api/user/self/usage",
headers={"Authorization": f"Bearer {key}"})
return data.get("data") or {}
async def delete_token(token_id: int) -> dict:
"""删除引擎令牌。"""
return await _request(