from fastapi import APIRouter, HTTPException from typing import Optional from database import get_session from models import Vehicle, FuelRecord from schemas import DashboardData, FuelRecordItem router = APIRouter(prefix="/dashboard", tags=["dashboard"]) @router.get("/data", response_model=DashboardData) def get_dashboard(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) # 获取最近5条加油记录(带油耗计算,排除已删除) recent_records = ( session.query(FuelRecord) .filter(FuelRecord.vehicle_id == vehicle_id, FuelRecord.is_deleted == False) .order_by(FuelRecord.date.desc(), FuelRecord.mileage.desc()) .limit(5) .all() ) recent_fuel_records = [] for record in recent_records: # 计算单次油耗 fuel_consumption = None if record.is_full_tank: # 先找更早日期的记录 prev_record = ( session.query(FuelRecord) .filter( FuelRecord.vehicle_id == vehicle_id, FuelRecord.date < record.date, FuelRecord.is_full_tank == True, FuelRecord.is_deleted == False, ) .order_by(FuelRecord.date.desc(), FuelRecord.mileage.desc()) .first() ) # 如果没找到,找同一天更早的记录 if not prev_record: prev_record = ( session.query(FuelRecord) .filter( FuelRecord.vehicle_id == vehicle_id, FuelRecord.date == record.date, FuelRecord.mileage < record.mileage, FuelRecord.is_full_tank == True, FuelRecord.is_deleted == False, ) .order_by(FuelRecord.mileage.desc()) .first() ) if prev_record: mileage_diff = record.mileage - prev_record.mileage if mileage_diff > 0: fuel_consumption = round( (float(record.fuel_amount) / mileage_diff) * 100, 2 ) recent_fuel_records.append( FuelRecordItem( id=record.id, date=record.date, mileage=record.mileage, fuel_amount=float(record.fuel_amount), total_cost=float(record.total_cost), fuel_consumption=fuel_consumption, ) ) # 计算日均行程 avg_daily_km = None if total_mileage > 0 and fuel_records: first_date = fuel_records[0].date # 第一次加油日期(已按日期升序排序) last_date = fuel_records[-1].date # 最后一次加油日期 days = (last_date - first_date).days if days > 0: avg_daily_km = round(total_mileage / days, 1) return DashboardData( vehicle_id=vehicle_id, vehicle_name=vehicle.name, purchase_date=vehicle.purchase_date, total_mileage=total_mileage, total_fuel_cost=round(total_fuel_cost, 2), avg_fuel_consumption=avg_fuel_consumption, avg_daily_km=avg_daily_km, recent_fuel_records=recent_fuel_records, )