"""双端手工派车日历 API;读取与维护权限分离。""" from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from app.core import menu_guard from app.core.database import get_db from app.core.db_auth import DbUserContext, get_db_current_user from app.core.tenant_context import get_tenant_no from app.schemas.pl.dispatch_calendar import CreateBody, UpdateBody from app.services import pl_dispatch_calendar_service as svc from app.services.web_auth_roles import iter_user_menu_perm_codes def _require_calendar_permission(action: str): """menu_guard 仅支持单码,这里沿用其角色守卫和多角色权限并集。""" def dependency(current_user: dict = Depends(menu_guard.require_admin_or_super_admin), db: Session = Depends(get_db)): if current_user.get("role") != menu_guard.SUPER_ADMIN_ROLE: tenant = get_tenant_no(db, current_user) codes = iter_user_menu_perm_codes(db, current_user.get("user_id"), tenant) allowed = {f"pl:dispatch-calendar:{action}", f"mini:pl:dispatch-calendar:{action}"} if not codes.intersection(allowed): raise HTTPException(status_code=403, detail="无派车日历访问权限" if action == "list" else "无派车日历维护权限") return current_user return dependency require_manage = _require_calendar_permission("manage") router = APIRouter( prefix="/transport/dispatch-calendar", tags=["手工派车日历"], dependencies=[Depends(_require_calendar_permission("list"))], ) @router.get("") def list_records(month: str = Query(...), vehicle_id: Optional[str] = Query(None, alias="vehicleId"), calendar_kind: Optional[str] = Query("acid", alias="calendarKind"), page: int = Query(1, ge=1), page_size: int = Query(500, alias="pageSize", ge=1, le=500), db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user)): tenant = get_tenant_no(db, user.to_tenant_user_dict()) return svc.list_records(db, tenant, user, month=month, vehicle_id=vehicle_id, calendar_kind=calendar_kind, page=page, page_size=page_size) @router.get("/vehicles") def vehicle_options(q: Optional[str] = None, page: int = Query(1, ge=1), page_size: int = Query(500, alias="pageSize", ge=1, le=500), db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user)): tenant = get_tenant_no(db, user.to_tenant_user_dict()) return svc.list_vehicles(db, tenant, user, q=q, page=page, page_size=page_size) @router.get("/products") def product_options(q: Optional[str] = None, page: int = Query(1, ge=1), page_size: int = Query(500, alias="pageSize", ge=1, le=500), db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user)): tenant = get_tenant_no(db, user.to_tenant_user_dict()) return svc.list_products(db, tenant, user, q=q, page=page, page_size=page_size) @router.post("", dependencies=[Depends(require_manage)]) def create_record(body: CreateBody, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user)): tenant = get_tenant_no(db, user.to_tenant_user_dict()) row = svc.create_record(db, tenant, user, body) return svc._row_to_dict(row) @router.get("/{record_id}") def get_record(record_id: str, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user)): tenant = get_tenant_no(db, user.to_tenant_user_dict()) row = svc.get_record(db, tenant, user, record_id) return svc.serialize_records(db, tenant, user, [row])[0] @router.put("/{record_id}", dependencies=[Depends(require_manage)]) def update_record(record_id: str, body: UpdateBody, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user)): tenant = get_tenant_no(db, user.to_tenant_user_dict()) row = svc.update_record(db, tenant, user, record_id, body) return svc._row_to_dict(row) @router.delete("/{record_id}", dependencies=[Depends(require_manage)]) def delete_record(record_id: str, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user)): tenant = get_tenant_no(db, user.to_tenant_user_dict()) return {"deleted": svc.delete_record(db, tenant, user, record_id)}