Backend: - Add auth.py for JWT token verification - Update main.py to protect all routes with auth middleware - Remove dashboard router (frontend handles aggregation) - Add Docker support with Dockerfile and docker-compose.yml Frontend: - Add OIDC authentication using oidc-client-ts with PKCE flow - Create router.js with auth guards for automatic login/logout - Add api.js for unified Axios instance with auth headers - Add composables: useAuth.js, useVehicleData.js for caching - Add views/Main.vue as main application page - Simplify App.vue to router-view container - Add deploy-web.sh deployment script Documentation: - Update AGENTS.md with new architecture and auth flow
93 lines
2.5 KiB
Python
93 lines
2.5 KiB
Python
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,
|
|
)
|
|
|
|
|
|
router = APIRouter(prefix="/vehicles", tags=["vehicles"])
|
|
|
|
|
|
@router.get("/list", response_model=list[VehicleResponse])
|
|
def get_vehicles():
|
|
"""获取所有车辆列表(排除已删除)"""
|
|
session = get_session()
|
|
try:
|
|
vehicles = (
|
|
session.query(Vehicle)
|
|
.filter(Vehicle.is_deleted == False)
|
|
.order_by(Vehicle.created_at.desc())
|
|
.all()
|
|
)
|
|
return vehicles
|
|
finally:
|
|
session.close()
|
|
|
|
|
|
@router.post("/create", response_model=VehicleResponse)
|
|
def create_vehicle(vehicle: VehicleCreate):
|
|
"""添加新车辆"""
|
|
session = get_session()
|
|
try:
|
|
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
|
|
finally:
|
|
session.close()
|
|
|
|
|
|
@router.post("/update", response_model=VehicleResponse)
|
|
def update_vehicle(vehicle: VehicleUpdate):
|
|
"""更新车辆信息"""
|
|
session = get_session()
|
|
try:
|
|
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
|
|
finally:
|
|
session.close()
|
|
|
|
|
|
@router.post("/delete")
|
|
def delete_vehicle(vehicle: VehicleDelete):
|
|
"""软删除车辆"""
|
|
session = get_session()
|
|
try:
|
|
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"}
|
|
finally:
|
|
session.close()
|