Files
AIPortPilot/backend/app/routers/admin.py
T
selfrelease fad458b2a7 docs(uiux): UIUX 设计方案大改 + 5 份作业指导书对齐 + 开发任务文档
- UIUX 文档:填充 19 个缺口(多主体画像/健康度/AI+看板/增长域/洞察域/创始人端/OODA/助推/商密)
- UIUX 文档:插入 6 个新章节(十四~十九),旧章节重编号为二十~三十一,更新目录和交叉引用
- 作业指导书 x5:导航改为 6 域分组,新增 Context Bar/工作模式/Insight Rail/决策线程/多工作区等 UI 概念
- 新建 docs/2-task-uiux.md:50 个代码落地开发任务,按 P0-P6 分优先级 + 8 Sprint 规划
- 后端/前端:大量新增模型、路由、组件(来自之前 Phase 开发)
2026-07-19 11:53:38 +08:00

89 lines
2.9 KiB
Python

"""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
])