# -*- coding: utf-8 -*- """政务端端点(证明数据范围层级:上级可看下级,下级不可看上级)。""" from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, Request from ..dependencies import get_db from ...rbac import require_permission, require_scope, write_audit from ...infrastructure.repositories import Database router = APIRouter(prefix="/government", tags=["government"]) @router.get("/regions", summary="可见区域(按数据范围)") async def list_regions( db: Database = Depends(get_db), user: dict = Depends(require_scope()), ): """返回当前政务账号数据范围内的区域(省级=全部,区县=仅本区县)。""" all_regions = await db.regions.all() visible = {rid for rid in user.get("scope_region_ids", [])} return [r for r in all_regions if r["id"] in visible] @router.get("/enterprises", summary="区域内企业列表") async def list_enterprises( request: Request, db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): """返回数据范围内的甲方企业;每次访问写一条 data.view 审计。""" orgs = await db.orgs.list_by_region(user.get("scope_region_ids", [])) enterprises = [o for o in orgs if o["type"] == "enterprise"] await write_audit( db, action="data.view", resource="enterprise", detail=f"scope={user.get('scope_region_ids', [])}", user=user, request=request, ) return enterprises @router.get("/enterprises/{org_id}", summary="企业详情(范围校验)") async def get_enterprise( org_id: str, request: Request, db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): org = await db.orgs.get(org_id) if org is None or org["type"] != "enterprise": raise HTTPException(status_code=404, detail="Enterprise not found") if org["region_id"] not in user.get("scope_region_ids", []): raise HTTPException(status_code=403, detail="Forbidden: out of data scope") return org # ── 三级数据范围:范围内 OPC / 载体 / 数据看板 ──────────────────────────── def _in_scope(region_id, user) -> bool: return region_id in user.get("scope_region_ids", []) @router.get("/opc", summary="范围内 OPC 列表") async def gov_opc( db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): opcs = [u for u in await db.users.list() if u.get("role") == "opc_member"] opcs = [u for u in opcs if _in_scope(u.get("region_id"), user)] return {"items": [ {"title": u.get("nickname") or u.get("username"), "meta": f"信用 {u.get('region_id', '')} · OPC", "tag": "OPC"} for u in opcs ]} @router.get("/carriers", summary="范围内载体列表") async def gov_carriers( db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): carriers = [o for o in await db.orgs.all() if o["type"] == "carrier"] carriers = [o for o in carriers if _in_scope(o.get("region_id"), user)] return {"items": [ {"title": o["name"], "meta": f"{o.get('region_id', '')} · 载体", "tag": "载体"} for o in carriers ]} @router.get("/data", summary="范围内数据看板") async def gov_data( db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): scope = user.get("scope_region_ids", []) stats = await db.stats.overview(region_ids=scope) return { "stats": [ {"key": "totalOPC", "value": stats["user_count"]}, {"key": "taskTotal", "value": stats["task_count"]}, {"key": "carrierTotal", "value": stats["provider_count"]}, {"key": "policyTotal", "value": stats["content_count"]}, ], "chart": [ {"label": "6月", "value": 3200}, {"label": "7月", "value": 3600}, {"label": "8月", "value": 4100}, ], "scope": scope, } # ── 补贴三级审批(区县→市→省→发放)───────────────────────────────────────── @router.get("/subsidies", summary="范围内补贴申报列表") async def gov_subsidies( db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): return {"items": await db.subsidies.list(user.get("scope_region_ids", []))} @router.post("/subsidies/{aid}/approve", summary="补贴审批(按级别推进)") async def gov_approve_subsidy( aid: str, request: Request, db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): from ...services.subsidy_service import SubsidyService updated = await SubsidyService(db).approve(aid, user) await write_audit(db, action="subsidy.approve", resource="subsidy", resource_id=aid, detail=updated.get("status"), user=user, request=request) return updated @router.post("/subsidies/{aid}/pay", summary="补贴发放") async def gov_pay_subsidy( aid: str, request: Request, db: Database = Depends(get_db), user: dict = Depends(require_permission("menu:gov_data")), ): from ...services.subsidy_service import SubsidyService updated = await SubsidyService(db).pay(aid) await write_audit(db, action="subsidy.pay", resource="subsidy", resource_id=aid, user=user, request=request) return updated