Files
server-core/app/api/routers/rbac_operator.py
T
Pine 01ef3c9637 refactor: schemas 抽取(DTO 从 models.py 与路由内联迁至 api/schemas/)
- 新建 api/schemas/:auth/agents/admin/ecosystem/investor/opc/operator/org/portals
- models.py 移除 15 个 Pydantic DTO(保留 ORM 数据模型层)
- 13 个路由内联 DTO 全部迁出,路由瘦身仅剩处理逻辑
- 全量 66 测试通过
2026-08-24 09:51:52 +08:00

166 lines
6.5 KiB
Python

# -*- coding: utf-8 -*-
"""运营端业务管理端点:任务 / 服务商 / 内容 / 系统配置 / 数据统计。
全部要求 operator 角色(内部子角色再按权限细分),并写审计日志。
"""
from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel
from ..dependencies import get_db
from ..schemas.operator import TaskCreateRequest, TaskStatusRequest, ProviderCreateRequest, ProviderUpdateRequest, ContentCreateRequest, ContentStatusRequest, ConfigUpdateRequest
from ...rbac import require_permission, require_roles, write_audit
from ...infrastructure.repositories import Database
router = APIRouter(prefix="/admin", tags=["admin-op"])
@router.get("/tasks", summary="任务列表")
async def list_tasks(
status: str | None = None,
db: Database = Depends(get_db),
_u: dict = Depends(require_roles("operator")),
):
return await db.tasks.list(status=status)
@router.post("/tasks", summary="创建任务")
async def create_task(
req: TaskCreateRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_permission("action:task.manage")),
):
task = await db.tasks.create(req.model_dump(exclude_none=True))
await write_audit(db, action="task.create", resource="task", resource_id=task["id"],
detail=task["title"], user=actor, request=request)
return task
@router.post("/tasks/{task_id}/status", summary="更新任务状态")
async def set_task_status(
task_id: str,
req: TaskStatusRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_permission("action:task.manage")),
):
if await db.tasks.get(task_id) is None:
raise HTTPException(status_code=404, detail="Task not found")
task = await db.tasks.set_status(task_id, req.status)
await write_audit(db, action="task.status", resource="task", resource_id=task_id,
detail=req.status, user=actor, request=request)
return task
# ── 服务商管理 ────────────────────────────────────────────────────────────
@router.get("/providers", summary="服务商列表")
async def list_providers(
status: str | None = None,
db: Database = Depends(get_db),
_u: dict = Depends(require_roles("operator")),
):
return await db.providers.list(status=status)
@router.post("/providers", summary="创建服务商")
async def create_provider(
req: ProviderCreateRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_permission("action:provider.manage")),
):
prov = await db.providers.create(req.model_dump(exclude_none=True))
await write_audit(db, action="provider.create", resource="provider", resource_id=prov["id"],
detail=prov["name"], user=actor, request=request)
return prov
@router.post("/providers/{provider_id}/update", summary="更新服务商(评级/状态)")
async def update_provider(
provider_id: str,
req: ProviderUpdateRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_permission("action:provider.manage")),
):
updated = await db.providers.update(provider_id, req.model_dump(exclude_none=True))
if updated is None:
raise HTTPException(status_code=404, detail="Provider not found")
await write_audit(db, action="provider.update", resource="provider", resource_id=provider_id,
detail=str(req.model_dump(exclude_none=True)), user=actor, request=request)
return updated
# ── 内容管理 ──────────────────────────────────────────────────────────────
@router.get("/content", summary="内容列表")
async def list_content(
ctype: str | None = None,
status: str | None = None,
db: Database = Depends(get_db),
_u: dict = Depends(require_roles("operator")),
):
return await db.content.list(ctype=ctype, status=status)
@router.post("/content", summary="创建内容")
async def create_content(
req: ContentCreateRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_permission("action:content.manage")),
):
item = await db.content.create(req.model_dump(exclude_none=True))
await write_audit(db, action="content.create", resource="content", resource_id=item["id"],
detail=item["title"], user=actor, request=request)
return item
@router.post("/content/{content_id}/status", summary="发布/下架内容")
async def set_content_status(
content_id: str,
req: ContentStatusRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_permission("action:content.manage")),
):
item = await db.content.set_status(content_id, req.status)
if item is None:
raise HTTPException(status_code=404, detail="Content not found")
await write_audit(db, action="content.status", resource="content", resource_id=content_id,
detail=req.status, user=actor, request=request)
return item
# ── 系统配置 ──────────────────────────────────────────────────────────────
@router.get("/config", summary="系统配置列表")
async def list_config(
db: Database = Depends(get_db),
_u: dict = Depends(require_roles("operator")),
):
return await db.config.all()
@router.put("/config/{key}", summary="更新系统配置")
async def set_config(
key: str,
req: ConfigUpdateRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_permission("action:config.manage")),
):
cfg = await db.config.set(key, req.value, req.description)
await write_audit(db, action="config.update", resource="config", resource_id=key,
detail=req.value, user=actor, request=request)
return cfg
# ── 数据统计 ──────────────────────────────────────────────────────────────
@router.get("/stats/overview", summary="运营数据总览")
async def stats_overview(
db: Database = Depends(get_db),
_u: dict = Depends(require_roles("operator")),
):
return await db.stats.overview()