129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
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,
|
||
)
|