"""小程序/门户登录态 · 司机运输计划单""" from __future__ import annotations from typing import Optional from fastapi import APIRouter, Depends, File, Form, HTTPException, Query, UploadFile from sqlalchemy.orm import Session from app.core.database import get_db from app.core.db_auth import DbUserContext, get_db_current_user from app.core.response import error_response, success_response from app.core.tenant_context import get_tenant_no from app.schemas.pl.transport import ( PublicTransportDriverStopFeedback, PublicTransportFeedback, ) from app.services import pl_driver_plan_service as drv_svc router = APIRouter(prefix="/driver-plan", tags=["运输计划-司机计划单"]) def _resolve_personnel_or_empty(db: Session, user: DbUserContext, tenant_no: str): return drv_svc.resolve_personnel_for_user( db, tenant_no=tenant_no, user_id=user.id ) @router.get("/history") def get_driver_plan_history( date: str = Query(..., description="筛选日 YYYY-MM-DD"), db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user), ): tenant_no = get_tenant_no(db, user.to_tenant_user_dict()) page, err = drv_svc.build_driver_history_page( db, tenant_no=tenant_no, user_id=user.id, date_str=date, ) if err: return error_response(400, err) return success_response(page.model_dump(by_alias=True)) @router.get("/calendar-counts") def get_driver_plan_calendar_counts( month: str = Query(..., description="月份 YYYY-MM"), db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user), ): tenant_no = get_tenant_no(db, user.to_tenant_user_dict()) counts, err = drv_svc.build_driver_calendar_counts( db, tenant_no=tenant_no, user_id=user.id, month_str=month, ) if err: return error_response(400, err) return success_response({"month": month, "counts": counts or {}}) @router.get("/{plan_id}") def get_driver_plan_detail( plan_id: str, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user), ): tenant_no = get_tenant_no(db, user.to_tenant_user_dict()) personnel = _resolve_personnel_or_empty(db, user, tenant_no) if not personnel: raise HTTPException(status_code=404, detail="未关联驾押人员,无法查看") page, err = drv_svc.build_driver_page_for_plan( db, tenant_no=tenant_no, plan_id=plan_id, personnel_id=personnel.id, ) if err or page is None: raise HTTPException(status_code=404, detail=err or "计划不存在") return success_response(page.model_dump(by_alias=True)) @router.post("/{plan_id}/ensure-copy-seq") def ensure_driver_plan_copy_seq( plan_id: str, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user), ): tenant_no = get_tenant_no(db, user.to_tenant_user_dict()) personnel = _resolve_personnel_or_empty(db, user, tenant_no) if not personnel: raise HTTPException(status_code=404, detail="未关联驾押人员,无法查看") seq, err = drv_svc.ensure_copy_seq_for_driver( db, tenant_no=tenant_no, plan_id=plan_id, personnel_id=personnel.id, ) if err or seq is None: raise HTTPException(status_code=404, detail=err or "计划不存在") db.commit() return success_response({"copySeqNo": seq}) @router.post("/{plan_id}/feedback") def save_driver_plan_feedback( plan_id: str, payload: PublicTransportFeedback, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user), ): tenant_no = get_tenant_no(db, user.to_tenant_user_dict()) personnel = _resolve_personnel_or_empty(db, user, tenant_no) if not personnel: return error_response(400, "未关联驾押人员,无法提交回执") ok, msg = drv_svc.save_driver_feedback_for_plan( db, tenant_no=tenant_no, plan_id=plan_id, personnel_id=personnel.id, payload=payload, ) if not ok: return error_response(400, msg or "保存失败") db.commit() return success_response({"success": True, "message": "保存成功"}) @router.post("/{plan_id}/driver-feedback") def save_driver_plan_stop_feedback( plan_id: str, payload: PublicTransportDriverStopFeedback, db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user), ): tenant_no = get_tenant_no(db, user.to_tenant_user_dict()) personnel = _resolve_personnel_or_empty(db, user, tenant_no) if not personnel: return error_response(400, "未关联驾押人员,无法提交回执") ok, msg = drv_svc.save_driver_stop_feedback_for_plan( db, tenant_no=tenant_no, plan_id=plan_id, personnel_id=personnel.id, payload=payload, ) if not ok: return error_response(400, msg or "保存失败") db.commit() return success_response({"success": True, "message": "保存成功"}) @router.post("/{plan_id}/attachments") def upload_driver_plan_attachment( plan_id: str, file: UploadFile = File(...), folder: Optional[str] = Form(""), db: Session = Depends(get_db), user: DbUserContext = Depends(get_db_current_user), ): tenant_no = get_tenant_no(db, user.to_tenant_user_dict()) personnel = _resolve_personnel_or_empty(db, user, tenant_no) if not personnel: return error_response(400, "未关联驾押人员,无法上传附件") data, err = drv_svc.upload_driver_attachment_for_plan( db, tenant_no=tenant_no, plan_id=plan_id, personnel_id=personnel.id, file=file, folder=folder or "", ) if err: code, msg = err return error_response(code, msg) return success_response(data)