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

182 lines
8.2 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 datetime import datetime
from app.database import get_db
from app.models.quality import QcTask, QcTaskItem, QcDefect
from app.schemas.quality import (
QcTaskCreate, QcTaskUpdate, QcTaskOut,
QcTaskItemCreate, QcTaskItemUpdate, QcTaskItemOut,
QcDefectCreate, QcDefectUpdate, QcDefectOut,
)
from app.schemas.common import Response, PageResponse
from app.services.auth_service import get_current_user
router = APIRouter()
# ─── 检验任务 ───────────────────────────────────────────────────────────────
@router.get("/tasks", response_model=Response[PageResponse[QcTaskOut]])
async def list_tasks(
page: int = 1,
page_size: int = 20,
task_code: Optional[str] = None,
coil_no: Optional[str] = None,
status: Optional[int] = None,
result: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
db: AsyncSession = Depends(get_db),
_=Depends(get_current_user),
):
query = select(QcTask).where(QcTask.del_flag == 0).order_by(desc(QcTask.created_at))
if task_code:
query = query.where(QcTask.task_code.ilike(f"%{task_code}%"))
if coil_no:
query = query.where(QcTask.coil_no.ilike(f"%{coil_no}%"))
if status is not None:
query = query.where(QcTask.status == status)
if result:
query = query.where(QcTask.result == result)
if start_date:
query = query.where(QcTask.created_at >= datetime.fromisoformat(start_date))
if end_date:
query = query.where(QcTask.created_at <= datetime.fromisoformat(end_date + "T23:59:59"))
total = (await db.execute(select(func.count()).select_from(query.subquery()))).scalar()
result_rows = await db.execute(query.offset((page - 1) * page_size).limit(page_size))
items = [QcTaskOut.model_validate(r) for r in result_rows.scalars()]
return Response.ok(PageResponse(total=total, page=page, page_size=page_size, items=items))
@router.post("/tasks", response_model=Response[QcTaskOut])
async def create_task(body: QcTaskCreate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
task = QcTask(**body.model_dump())
db.add(task)
await db.flush()
return Response.ok(QcTaskOut.model_validate(task))
@router.get("/tasks/{task_id}", response_model=Response[QcTaskOut])
async def get_task(task_id: int, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
r = await db.execute(select(QcTask).where(QcTask.id == task_id, QcTask.del_flag == 0))
task = r.scalar_one_or_none()
if not task:
raise HTTPException(status_code=404, detail="任务不存在")
return Response.ok(QcTaskOut.model_validate(task))
@router.put("/tasks/{task_id}", response_model=Response[QcTaskOut])
async def update_task(task_id: int, body: QcTaskUpdate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
r = await db.execute(select(QcTask).where(QcTask.id == task_id, QcTask.del_flag == 0))
task = r.scalar_one_or_none()
if not task:
raise HTTPException(status_code=404, detail="任务不存在")
for k, v in body.model_dump(exclude_none=True).items():
setattr(task, k, v)
await db.flush()
return Response.ok(QcTaskOut.model_validate(task))
@router.delete("/tasks/{task_id}", response_model=Response[dict])
async def delete_task(task_id: int, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
r = await db.execute(select(QcTask).where(QcTask.id == task_id))
task = r.scalar_one_or_none()
if not task:
raise HTTPException(status_code=404, detail="任务不存在")
task.del_flag = 1
await db.flush()
return Response.ok({})
# ─── 检验项目 ────────────────────────────────────────────────────────────────
@router.get("/tasks/{task_id}/items", response_model=Response[list[QcTaskItemOut]])
async def list_task_items(task_id: int, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
r = await db.execute(select(QcTaskItem).where(QcTaskItem.task_id == task_id).order_by(QcTaskItem.id))
return Response.ok([QcTaskItemOut.model_validate(i) for i in r.scalars()])
@router.post("/task-items", response_model=Response[QcTaskItemOut])
async def create_task_item(body: QcTaskItemCreate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
item = QcTaskItem(**body.model_dump())
db.add(item)
await db.flush()
return Response.ok(QcTaskItemOut.model_validate(item))
@router.put("/task-items/{item_id}", response_model=Response[QcTaskItemOut])
async def update_task_item(item_id: int, body: QcTaskItemUpdate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
r = await db.execute(select(QcTaskItem).where(QcTaskItem.id == item_id))
item = r.scalar_one_or_none()
if not item:
raise HTTPException(status_code=404, detail="检验项不存在")
for k, v in body.model_dump(exclude_none=True).items():
setattr(item, k, v)
await db.flush()
return Response.ok(QcTaskItemOut.model_validate(item))
# ─── 缺陷记录 ────────────────────────────────────────────────────────────────
@router.get("/defects", response_model=Response[PageResponse[QcDefectOut]])
async def list_defects(
page: int = 1,
page_size: int = 20,
coil_no: Optional[str] = None,
defect_type: Optional[str] = None,
degree: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
db: AsyncSession = Depends(get_db),
_=Depends(get_current_user),
):
query = select(QcDefect).where(QcDefect.del_flag == 0).order_by(desc(QcDefect.created_at))
if coil_no:
query = query.where(QcDefect.coil_no.ilike(f"%{coil_no}%"))
if defect_type:
query = query.where(QcDefect.defect_type.ilike(f"%{defect_type}%"))
if degree:
query = query.where(QcDefect.degree == degree)
if start_date:
query = query.where(QcDefect.created_at >= datetime.fromisoformat(start_date))
if end_date:
query = query.where(QcDefect.created_at <= datetime.fromisoformat(end_date + "T23:59:59"))
total = (await db.execute(select(func.count()).select_from(query.subquery()))).scalar()
rows = await db.execute(query.offset((page - 1) * page_size).limit(page_size))
items = [QcDefectOut.model_validate(r) for r in rows.scalars()]
return Response.ok(PageResponse(total=total, page=page, page_size=page_size, items=items))
@router.post("/defects", response_model=Response[QcDefectOut])
async def create_defect(body: QcDefectCreate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
defect = QcDefect(**body.model_dump())
db.add(defect)
await db.flush()
return Response.ok(QcDefectOut.model_validate(defect))
@router.put("/defects/{defect_id}", response_model=Response[QcDefectOut])
async def update_defect(defect_id: int, body: QcDefectUpdate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
r = await db.execute(select(QcDefect).where(QcDefect.id == defect_id, QcDefect.del_flag == 0))
defect = r.scalar_one_or_none()
if not defect:
raise HTTPException(status_code=404, detail="缺陷记录不存在")
for k, v in body.model_dump(exclude_none=True).items():
setattr(defect, k, v)
await db.flush()
return Response.ok(QcDefectOut.model_validate(defect))
@router.delete("/defects/{defect_id}", response_model=Response[dict])
async def delete_defect(defect_id: int, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)):
r = await db.execute(select(QcDefect).where(QcDefect.id == defect_id))
defect = r.scalar_one_or_none()
if not defect:
raise HTTPException(status_code=404, detail="缺陷记录不存在")
defect.del_flag = 1
await db.flush()
return Response.ok({})