500 lines
18 KiB
Python
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))
|