JhHardwareWRS_BackPoint/app/routers/equipment.py
2026-06-24 15:19:14 +08:00

109 lines
4.6 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import or_, select
from sqlalchemy.orm import Session
from app.database import get_db
from app.deps import require_roles
from app.models import Equipment, Personnel, Role
from app.schemas import EquipmentCreate, EquipmentOut, PageResponse
from app.services.attendance_points import accessible_point_names, require_attendance_point_access
from app.services.common import normalize_device_no, paginate
from app.services.serializers import equipment_out
router = APIRouter(prefix="/api/equipment", tags=["equipment"])
EQUIPMENT_TYPES = {"冲压设备", "清洗设备"}
@router.get("", response_model=PageResponse)
def list_equipment(
attendance_point_name: str = "",
keyword: str = "",
device_type: str = "",
page: int = Query(1, ge=1),
page_size: int = Query(10, ge=1, le=100),
user: Personnel = Depends(require_roles(Role.worker, Role.admin, Role.manager)),
db: Session = Depends(get_db),
) -> PageResponse:
point_names = accessible_point_names(db, user)
query = select(Equipment).where(Equipment.attendance_point_name.in_(point_names)).order_by(Equipment.updated_at.desc(), Equipment.device_no.asc())
if attendance_point_name:
try:
point_name = require_attendance_point_access(db, user, attendance_point_name)
except (ValueError, PermissionError) as exc:
raise HTTPException(status_code=403, detail=str(exc)) from exc
query = query.where(Equipment.attendance_point_name == point_name)
if device_type:
query = query.where(Equipment.device_type == device_type)
if keyword:
like = f"%{keyword}%"
query = query.where(
or_(
Equipment.attendance_point_name.like(like),
Equipment.device_no.like(like),
Equipment.device_type.like(like),
Equipment.remark.like(like),
)
)
result = paginate(db, query, page, page_size)
return PageResponse(**{**result, "rows": [equipment_out(row) for row in result["rows"]]})
@router.post("", response_model=EquipmentOut)
def save_equipment(
payload: EquipmentCreate,
user: Personnel = Depends(require_roles(Role.admin)),
db: Session = Depends(get_db),
) -> EquipmentOut:
try:
point_name = require_attendance_point_access(db, user, payload.attendance_point_name)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
except PermissionError as exc:
raise HTTPException(status_code=403, detail=str(exc)) from exc
device_no = normalize_device_no(payload.device_no)
if not device_no:
raise HTTPException(status_code=400, detail="请输入设备号")
if payload.device_type not in EQUIPMENT_TYPES:
raise HTTPException(status_code=400, detail="设备类型只能是冲压设备或清洗设备")
original_point_name = payload.original_attendance_point_name or point_name
original_device_no = normalize_device_no(payload.original_device_no) or device_no
original_key = {"attendance_point_name": original_point_name, "device_no": original_device_no}
next_key = {"attendance_point_name": point_name, "device_no": device_no}
equipment = db.get(Equipment, original_key)
if equipment is not None and original_key != next_key:
existed = db.get(Equipment, next_key)
if existed is not None:
raise HTTPException(status_code=409, detail="该设备号已存在,不能重复保存")
equipment.attendance_point_name = point_name
equipment.device_no = device_no
elif equipment is None:
equipment = db.get(Equipment, next_key)
if equipment is None:
equipment = Equipment(attendance_point_name=point_name, device_no=device_no)
db.add(equipment)
equipment.device_type = payload.device_type
equipment.remark = payload.remark
db.commit()
db.refresh(equipment)
return equipment_out(equipment)
@router.delete("/{device_no}", status_code=204)
def delete_equipment(
device_no: str,
attendance_point_name: str,
user: Personnel = Depends(require_roles(Role.admin)),
db: Session = Depends(get_db),
) -> None:
try:
point_name = require_attendance_point_access(db, user, attendance_point_name)
except (ValueError, PermissionError) as exc:
raise HTTPException(status_code=403, detail=str(exc)) from exc
equipment = db.get(Equipment, {"attendance_point_name": point_name, "device_no": normalize_device_no(device_no)})
if equipment is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="设备不存在")
db.delete(equipment)
db.commit()