from fastapi import APIRouter, HTTPException from typing import Optional from decimal import Decimal from database import get_session from models import Cost, Vehicle from schemas import ( CostCreate, CostUpdate, CostDelete, CostResponse, ) router = APIRouter(prefix="/costs", tags=["costs"]) def _to_cost_response(cost: Cost) -> CostResponse: """将 Cost 模型转换为 CostResponse""" return CostResponse( id=cost.id, vehicle_id=cost.vehicle_id, date=cost.date, type=cost.type, amount=float(cost.amount), mileage=cost.mileage, notes=cost.notes, is_installment=cost.is_installment, installment_months=cost.installment_months, is_deleted=cost.is_deleted, created_at=cost.created_at, updated_at=cost.updated_at, ) @router.get("/list", response_model=list[CostResponse]) def get_costs( vehicle_id: Optional[int] = None, cost_type: Optional[str] = None, ): """获取费用记录列表(排除已删除),返回全部数据""" session = get_session() try: query = session.query(Cost).filter(Cost.is_deleted == False) if vehicle_id: query = query.filter(Cost.vehicle_id == vehicle_id) if cost_type: query = query.filter(Cost.type == cost_type) costs = query.order_by(Cost.date.desc()).all() return [_to_cost_response(c) for c in costs] finally: session.close() @router.post("/create", response_model=CostResponse) def create_cost(cost: CostCreate): """添加费用记录""" session = get_session() try: # 验证车辆存在 vehicle = session.query(Vehicle).filter(Vehicle.id == cost.vehicle_id).first() if not vehicle: raise HTTPException(status_code=404, detail="Vehicle not found") db_cost = Cost( vehicle_id=cost.vehicle_id, date=cost.date, type=cost.type, amount=Decimal(str(cost.amount)), mileage=cost.mileage, notes=cost.notes or "", is_installment=cost.is_installment or False, installment_months=cost.installment_months or 12, ) session.add(db_cost) session.commit() session.refresh(db_cost) return _to_cost_response(db_cost) finally: session.close() @router.post("/update", response_model=CostResponse) def update_cost(cost_update: CostUpdate): """更新费用记录""" session = get_session() try: cost = session.query(Cost).filter(Cost.id == cost_update.id).first() if not cost: raise HTTPException(status_code=404, detail="Cost record not found") if cost_update.date is not None: cost.date = cost_update.date if cost_update.type is not None: cost.type = cost_update.type if cost_update.amount is not None: cost.amount = Decimal(str(cost_update.amount)) if cost_update.mileage is not None: cost.mileage = cost_update.mileage if cost_update.notes is not None: cost.notes = cost_update.notes or "" if cost_update.is_installment is not None: cost.is_installment = cost_update.is_installment if cost_update.installment_months is not None: cost.installment_months = cost_update.installment_months session.commit() session.refresh(cost) return _to_cost_response(cost) finally: session.close() @router.post("/delete") def delete_cost(cost: CostDelete): """软删除费用记录""" session = get_session() try: db_cost = ( session.query(Cost) .filter(Cost.id == cost.id, Cost.is_deleted == False) .first() ) if not db_cost: raise HTTPException(status_code=404, detail="Cost record not found") db_cost.is_deleted = True session.commit() return {"message": "Cost record deleted successfully"} finally: session.close()