Files
pickling-mes/backend/app/api/material.py

103 lines
3.8 KiB
Python
Raw Normal View History

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, desc
from typing import Optional
from app.database import get_db
from app.models.material import Coil, MaterialTracking, CoilStatus
from app.schemas.material import CoilCreate, CoilUpdate, CoilOut, TrackingCreate, TrackingOut
from app.schemas.common import Response, PageResponse
from app.services.auth_service import get_current_user
router = APIRouter()
@router.get("/coils", response_model=Response[PageResponse[CoilOut]])
async def list_coils(
page: int = 1,
page_size: int = 20,
coil_no: Optional[str] = None,
status: Optional[str] = None,
steel_grade: Optional[str] = None,
db: AsyncSession = Depends(get_db),
_ = Depends(get_current_user),
):
query = select(Coil).order_by(desc(Coil.created_at))
if coil_no:
query = query.where(Coil.coil_no.ilike(f"%{coil_no}%"))
if status:
try:
query = query.where(Coil.status == CoilStatus(status))
except ValueError:
pass
if steel_grade:
query = query.where(Coil.steel_grade == steel_grade)
total_result = await db.execute(select(func.count()).select_from(query.subquery()))
total = total_result.scalar()
result = await db.execute(query.offset((page - 1) * page_size).limit(page_size))
items = [CoilOut.model_validate(c) for c in result.scalars()]
return Response.ok(PageResponse(total=total, page=page, page_size=page_size, items=items))
@router.post("/coils", response_model=Response[CoilOut])
async def create_coil(
body: CoilCreate,
db: AsyncSession = Depends(get_db),
_ = Depends(get_current_user),
):
existing = await db.execute(select(Coil).where(Coil.coil_no == body.coil_no))
if existing.scalar_one_or_none():
raise HTTPException(status_code=400, detail="卷号已存在")
coil = Coil(**body.model_dump())
db.add(coil)
await db.flush()
return Response.ok(CoilOut.model_validate(coil))
@router.get("/coils/{coil_no}", response_model=Response[CoilOut])
async def get_coil(coil_no: str, db: AsyncSession = Depends(get_db), _ = Depends(get_current_user)):
result = await db.execute(select(Coil).where(Coil.coil_no == coil_no))
coil = result.scalar_one_or_none()
if not coil:
raise HTTPException(status_code=404, detail="钢卷不存在")
return Response.ok(CoilOut.model_validate(coil))
@router.put("/coils/{coil_no}", response_model=Response[CoilOut])
async def update_coil(
coil_no: str,
body: CoilUpdate,
db: AsyncSession = Depends(get_db),
_ = Depends(get_current_user),
):
result = await db.execute(select(Coil).where(Coil.coil_no == coil_no))
coil = result.scalar_one_or_none()
if not coil:
raise HTTPException(status_code=404, detail="钢卷不存在")
for k, v in body.model_dump(exclude_none=True).items():
setattr(coil, k, v)
await db.flush()
return Response.ok(CoilOut.model_validate(coil))
@router.get("/tracking", response_model=Response[PageResponse[TrackingOut]])
async def list_tracking(
coil_no: Optional[str] = None,
page: int = 1,
page_size: int = 50,
db: AsyncSession = Depends(get_db),
_ = Depends(get_current_user),
):
query = select(MaterialTracking).order_by(desc(MaterialTracking.event_time))
if coil_no:
query = query.where(MaterialTracking.coil_no == coil_no)
total_result = await db.execute(select(func.count()).select_from(query.subquery()))
total = total_result.scalar()
result = await db.execute(query.offset((page - 1) * page_size).limit(page_size))
items = [TrackingOut.model_validate(t) for t in result.scalars()]
return Response.ok(PageResponse(total=total, page=page, page_size=page_size, items=items))