Files
server-core/app/api/routers/rbac_portals.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

180 lines
7.0 KiB
Python

# -*- coding: utf-8 -*-
"""各业务端口工作台与子页面端点(企业/载体/服务商/政务)。
列表类页面数据全部由服务端(portal_pages 表)提供;企业发布任务写入 tasks 表。
OPC 端工作台在 ``rbac_opc.py`` 中(按用户聚合)。
"""
from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel
from ..dependencies import get_db
from ..schemas.portals import EnterpriseTaskCreate, TaskReviewRequest, ReferralCreate
from ...rbac import require_roles, write_audit
from ...infrastructure.repositories import Database
router = APIRouter(tags=["portals"])
# 端口 -> 允许的角色
_PORT_ROLE = {
"enterprise": "enterprise",
"carrier": "carrier",
"provider": "provider",
"government": "government",
}
def _dashboard(port: str):
role = _PORT_ROLE.get(port)
if role is None:
raise HTTPException(status_code=404, detail="Unknown port")
async def handler(
db: Database = Depends(get_db),
_u: dict = Depends(require_roles(role)),
):
payload = await db.portal_dashboards.get(port)
if payload is None:
raise HTTPException(status_code=404, detail="Dashboard not found")
return payload
return handler
def _page(port: str, page: str):
role = _PORT_ROLE.get(port)
if role is None:
raise HTTPException(status_code=404, detail="Unknown port")
async def handler(
db: Database = Depends(get_db),
_u: dict = Depends(require_roles(role)),
):
payload = await db.portal_pages.get(port, page)
if payload is None:
raise HTTPException(status_code=404, detail="Page data not found")
payload.setdefault("port", port)
payload.setdefault("page", page)
return payload
return handler
router.get("/enterprise/dashboard", summary="企业端工作台")(_dashboard("enterprise"))
router.get("/carrier/dashboard", summary="载体/园区端工作台")(_dashboard("carrier"))
router.get("/provider/dashboard", summary="服务商端工作台")(_dashboard("provider"))
router.get("/government/dashboard", summary="政务端工作台")(_dashboard("government"))
# ── 子页面(列表/数据均由服务端提供)──────────────────────────────────────
router.get("/enterprise/talents", summary="企业·人才搜索")(_page("enterprise", "talents"))
router.get("/carrier/opc", summary="载体·OPC 管理")(_page("carrier", "opc"))
router.get("/carrier/services", summary="载体·服务管理")(_page("carrier", "services"))
router.get("/provider/orders", summary="服务商·订单管理")(_page("provider", "orders"))
router.get("/provider/services", summary="服务商·服务管理")(_page("provider", "services"))
router.get("/government/policies", summary="政务·政策管理")(_page("government", "policies"))
# ── 企业·任务(发布任务/我的任务)─────────────────────────────────────────
@router.get("/enterprise/tasks", summary="企业·我的任务列表")
async def enterprise_tasks(
db: Database = Depends(get_db),
_u: dict = Depends(require_roles("enterprise")),
):
return {"items": await db.tasks.list(status="published")}
@router.post("/enterprise/tasks", summary="企业·发布任务")
async def enterprise_create_task(
req: EnterpriseTaskCreate,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_roles("enterprise")),
):
task = await db.tasks.create({**req.model_dump(exclude_none=True), "status": "pending"})
await write_audit(db, action="task.publish", resource="task", resource_id=task["id"],
detail=task["title"], user=actor, request=request)
return task
@router.post("/enterprise/tasks/{task_id}/submit", summary="企业·提交审核并发布")
async def enterprise_submit_task(
task_id: str,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_roles("enterprise")),
):
task = await db.tasks.set_status(task_id, "published")
if task is None:
raise HTTPException(status_code=404, detail="Task not found")
await write_audit(db, action="task.submit", resource="task", resource_id=task_id,
user=actor, request=request)
return task
@router.get("/enterprise/tasks/{task_id}/bids", summary="企业·查看竞标")
async def enterprise_list_bids(
task_id: str,
db: Database = Depends(get_db),
_u: dict = Depends(require_roles("enterprise")),
):
return {"items": await db.bids.list_for_task(task_id)}
@router.post("/enterprise/tasks/{task_id}/bids/{bid_id}/win", summary="企业·评标中标")
async def enterprise_win_bid(
task_id: str, bid_id: str,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_roles("enterprise")),
):
bid = await db.bids.set_status(bid_id, "win")
if bid is None:
raise HTTPException(status_code=404, detail="Bid not found")
await db.tasks.set_status(task_id, "in_progress")
await write_audit(db, action="bid.win", resource="bid", resource_id=bid_id,
detail=f"task={task_id} winner={bid['opc_name']}", user=actor, request=request)
return bid
@router.post("/enterprise/tasks/{task_id}/review", summary="企业·验收任务")
async def enterprise_review_task(
task_id: str,
req: TaskReviewRequest,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_roles("enterprise")),
):
task = await db.tasks.get(task_id)
if task is None:
raise HTTPException(status_code=404, detail="Task not found")
new_status = "completed" if req.action == "accept" else "in_progress"
updated = await db.tasks.set_status(task_id, new_status)
await write_audit(db, action="task.review", resource="task", resource_id=task_id,
detail=req.action, user=actor, request=request)
return updated
# ── 载体·服务商引荐(三方绑定:载体引荐服务商→服务园区内 OPC)─────────────
@router.get("/carrier/referrals", summary="载体·引荐记录")
async def carrier_referrals(
db: Database = Depends(get_db),
user: dict = Depends(require_roles("carrier")),
):
return {"items": await db.referrals.list_for(user.get("org_id"))}
@router.post("/carrier/referrals", summary="载体·引荐服务商给园区内 OPC")
async def carrier_create_referral(
req: ReferralCreate,
request: Request,
db: Database = Depends(get_db),
actor: dict = Depends(require_roles("carrier")),
):
referral = await db.referrals.create({
**req.model_dump(exclude_none=True), "carrier_id": actor.get("org_id") or actor["id"],
})
await write_audit(db, action="referral.create", resource="referral", resource_id=referral["id"],
detail=f"{referral['provider_name']}->{referral['opc_name']}", user=actor, request=request)
return referral