Files
server-core/app/services/subsidy_service.py
T

43 lines
1.8 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""业务层 · 补贴服务(政务三级审批状态机)。"""
from __future__ import annotations
from fastapi import HTTPException
from ..infrastructure.repositories import Database
# 各政务级别可推进的状态映射(领域规则)
SUBSIDY_NEXT: dict[str, dict[str, str]] = {
"gov_district": {"applying": "district_review"},
"gov_city": {"district_review": "city_review"},
"gov_province": {"city_review": "province_review", "province_review": "approved"},
}
class SubsidyService:
"""补贴申报审批(区县→市→省→发放)。"""
def __init__(self, db: Database):
self.db = db
async def approve(self, aid: str, user: dict) -> dict:
"""按级别推进补贴审批;越级/越权 403/400。"""
sub = await self.db.subsidies.get(aid)
if sub is None:
raise HTTPException(status_code=404, detail="Subsidy not found")
if sub.get("region_id") and sub["region_id"] not in user.get("scope_region_ids", []):
raise HTTPException(status_code=403, detail="Forbidden: out of data scope")
nxt = (SUBSIDY_NEXT.get(user.get("sub_role") or "") or {}).get(sub["status"])
if not nxt:
raise HTTPException(status_code=400, detail="当前级别不能审批该状态")
return await self.db.subsidies.set_status(aid, nxt)
async def pay(self, aid: str) -> dict:
"""发放补贴:仅已终审(approved)可发放。"""
sub = await self.db.subsidies.get(aid)
if sub is None:
raise HTTPException(status_code=404, detail="Subsidy not found")
if sub["status"] != "approved":
raise HTTPException(status_code=400, detail="仅已终审的补贴可发放")
return await self.db.subsidies.set_status(aid, "paid")