| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- from __future__ import annotations
- from fastapi import APIRouter, Depends, HTTPException, Query, status
- from sqlalchemy import func
- from sqlmodel import select
- from sqlmodel.ext.asyncio.session import AsyncSession
- from app.db.session import get_async_session
- from app.models.master_data import Cargo
- from app.schemas.master_data import CargoCreate, CargoRead, CargoUpdate
- router = APIRouter(prefix="/master-data/cargos", tags=["cargos"])
- def _base_query():
- return select(Cargo).where(Cargo.is_deleted == 0)
- @router.get("/", response_model=list[CargoRead])
- async def list_cargos(
- q: str | None = Query(default=None, description="模糊搜索货物名称"),
- session: AsyncSession = Depends(get_async_session),
- ) -> list[Cargo]:
- query = _base_query().order_by(Cargo.created_at.desc())
- if q:
- query = query.where(func.lower(Cargo.name).contains(q.lower()))
- result = await session.exec(query)
- return result.all()
- @router.post("/", response_model=CargoRead, status_code=status.HTTP_201_CREATED)
- async def create_cargo(
- payload: CargoCreate,
- session: AsyncSession = Depends(get_async_session),
- ) -> Cargo:
- from datetime import datetime
- await _ensure_unique_name(payload.name, session)
- cargo = Cargo(
- name=payload.name.strip(),
- remarks=payload.remarks,
- created_at=datetime.now().isoformat()
- )
- session.add(cargo)
- await session.commit()
- await session.refresh(cargo)
- return cargo
- @router.put("/{cargo_id}", response_model=CargoRead)
- async def update_cargo(
- cargo_id: int,
- payload: CargoUpdate,
- session: AsyncSession = Depends(get_async_session),
- ) -> Cargo:
- cargo = await _get_cargo(cargo_id, session)
- if payload.name and payload.name.strip().lower() != cargo.name.lower():
- await _ensure_unique_name(payload.name, session)
- cargo.name = payload.name.strip()
- if payload.remarks is not None:
- cargo.remarks = payload.remarks
- await session.commit()
- await session.refresh(cargo)
- return cargo
- @router.patch("/{cargo_id}", response_model=CargoRead)
- async def patch_cargo(
- cargo_id: int,
- payload: CargoUpdate,
- session: AsyncSession = Depends(get_async_session),
- ) -> Cargo:
- cargo = await _get_cargo(cargo_id, session)
- if payload.name and payload.name.strip().lower() != cargo.name.lower():
- await _ensure_unique_name(payload.name, session)
- cargo.name = payload.name.strip()
- if payload.remarks is not None:
- cargo.remarks = payload.remarks
- await session.commit()
- await session.refresh(cargo)
- return cargo
- @router.delete(
- "/{cargo_id}",
- status_code=status.HTTP_204_NO_CONTENT,
- )
- async def delete_cargo(
- cargo_id: int,
- session: AsyncSession = Depends(get_async_session),
- ) -> None:
- cargo = await _get_cargo(cargo_id, session)
- cargo.is_deleted = 1
- await session.commit()
- async def _get_cargo(cargo_id: int, session: AsyncSession) -> Cargo:
- result = await session.exec(_base_query().where(Cargo.id == cargo_id))
- cargo = result.one_or_none()
- if cargo is None:
- raise HTTPException(
- status_code=status.HTTP_404_NOT_FOUND,
- detail=f"Cargo {cargo_id} not found",
- )
- return cargo
- async def _ensure_unique_name(name: str, session: AsyncSession) -> None:
- normalized = name.strip().lower()
- result = await session.exec(
- _base_query().where(func.lower(Cargo.name) == normalized),
- )
- if result.first():
- raise HTTPException(
- status_code=status.HTTP_409_CONFLICT,
- detail="Cargo name already exists",
- )
|