Files
zkxw/backend/app/api/cleanroom_garment.py
T
2026-06-13 19:47:22 +08:00

500 lines
18 KiB
Python

"""洁净服管理 API"""
from typing import List, Optional
from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel, ConfigDict, Field
from sqlalchemy.orm import Session
from app.core.database import get_db
from app.core.menu_guard import require_admin_or_super_admin, require_menu_code
from app.core.response import error_response, success_response
from app.crud import cleanroom_garment as garment_svc
from app.models.models import SysUser
router = APIRouter(prefix="/web/admin", tags=["洁净服管理"])
def _get_tenant_no(db: Session, user: dict) -> str:
user_id = user.get("user_id")
if not user_id:
raise PermissionError("用户身份信息缺失,无法确定租户")
sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
if not sys_user or not sys_user.tenant_no:
raise PermissionError("用户租户信息缺失")
return sys_user.tenant_no
class GarmentCreateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
garment_code: str = Field(..., alias="garmentCode")
garment_name: str = Field(..., alias="garmentName")
wash_discard_limit: int = Field(..., alias="washDiscardLimit")
sterilize_discard_limit: int = Field(..., alias="sterilizeDiscardLimit")
inbound_date: str = Field(..., alias="inboundDate")
order_num: Optional[int] = Field(None, alias="orderNum")
remark: Optional[str] = None
class GarmentUpdateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
garment_code: Optional[str] = Field(None, alias="garmentCode")
garment_name: Optional[str] = Field(None, alias="garmentName")
wash_discard_limit: Optional[int] = Field(None, alias="washDiscardLimit")
sterilize_discard_limit: Optional[int] = Field(None, alias="sterilizeDiscardLimit")
inbound_date: Optional[str] = Field(None, alias="inboundDate")
order_num: Optional[int] = Field(None, alias="orderNum")
remark: Optional[str] = None
class GarmentBatchDeleteBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
ids: List[str] = Field(..., alias="ids")
class GarmentDiscardBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
discard_date: Optional[str] = Field(None, alias="discardDate")
remark: Optional[str] = None
class GarmentBatchDiscardBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
garment_ids: List[str] = Field(..., alias="garmentIds")
discard_date: Optional[str] = Field(None, alias="discardDate")
remark: Optional[str] = None
class WashLogCreateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
garment_id: str = Field(..., alias="garmentId")
wash_time: str = Field(..., alias="washTime")
operator_user_id: Optional[str] = Field(None, alias="operatorUserId")
operator_name: Optional[str] = Field(None, alias="operatorName")
order_num: Optional[int] = Field(0, alias="orderNum")
remark: Optional[str] = None
class WashLogUpdateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
wash_time: Optional[str] = Field(None, alias="washTime")
operator_user_id: Optional[str] = Field(None, alias="operatorUserId")
operator_name: Optional[str] = Field(None, alias="operatorName")
order_num: Optional[int] = Field(None, alias="orderNum")
remark: Optional[str] = None
class WashLogBatchBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
garment_ids: List[str] = Field(..., alias="garmentIds")
wash_time: str = Field(..., alias="washTime")
operator_user_id: Optional[str] = Field(None, alias="operatorUserId")
operator_name: Optional[str] = Field(None, alias="operatorName")
remark: Optional[str] = None
class SterilizeLogCreateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
garment_id: str = Field(..., alias="garmentId")
sterilize_time: str = Field(..., alias="sterilizeTime")
operator_user_id: Optional[str] = Field(None, alias="operatorUserId")
operator_name: Optional[str] = Field(None, alias="operatorName")
order_num: Optional[int] = Field(0, alias="orderNum")
remark: Optional[str] = None
class SterilizeLogUpdateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
sterilize_time: Optional[str] = Field(None, alias="sterilizeTime")
operator_user_id: Optional[str] = Field(None, alias="operatorUserId")
operator_name: Optional[str] = Field(None, alias="operatorName")
order_num: Optional[int] = Field(None, alias="orderNum")
remark: Optional[str] = None
class SterilizeLogBatchBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
garment_ids: List[str] = Field(..., alias="garmentIds")
sterilize_time: str = Field(..., alias="sterilizeTime")
operator_user_id: Optional[str] = Field(None, alias="operatorUserId")
operator_name: Optional[str] = Field(None, alias="operatorName")
remark: Optional[str] = None
@router.get("/cleanroom-garments")
async def list_cleanroom_garments(
page: int = Query(1, ge=1),
pageSize: int = Query(10, ge=1, le=100, alias="pageSize"),
keyword: Optional[str] = None,
garmentStatus: Optional[str] = Query(None, alias="garmentStatus"),
needAttention: Optional[str] = Query(None, alias="needAttention"),
user: dict = Depends(require_menu_code("production:cleanroom-garment:list")),
db: Session = Depends(get_db),
):
tenant_no = _get_tenant_no(db, user)
items, total = garment_svc.list_garments(
db,
page=page,
page_size=pageSize,
keyword=keyword,
garment_status=garmentStatus,
need_attention=needAttention in ("1", "true", "True"),
tenant_no=tenant_no,
user_info=user,
)
tp = garment_svc.total_pages(total, pageSize)
return success_response({"list": items, "total": total, "page": page, "pageSize": pageSize, "totalPages": tp})
@router.get("/cleanroom-garments/{garment_id}")
async def get_cleanroom_garment(
garment_id: str,
user: dict = Depends(require_menu_code("production:cleanroom-garment:list")),
db: Session = Depends(get_db),
):
tenant_no = _get_tenant_no(db, user)
detail = garment_svc.get_garment_detail(db, garment_id, tenant_no=tenant_no)
if not detail:
return error_response(404, "洁净服不存在")
return success_response(detail)
@router.post("/cleanroom-garments")
async def create_cleanroom_garment(
body: GarmentCreateBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
obj = garment_svc.create_garment(
db,
garment_code=body.garment_code,
garment_name=body.garment_name,
wash_discard_limit=body.wash_discard_limit,
sterilize_discard_limit=body.sterilize_discard_limit,
inbound_date=body.inbound_date,
tenant_no=tenant_no,
order_num=body.order_num,
remark=body.remark,
user_id=user.get("user_id"),
)
return success_response(garment_svc.get_garment_detail(db, obj.id, tenant_no=tenant_no), message="创建成功")
except ValueError as e:
return error_response(400, str(e))
@router.put("/cleanroom-garments/{garment_id}")
async def update_cleanroom_garment(
garment_id: str,
body: GarmentUpdateBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
payload = body.model_dump(exclude_unset=True, by_alias=False)
obj = garment_svc.update_garment(
db,
garment_id,
garment_code=payload.get("garment_code"),
garment_name=payload.get("garment_name"),
wash_discard_limit=payload.get("wash_discard_limit"),
sterilize_discard_limit=payload.get("sterilize_discard_limit"),
inbound_date=payload.get("inbound_date"),
order_num=payload.get("order_num"),
remark=payload.get("remark"),
user_id=user.get("user_id"),
tenant_no=tenant_no,
)
return success_response(garment_svc.get_garment_detail(db, obj.id, tenant_no=tenant_no), message="更新成功")
except ValueError as e:
return error_response(400, str(e))
@router.post("/cleanroom-garments/batch-delete")
async def batch_delete_cleanroom_garments(
body: GarmentBatchDeleteBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
count = garment_svc.batch_soft_delete_garments(db, body.ids, tenant_no=tenant_no)
return success_response({"deletedCount": count}, message="删除成功")
except ValueError as e:
return error_response(400, str(e))
@router.delete("/cleanroom-garments/{garment_id}")
async def delete_cleanroom_garment(
garment_id: str,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
garment_svc.soft_delete_garment(db, garment_id, tenant_no=tenant_no)
return success_response(None, message="删除成功")
except ValueError as e:
return error_response(400, str(e))
@router.post("/cleanroom-garments/batch-discard")
async def batch_discard_cleanroom_garments(
body: GarmentBatchDiscardBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
result = garment_svc.batch_discard_garments(
db,
body.garment_ids,
discard_date=body.discard_date,
remark=body.remark,
user_id=user.get("user_id"),
tenant_no=tenant_no,
)
return success_response(result, message="废弃成功")
except ValueError as e:
return error_response(400, str(e))
@router.post("/cleanroom-garments/{garment_id}/discard")
async def discard_cleanroom_garment(
garment_id: str,
body: GarmentDiscardBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
obj = garment_svc.discard_garment(
db,
garment_id,
discard_date=body.discard_date,
remark=body.remark,
user_id=user.get("user_id"),
tenant_no=tenant_no,
)
return success_response(garment_svc.get_garment_detail(db, obj.id, tenant_no=tenant_no), message="废弃成功")
except ValueError as e:
return error_response(400, str(e))
@router.get("/cleanroom-garment-wash-logs")
async def list_wash_logs(
page: int = Query(1, ge=1),
pageSize: int = Query(10, ge=1, le=100, alias="pageSize"),
garmentId: str = Query(..., alias="garmentId"),
user: dict = Depends(require_menu_code("production:cleanroom-garment:list")),
db: Session = Depends(get_db),
):
tenant_no = _get_tenant_no(db, user)
items, total = garment_svc.list_wash_logs(
db, garment_id=garmentId, page=page, page_size=pageSize, tenant_no=tenant_no
)
tp = garment_svc.total_pages(total, pageSize)
return success_response({"list": items, "total": total, "page": page, "pageSize": pageSize, "totalPages": tp})
@router.post("/cleanroom-garment-wash-logs")
async def create_wash_log(
body: WashLogCreateBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
obj = garment_svc.create_wash_log(
db,
garment_id=body.garment_id,
wash_time=body.wash_time,
operator_user_id=body.operator_user_id,
operator_name=body.operator_name,
tenant_no=tenant_no,
order_num=body.order_num,
remark=body.remark,
user_id=user.get("user_id"),
)
return success_response(garment_svc._wash_log_to_dict(obj), message="创建成功")
except ValueError as e:
return error_response(400, str(e))
@router.post("/cleanroom-garment-wash-logs/batch")
async def batch_create_wash_logs(
body: WashLogBatchBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
result = garment_svc.batch_create_wash_logs(
db,
garment_ids=body.garment_ids,
wash_time=body.wash_time,
operator_user_id=body.operator_user_id,
operator_name=body.operator_name,
remark=body.remark,
tenant_no=tenant_no,
user_id=user.get("user_id"),
)
return success_response(result, message="批量清洗登记成功")
except ValueError as e:
return error_response(400, str(e))
@router.put("/cleanroom-garment-wash-logs/{log_id}")
async def update_wash_log(
log_id: str,
body: WashLogUpdateBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
payload = body.model_dump(exclude_unset=True, by_alias=False)
obj = garment_svc.update_wash_log(
db,
log_id,
wash_time=payload.get("wash_time"),
operator_user_id=payload.get("operator_user_id"),
operator_name=payload.get("operator_name"),
order_num=payload.get("order_num"),
remark=payload.get("remark"),
user_id=user.get("user_id"),
tenant_no=tenant_no,
)
return success_response(garment_svc._wash_log_to_dict(obj), message="更新成功")
except ValueError as e:
return error_response(400, str(e))
@router.delete("/cleanroom-garment-wash-logs/{log_id}")
async def delete_wash_log(
log_id: str,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
garment_svc.soft_delete_wash_log(db, log_id, tenant_no=tenant_no)
return success_response(None, message="删除成功")
except ValueError as e:
return error_response(400, str(e))
@router.get("/cleanroom-garment-sterilize-logs")
async def list_sterilize_logs(
page: int = Query(1, ge=1),
pageSize: int = Query(10, ge=1, le=100, alias="pageSize"),
garmentId: str = Query(..., alias="garmentId"),
user: dict = Depends(require_menu_code("production:cleanroom-garment:list")),
db: Session = Depends(get_db),
):
tenant_no = _get_tenant_no(db, user)
items, total = garment_svc.list_sterilize_logs(
db, garment_id=garmentId, page=page, page_size=pageSize, tenant_no=tenant_no
)
tp = garment_svc.total_pages(total, pageSize)
return success_response({"list": items, "total": total, "page": page, "pageSize": pageSize, "totalPages": tp})
@router.post("/cleanroom-garment-sterilize-logs")
async def create_sterilize_log(
body: SterilizeLogCreateBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
obj = garment_svc.create_sterilize_log(
db,
garment_id=body.garment_id,
sterilize_time=body.sterilize_time,
operator_user_id=body.operator_user_id,
operator_name=body.operator_name,
tenant_no=tenant_no,
order_num=body.order_num,
remark=body.remark,
user_id=user.get("user_id"),
)
return success_response(garment_svc._sterilize_log_to_dict(obj), message="创建成功")
except ValueError as e:
return error_response(400, str(e))
@router.post("/cleanroom-garment-sterilize-logs/batch")
async def batch_create_sterilize_logs(
body: SterilizeLogBatchBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
result = garment_svc.batch_create_sterilize_logs(
db,
garment_ids=body.garment_ids,
sterilize_time=body.sterilize_time,
operator_user_id=body.operator_user_id,
operator_name=body.operator_name,
remark=body.remark,
tenant_no=tenant_no,
user_id=user.get("user_id"),
)
return success_response(result, message="批量灭菌登记成功")
except ValueError as e:
return error_response(400, str(e))
@router.put("/cleanroom-garment-sterilize-logs/{log_id}")
async def update_sterilize_log(
log_id: str,
body: SterilizeLogUpdateBody,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
payload = body.model_dump(exclude_unset=True, by_alias=False)
obj = garment_svc.update_sterilize_log(
db,
log_id,
sterilize_time=payload.get("sterilize_time"),
operator_user_id=payload.get("operator_user_id"),
operator_name=payload.get("operator_name"),
order_num=payload.get("order_num"),
remark=payload.get("remark"),
user_id=user.get("user_id"),
tenant_no=tenant_no,
)
return success_response(garment_svc._sterilize_log_to_dict(obj), message="更新成功")
except ValueError as e:
return error_response(400, str(e))
@router.delete("/cleanroom-garment-sterilize-logs/{log_id}")
async def delete_sterilize_log(
log_id: str,
user: dict = Depends(require_admin_or_super_admin),
db: Session = Depends(get_db),
):
try:
tenant_no = _get_tenant_no(db, user)
garment_svc.soft_delete_sterilize_log(db, log_id, tenant_no=tenant_no)
return success_response(None, message="删除成功")
except ValueError as e:
return error_response(400, str(e))