fix(enterprise): 企业成员列表算力余额改读 compute-engine 实时真实余额
company_members.compute_balance 仅含企业分配,个人充值不进入该字段, 导致企业管理看不到成员真实算力。改为并发查询引擎 users.quota(微元, 个人充值+企业分配全量计入),换算为分返回;引擎不可用时回退平台镜像。
This commit is contained in:
+34
-2
@@ -7,6 +7,7 @@ sim_engine 需同步 tick,故另提供同步只读访问器 get_tenant_data_sy
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
|
||||
import hashlib
|
||||
@@ -491,15 +492,22 @@ async def company_member_count(s, company_id: str) -> int:
|
||||
|
||||
|
||||
async def company_members(company_id: str) -> list[dict]:
|
||||
"""企业成员列表(company_members JOIN users;is_admin 标注企业管理员)。"""
|
||||
"""企业成员列表(company_members JOIN users;is_admin 标注企业管理员)。
|
||||
|
||||
算力余额口径:compute_balance / compute_balance_used 采用 compute-engine 实时
|
||||
真实余额(单位=分;引擎 quota 为微元,个人充值+企业分配全部计入),
|
||||
避免只显示企业分配余额(company_members.compute_balance)而漏掉个人充值部分;
|
||||
引擎不可用时回退平台镜像(users.compute_quota / company_members.compute_balance)。
|
||||
"""
|
||||
async with _get_session() as s:
|
||||
rows = (await s.execute(
|
||||
select(User, CompanyMember).join(CompanyMember, CompanyMember.user_id == User.id).where(
|
||||
CompanyMember.company_id == company_id, CompanyMember.status == "active"
|
||||
).order_by(CompanyMember.created_at)
|
||||
)).all()
|
||||
return [{
|
||||
items = [{
|
||||
"id": u.id, "username": u.username, "nickname": u.nickname or "",
|
||||
"avatar": u.avatar or "",
|
||||
"phone": u.phone or "", "role": u.role or "",
|
||||
"is_admin": bool(cm.is_admin), "member_type": cm.member_type,
|
||||
"certification_status": u.certification_status or "uncertified",
|
||||
@@ -512,6 +520,30 @@ async def company_members(company_id: str) -> list[dict]:
|
||||
"created_at": u.created_at or "",
|
||||
} for u, cm in rows]
|
||||
|
||||
# 并发刷新引擎真实余额(1 元 = 1_000_000 micro = 100 分 → 1 分 = 10_000 micro)
|
||||
if items:
|
||||
from ..services import compute_client # 延迟导入避免循环依赖
|
||||
|
||||
async def _engine_balance(uname: str):
|
||||
try:
|
||||
data = await compute_client.user_balance(uname)
|
||||
quota = int(data.get("quota") or 0)
|
||||
used = int(data.get("used_quota") or 0)
|
||||
return quota, used
|
||||
except Exception: # noqa: BLE001 引擎不可用时回退镜像
|
||||
return None
|
||||
|
||||
balances = await asyncio.gather(*(_engine_balance(it["username"]) for it in items))
|
||||
for it, bal in zip(items, balances):
|
||||
if bal is None:
|
||||
continue
|
||||
quota, used = bal
|
||||
it["compute_quota"] = quota
|
||||
it["compute_used_quota"] = used
|
||||
it["compute_balance"] = max(0, quota - used) // 10_000 # 可用余额(分)
|
||||
it["compute_balance_used"] = used // 10_000 # 已用(分)
|
||||
return items
|
||||
|
||||
|
||||
async def add_company_member(company_id: str, user_id: str, *, is_admin: bool = False,
|
||||
created_by: str = "") -> dict | None:
|
||||
|
||||
Reference in New Issue
Block a user