carcost/api/routers/vehicles.py
yuany3721 71e11eaf30 feat: Add OIDC authentication with Authentik and refactor project structure
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
2026-04-12 13:31:27 +08:00

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()