"""Admin 管理后台路由 — 租户 CRUD + 用户管理 + 审计日志。""" from fastapi import APIRouter, Depends, Query, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.dependencies import get_current_user, require_role from app.models.audit import AuditLog from app.models.tenant import Tenant from app.models.user import User from app.schemas.common import ApiResponse, success router = APIRouter(prefix="/admin", tags=["admin"]) @router.get("/overview", response_model=ApiResponse[dict]) async def admin_overview( db: AsyncSession = Depends(get_db), user: User = Depends(require_role("admin")), ): """系统概览。""" tenants_result = await db.execute(select(Tenant)) tenants = tenants_result.scalars().all() users_result = await db.execute(select(User)) users = users_result.scalars().all() return success(data={ "tenant_count": len(tenants), "user_count": len(users), "tenants": [{"id": str(t.id), "name": t.name} for t in tenants], }) @router.get("/tenants", response_model=ApiResponse[list]) async def list_tenants( db: AsyncSession = Depends(get_db), user: User = Depends(require_role("admin")), ): """租户管理列表。""" result = await db.execute(select(Tenant)) items = result.scalars().all() return success(data=[ {"id": str(i.id), "name": i.name, "created_at": i.created_at.isoformat() if i.created_at else None} for i in items ]) @router.get("/users", response_model=ApiResponse[list]) async def list_users( db: AsyncSession = Depends(get_db), user: User = Depends(require_role("admin")), ): """用户管理列表。""" result = await db.execute(select(User)) items = result.scalars().all() return success(data=[ {"id": str(i.id), "email": i.email, "name": i.name, "role": i.role, "tenant_id": str(i.tenant_id), "is_active": i.is_active} for i in items ]) @router.get("/audit-logs", response_model=ApiResponse[list]) async def list_audit_logs( page: int = Query(default=1, ge=1), page_size: int = Query(default=20, ge=1, le=100), db: AsyncSession = Depends(get_db), user: User = Depends(require_role("admin")), ): """审计日志查看。""" offset = (page - 1) * page_size result = await db.execute( select(AuditLog).order_by(AuditLog.created_at.desc()).offset(offset).limit(page_size) ) items = result.scalars().all() return success(data=[ { "id": str(i.id), "user_id": str(i.user_id) if i.user_id else None, "action": i.action, "target_type": i.resource_type, "target_id": i.resource_id, "detail": i.detail_json, "created_at": i.created_at.isoformat() if i.created_at else None, } for i in items ])