109 lines
4.6 KiB
Python
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()
|