01ef3c9637
- 新建 api/schemas/:auth/agents/admin/ecosystem/investor/opc/operator/org/portals - models.py 移除 15 个 Pydantic DTO(保留 ORM 数据模型层) - 13 个路由内联 DTO 全部迁出,路由瘦身仅剩处理逻辑 - 全量 66 测试通过
180 lines
7.0 KiB
Python
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
|