from fastapi import APIRouter, Depends, HTTPException 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.inspection import EqpChecklist, EqpChecklistItem, EqpInspectionRecord, EqpInspectionDetail from app.schemas.inspection import ( EqpChecklistCreate, EqpChecklistUpdate, EqpChecklistOut, EqpChecklistItemCreate, EqpChecklistItemOut, EqpInspectionRecordCreate, EqpInspectionRecordOut, EqpInspectionDetailOut, ) from app.schemas.common import Response, PageResponse from app.services.auth_service import get_current_user router = APIRouter() # ─── 巡检模板 ──────────────────────────────────────────────────────────────── @router.get("/checklists", response_model=Response[list[EqpChecklistOut]]) async def list_checklists( equipment_code: Optional[str] = None, db: AsyncSession = Depends(get_db), _=Depends(get_current_user), ): query = select(EqpChecklist).order_by(EqpChecklist.id) if equipment_code: query = query.where(EqpChecklist.equipment_code == equipment_code) r = await db.execute(query) return Response.ok([EqpChecklistOut.model_validate(c) for c in r.scalars()]) @router.post("/checklists", response_model=Response[EqpChecklistOut]) async def create_checklist(body: EqpChecklistCreate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)): items_data = body.items or [] data = body.model_dump(exclude={"items"}) checklist = EqpChecklist(**data) db.add(checklist) await db.flush() for item in items_data: ci = EqpChecklistItem(checklist_id=checklist.id, **item.model_dump()) db.add(ci) await db.flush() return Response.ok(EqpChecklistOut.model_validate(checklist)) @router.put("/checklists/{checklist_id}", response_model=Response[EqpChecklistOut]) async def update_checklist(checklist_id: int, body: EqpChecklistUpdate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)): r = await db.execute(select(EqpChecklist).where(EqpChecklist.id == checklist_id)) checklist = r.scalar_one_or_none() if not checklist: raise HTTPException(status_code=404, detail="模板不存在") for k, v in body.model_dump(exclude_none=True).items(): setattr(checklist, k, v) await db.flush() return Response.ok(EqpChecklistOut.model_validate(checklist)) @router.get("/checklists/{checklist_id}/items", response_model=Response[list[EqpChecklistItemOut]]) async def list_checklist_items(checklist_id: int, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)): r = await db.execute( select(EqpChecklistItem).where(EqpChecklistItem.checklist_id == checklist_id) .order_by(EqpChecklistItem.sort_order, EqpChecklistItem.id) ) return Response.ok([EqpChecklistItemOut.model_validate(i) for i in r.scalars()]) @router.post("/checklist-items", response_model=Response[EqpChecklistItemOut]) async def create_checklist_item( body: EqpChecklistItemCreate, checklist_id: int, db: AsyncSession = Depends(get_db), _=Depends(get_current_user), ): item = EqpChecklistItem(checklist_id=checklist_id, **body.model_dump()) db.add(item) await db.flush() return Response.ok(EqpChecklistItemOut.model_validate(item)) # ─── 巡检记录 ──────────────────────────────────────────────────────────────── @router.get("/records", response_model=Response[PageResponse[EqpInspectionRecordOut]]) async def list_records( page: int = 1, page_size: int = 20, checklist_id: Optional[int] = None, status: Optional[str] = None, start_date: Optional[str] = None, end_date: Optional[str] = None, db: AsyncSession = Depends(get_db), _=Depends(get_current_user), ): query = select(EqpInspectionRecord).order_by(desc(EqpInspectionRecord.created_at)) if checklist_id: query = query.where(EqpInspectionRecord.checklist_id == checklist_id) if status: query = query.where(EqpInspectionRecord.status == status) if start_date: query = query.where(EqpInspectionRecord.inspect_time >= datetime.fromisoformat(start_date)) if end_date: query = query.where(EqpInspectionRecord.inspect_time <= 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 = [EqpInspectionRecordOut.model_validate(r) for r in rows.scalars()] return Response.ok(PageResponse(total=total, page=page, page_size=page_size, items=items)) @router.post("/records", response_model=Response[EqpInspectionRecordOut]) async def create_record(body: EqpInspectionRecordCreate, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)): details_data = body.details or [] # get checklist name cl_r = await db.execute(select(EqpChecklist).where(EqpChecklist.id == body.checklist_id)) cl = cl_r.scalar_one_or_none() data = body.model_dump(exclude={"details"}) record = EqpInspectionRecord(**data, checklist_name=cl.name if cl else None) db.add(record) await db.flush() for d in details_data: detail = EqpInspectionDetail(record_id=record.id, **d.model_dump()) db.add(detail) await db.flush() return Response.ok(EqpInspectionRecordOut.model_validate(record)) @router.get("/records/{record_id}/details", response_model=Response[list[EqpInspectionDetailOut]]) async def get_record_details(record_id: int, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)): r = await db.execute( select(EqpInspectionDetail).where(EqpInspectionDetail.record_id == record_id).order_by(EqpInspectionDetail.id) ) return Response.ok([EqpInspectionDetailOut.model_validate(d) for d in r.scalars()])