from fastapi import APIRouter, HTTPException from typing import Optional from decimal import Decimal from database import get_session from models import Vehicle, FuelRecord from schemas import ( VehicleCreate, VehicleUpdate, VehicleDelete, VehicleResponse, VehicleStats, ) router = APIRouter(prefix="/vehicles", tags=["vehicles"]) @router.get("/list", response_model=list[VehicleResponse]) def get_vehicles(): """获取所有车辆列表(排除已删除)""" with get_session() as session: vehicles = ( session.query(Vehicle) .filter(Vehicle.is_deleted == False) .order_by(Vehicle.created_at.desc()) .all() ) return vehicles @router.post("/create", response_model=VehicleResponse) def create_vehicle(vehicle: VehicleCreate): """添加新车辆""" with get_session() as session: db_vehicle = Vehicle( name=vehicle.name, purchase_date=vehicle.purchase_date, initial_mileage=vehicle.initial_mileage, ) session.add(db_vehicle) session.commit() session.refresh(db_vehicle) return db_vehicle @router.post("/update", response_model=VehicleResponse) def update_vehicle(vehicle: VehicleUpdate): """更新车辆信息""" with get_session() as session: db_vehicle = session.query(Vehicle).filter(Vehicle.id == vehicle.id).first() if not db_vehicle: raise HTTPException(status_code=404, detail="Vehicle not found") if vehicle.name is not None: db_vehicle.name = vehicle.name if vehicle.purchase_date is not None: db_vehicle.purchase_date = vehicle.purchase_date if vehicle.initial_mileage is not None: db_vehicle.initial_mileage = vehicle.initial_mileage session.commit() session.refresh(db_vehicle) return db_vehicle @router.post("/delete") def delete_vehicle(vehicle: VehicleDelete): """软删除车辆""" with get_session() as session: db_vehicle = ( session.query(Vehicle) .filter(Vehicle.id == vehicle.id, Vehicle.is_deleted == False) .first() ) if not db_vehicle: raise HTTPException(status_code=404, detail="Vehicle not found") db_vehicle.is_deleted = True session.commit() return {"message": "Vehicle deleted successfully"} @router.get("/stats", response_model=VehicleStats) def get_vehicle_stats(vehicle_id: int): """获取车辆统计信息""" with get_session() as session: vehicle = ( session.query(Vehicle) .filter(Vehicle.id == vehicle_id, Vehicle.is_deleted == False) .first() ) if not vehicle: raise HTTPException(status_code=404, detail="Vehicle not found") # 获取所有未删除的加油记录 fuel_records = ( session.query(FuelRecord) .filter(FuelRecord.vehicle_id == vehicle_id, FuelRecord.is_deleted == False) .order_by(FuelRecord.date.asc()) .all() ) # 计算总里程 if fuel_records: latest_mileage = max(r.mileage for r in fuel_records) total_mileage = latest_mileage - vehicle.initial_mileage else: total_mileage = 0 # 计算总油费和总加油量(只算加满的记录) total_fuel_cost = sum(float(r.total_cost) for r in fuel_records) total_fuel_amount = sum( float(r.fuel_amount) for r in fuel_records if r.is_full_tank ) # 计算平均油耗 avg_fuel_consumption = None if total_mileage > 0 and total_fuel_amount > 0: avg_fuel_consumption = round((total_fuel_amount / total_mileage) * 100, 2) return VehicleStats( total_mileage=total_mileage, total_fuel_cost=round(total_fuel_cost, 2), total_fuel_amount=round(total_fuel_amount, 2), avg_fuel_consumption=avg_fuel_consumption, )