团队管理设置
This commit is contained in:
@@ -23,6 +23,7 @@ from app.models.image_engine import ImageEngine
|
||||
from app.models.credit_ratio import CreditRatio
|
||||
from app.models.operation_log import OperationLog
|
||||
from app.enums.user import FrontendUserKind, UserType
|
||||
from app.enums.team import TEAM_UNASSIGNED_VALUE
|
||||
from app.schemas.admin import (
|
||||
CreditAdjustRequest,
|
||||
ModelConfigCreate,
|
||||
@@ -37,6 +38,7 @@ from app.schemas.admin import (
|
||||
UpdateFrontendUserKindRequest,
|
||||
OperationLogOut,
|
||||
)
|
||||
from app.schemas.team import UpdateUserTeamRequest
|
||||
from app.schemas.industry import IndustryConfigCreate, IndustryConfigOut
|
||||
from app.schemas.video_engine import VideoEngineCreate, VideoEngineOut
|
||||
from app.schemas.image_engine import ImageEngineCreate, ImageEngineOut
|
||||
@@ -50,6 +52,7 @@ from app.services.operation_log import log_operation
|
||||
from app.services.resource_signed_url_service import build_resource_signed_url
|
||||
from app.services.payment import sync_pending_orders, process_refund
|
||||
from app.services.resource_capacity_service import batch_get_user_resource_capacity_usage, get_user_resource_capacity_usage
|
||||
from app.services.team_service import batch_get_team_name_map, set_frontend_user_team
|
||||
|
||||
from app.services.generation_billing_service import (
|
||||
OWNER_GENERATION_RECORD,
|
||||
@@ -89,6 +92,7 @@ async def list_users(
|
||||
search: str = Query(""),
|
||||
user_type: str | None = Query(None, pattern="^(frontend|admin)$"),
|
||||
frontend_user_kind: str | None = Query(None, pattern="^(internal|external)$"),
|
||||
team_id: str | None = Query(None),
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
@@ -105,16 +109,28 @@ async def list_users(
|
||||
if frontend_user_kind:
|
||||
query = query.where(User.user_type == UserType.FRONTEND.value, User.frontend_user_kind == frontend_user_kind)
|
||||
count_query = count_query.where(User.user_type == UserType.FRONTEND.value, User.frontend_user_kind == frontend_user_kind)
|
||||
if team_id:
|
||||
team_filter = User.team_id.is_(None) if team_id == TEAM_UNASSIGNED_VALUE else (User.team_id == team_id)
|
||||
query = query.where(team_filter)
|
||||
count_query = count_query.where(team_filter)
|
||||
total = (await db.execute(count_query)).scalar() or 0
|
||||
result = await db.execute(query.offset((page - 1) * page_size).limit(page_size))
|
||||
items = result.scalars().all()
|
||||
capacity_map = await batch_get_user_resource_capacity_usage(db, [u.id for u in items])
|
||||
users = list(result.scalars().all())
|
||||
user_ids = [u.id for u in users]
|
||||
team_ids = [getattr(u, "team_id", None) for u in users if getattr(u, "team_id", None)]
|
||||
capacity_map = await batch_get_user_resource_capacity_usage(db, user_ids)
|
||||
team_name_map = await batch_get_team_name_map(db, team_ids)
|
||||
return {
|
||||
"items": [
|
||||
AdminUserOut.model_validate(u)
|
||||
.model_copy(update={"resource_capacity": capacity_map.get(u.id)})
|
||||
AdminUserOut.model_validate(user)
|
||||
.model_copy(
|
||||
update={
|
||||
"resource_capacity": capacity_map.get(user.id),
|
||||
"team_name": team_name_map.get(getattr(user, "team_id", None)),
|
||||
}
|
||||
)
|
||||
.model_dump(mode="json")
|
||||
for u in items
|
||||
for user in users
|
||||
],
|
||||
"total": total,
|
||||
}
|
||||
@@ -194,8 +210,12 @@ async def get_user(
|
||||
raise HTTPException(status_code=404, detail="用户不存在")
|
||||
user.credits = round(user.credits, 2)
|
||||
resource_capacity = await get_user_resource_capacity_usage(db, user.id)
|
||||
team_name_map = await batch_get_team_name_map(db, [getattr(user, "team_id", None)])
|
||||
return AdminUserOut.model_validate(user).model_copy(
|
||||
update={"resource_capacity": resource_capacity}
|
||||
update={
|
||||
"resource_capacity": resource_capacity,
|
||||
"team_name": team_name_map.get(getattr(user, "team_id", None)),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -254,6 +274,29 @@ async def update_user_frontend_kind(
|
||||
return user
|
||||
|
||||
|
||||
@router.put("/users/{user_id}/team", response_model=AdminUserOut)
|
||||
async def update_user_team(
|
||||
user_id: str,
|
||||
req: UpdateUserTeamRequest,
|
||||
admin: User = Depends(get_admin_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
user, before, after = await set_frontend_user_team(db, user_id=user_id, team_id=req.team_id)
|
||||
await log_operation(
|
||||
db,
|
||||
admin.id,
|
||||
admin.username,
|
||||
f"设置用户团队 {user.username}",
|
||||
"PUT",
|
||||
f"/admin/users/{user_id}/team",
|
||||
detail=json.dumps({"before": before, "after": after}, ensure_ascii=False),
|
||||
)
|
||||
resource_capacity = await get_user_resource_capacity_usage(db, user.id)
|
||||
return AdminUserOut.model_validate(user).model_copy(
|
||||
update={"resource_capacity": resource_capacity, "team_name": after.get("team_name")}
|
||||
)
|
||||
|
||||
|
||||
@router.put("/users/{user_id}/reset-password")
|
||||
async def reset_user_password(
|
||||
user_id: str,
|
||||
@@ -299,6 +342,7 @@ async def list_credit_records(
|
||||
user_name: str | None = Query(None),
|
||||
user_type: str | None = Query(None),
|
||||
frontend_user_kind: str | None = Query(None),
|
||||
team_id: str | None = Query(None),
|
||||
record_type: str | None = Query(None),
|
||||
type: str | None = Query(None),
|
||||
credit_subject: str | None = Query(None),
|
||||
@@ -321,6 +365,7 @@ async def list_credit_records(
|
||||
user_name=user_name,
|
||||
user_type=user_type,
|
||||
frontend_user_kind=frontend_user_kind,
|
||||
team_id=team_id,
|
||||
record_type=record_type or type,
|
||||
credit_subject=credit_subject,
|
||||
media_type=media_type,
|
||||
|
||||
Reference in New Issue
Block a user