137 lines
4.9 KiB
Python
137 lines
4.9 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.dependencies import get_admin_user, get_db
|
|
from app.models.user import User
|
|
from app.schemas.private_portrait import (
|
|
PrivatePortraitAdminConfigUpdate,
|
|
PrivatePortraitAssetListOut,
|
|
PrivatePortraitConfigOut,
|
|
PrivatePortraitProjectListOut,
|
|
)
|
|
from app.services.operation_log import log_operation
|
|
from app.services.private_portrait.asset_service import (
|
|
asset_to_out,
|
|
get_user_private_portrait_config,
|
|
list_assets,
|
|
set_user_private_portrait_limit,
|
|
)
|
|
from app.services.private_portrait.project_service import list_projects, project_to_out
|
|
|
|
router = APIRouter(prefix="/admin/private-portrait", tags=["admin-private-portrait"])
|
|
|
|
|
|
def _json_detail(data: dict[str, Any]) -> str:
|
|
return json.dumps(data, ensure_ascii=False, default=str)
|
|
|
|
|
|
@router.get("/users/{user_id}/config", response_model=PrivatePortraitConfigOut)
|
|
async def admin_get_private_portrait_config(
|
|
user_id: str,
|
|
admin: User = Depends(get_admin_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
config = await get_user_private_portrait_config(db, user_id=user_id)
|
|
await log_operation(
|
|
db,
|
|
admin.id,
|
|
admin.username,
|
|
"查看真人素材库配置",
|
|
"GET",
|
|
f"/admin/private-portrait/users/{user_id}/config",
|
|
detail=_json_detail({"target_user_id": user_id, "config": config.model_dump(mode="json")}),
|
|
)
|
|
return config
|
|
|
|
|
|
@router.put("/users/{user_id}/config", response_model=PrivatePortraitConfigOut)
|
|
async def admin_update_private_portrait_config(
|
|
user_id: str,
|
|
payload: PrivatePortraitAdminConfigUpdate,
|
|
admin: User = Depends(get_admin_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
before = await get_user_private_portrait_config(db, user_id=user_id)
|
|
await set_user_private_portrait_limit(db, user_id=user_id, limit=payload.private_portrait_image_limit)
|
|
after = await get_user_private_portrait_config(db, user_id=user_id)
|
|
await log_operation(
|
|
db,
|
|
admin.id,
|
|
admin.username,
|
|
f"设置真人素材库数量限制:{before.image_limit} -> {after.image_limit}",
|
|
"PUT",
|
|
f"/admin/private-portrait/users/{user_id}/config",
|
|
detail=_json_detail(
|
|
{
|
|
"target_user_id": user_id,
|
|
"before": before.model_dump(mode="json"),
|
|
"after": after.model_dump(mode="json"),
|
|
}
|
|
),
|
|
)
|
|
return after
|
|
|
|
|
|
@router.get("/projects", response_model=PrivatePortraitProjectListOut)
|
|
async def admin_list_private_portrait_projects(
|
|
page: int = Query(1, ge=1),
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
user_id: str | None = Query(None),
|
|
keyword: str | None = Query(None),
|
|
status: str | None = Query(None),
|
|
admin: User = Depends(get_admin_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
items, total = await list_projects(db, user_id=user_id, page=page, page_size=page_size, keyword=keyword, status=status)
|
|
await log_operation(
|
|
db,
|
|
admin.id,
|
|
admin.username,
|
|
"查看真人素材项目列表",
|
|
"GET",
|
|
"/admin/private-portrait/projects",
|
|
detail=_json_detail(
|
|
{
|
|
"filters": {"user_id": user_id, "keyword": keyword, "status": status, "page": page, "page_size": page_size},
|
|
"total": total,
|
|
"returned_count": len(items),
|
|
}
|
|
),
|
|
)
|
|
return PrivatePortraitProjectListOut(items=[project_to_out(item, include_user=True) for item in items], total=total, page=page, page_size=page_size)
|
|
|
|
|
|
@router.get("/assets", response_model=PrivatePortraitAssetListOut)
|
|
async def admin_list_private_portrait_assets(
|
|
page: int = Query(1, ge=1),
|
|
page_size: int = Query(20, ge=1, le=100),
|
|
user_id: str | None = Query(None),
|
|
project_id: str | None = Query(None),
|
|
keyword: str | None = Query(None),
|
|
status: str | None = Query(None),
|
|
admin: User = Depends(get_admin_user),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
assets, total, project_name_map = await list_assets(db, user_id=user_id, project_id=project_id, status=status, keyword=keyword, page=page, page_size=page_size)
|
|
await log_operation(
|
|
db,
|
|
admin.id,
|
|
admin.username,
|
|
"查看真人素材列表",
|
|
"GET",
|
|
"/admin/private-portrait/assets",
|
|
detail=_json_detail(
|
|
{
|
|
"filters": {"user_id": user_id, "project_id": project_id, "keyword": keyword, "status": status, "page": page, "page_size": page_size},
|
|
"total": total,
|
|
"returned_count": len(assets),
|
|
}
|
|
),
|
|
)
|
|
return PrivatePortraitAssetListOut(items=[asset_to_out(asset, project_name=project_name_map.get(asset.project_id), include_user=True) for asset in assets], total=total, page=page, page_size=page_size)
|