"""标签打印 API — 预览 / 执行 / 打印机配置""" from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, Field from app.services.label_service import generate_preview_image, send_to_printer from app.services.print_config import PrintConfigManager from app.services.auth_service import get_current_user router = APIRouter(prefix="/print", tags=["标签打印"]) # ============================================================ # 请求体 # ============================================================ class LabelPreviewRequest(BaseModel): serial_number: str = Field(..., min_length=1, description="16位HEX系统ID(二维码内容)") material_name: str = Field("", description="物料名称") spec_model: str = Field("", description="规格型号") order_no: str = Field("", description="订单号(条件渲染)") class PrintExecuteRequest(LabelPreviewRequest): copies: int = Field(1, ge=1, le=100, description="打印份数") printer_ip: str | None = Field(None, description="覆盖配置的打印机 IP") printer_port: int | None = Field(None, description="覆盖配置的打印机端口") class PrinterConfigUpdate(BaseModel): ip: str = Field(..., description="打印机 IP 地址") port: int = Field(9100, ge=1, le=65535, description="打印机端口") enabled: bool = Field(True, description="是否启用") # ============================================================ # 端点 # ============================================================ @router.post("/preview") def print_preview(data: LabelPreviewRequest) -> dict: """生成标签预览图(Base64 JPEG)""" try: data_url = generate_preview_image(**data.model_dump()) return {"data_url": data_url} except Exception as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"生成预览失败: {str(e)}", ) @router.post("/execute") def print_execute( data: PrintExecuteRequest, current_user: dict = Depends(get_current_user), ) -> dict: """发送打印指令到物理打标机""" payload = data.model_dump() copies = payload.pop("copies", 1) printer_ip = payload.pop("printer_ip", None) printer_port = payload.pop("printer_port", None) result = send_to_printer( copies=copies, printer_ip=printer_ip, printer_port=printer_port, **payload, ) if not result["success"]: raise HTTPException( status_code=status.HTTP_502_BAD_GATEWAY, detail=result["message"], ) return result @router.get("/config") def get_printer_config() -> dict: """获取打印机当前配置""" return PrintConfigManager.get_config() @router.post("/config") def update_printer_config( data: PrinterConfigUpdate, current_user: dict = Depends(get_current_user), ) -> dict: """更新打印机配置(IP/端口)""" current = PrintConfigManager.get_config() current["label_printer"] = { "ip": data.ip, "port": data.port, "enabled": data.enabled, } PrintConfigManager.save_config(current) return { "message": "打印机配置已更新", "config": current["label_printer"], }