package com.dpkj.modules.autoReplyPrint.controller; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.dpkj.common.config.PrinterConfig; import com.dpkj.common.exception.RRException; import com.dpkj.common.vo.Result; import com.dpkj.modules.autoReplyPrint.enums.ReceiptTemplateEnum; import com.dpkj.modules.autoReplyPrint.request.ReceiptPrintRequest; import com.dpkj.modules.autoReplyPrint.service.ImagePrintService; import com.dpkj.modules.autoReplyPrint.service.impl.TemplateService; import com.dpkj.modules.autoReplyPrint.utils.FolderUtils; import com.dpkj.modules.autoReplyPrint.vo.PrinterStatus; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.thymeleaf.util.StringUtils; import javax.annotation.Resource; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.text.SimpleDateFormat; import java.util.Date; /** * 小票打印机控制层 * * @author 石头人 * @version 1.0 * @since 2025-03-10 9:29:22 */ @Slf4j @RestController @RequestMapping("/receipt") public class ReceiptPrintController { @Resource private PrinterConfig printerConfig; private static final int MAX_HEIGHT = 1000; private static final int FIXED_WIDTH = 730; @Resource(name = "USBImagePrint") private ImagePrintService usbImagePrintService; @Resource private TemplateService templateService; @PostMapping("/print") private Result print(@Validated @RequestBody ReceiptPrintRequest request) throws UnsupportedEncodingException { FolderUtils.checkFolderAndCreate(request.getFileDir()); String devName = "VID:0x0FE6,PID:0x811E"; // 采用默认的devName,不进行入参传值了 String templateName = ReceiptTemplateEnum.getTemplateName(request.getTemplateName()); // 宽度固定 request.setWidth(request.getWidth() > 610 ? 600 : request.getWidth()); JSONObject data = JSONObject.parseObject(URLDecoder.decode(request.getTemplateFillData(), "UTF-8")); // 强行设置终端号 不需要固定,前端自己穿 // data.put("terminalNumber", printerConfig.getTerminalNumber()); // 强行设置打印时间 SimpleDateFormat sdf = new SimpleDateFormat(printerConfig.getTimeType()); String formattedDate = sdf.format(new Date()); data.put("printTime", formattedDate); Integer height = request.getHeight(); int dinyHeight = 0; if (templateName.equals("department")) { // 由于是使用的门诊小票-T2,那么默认的高度为1100,强行设置,通过动态修改渲染的图片的高度 height = 800;//根据实际情况800较为合适 // 单行最大长度为10 int singleLineMaxLength = 10; // 这里的长度取自于department.html模板中的项目单个tr高度,并且略高于该高度 int singleLineHeight = 30; // 动态计算长度 JSONArray items = data.getJSONArray("items"); for (Object item : items) { JSONObject itemEntity = (JSONObject) item; String projectName = String.valueOf(itemEntity.get("name")); int length = projectName.length(); int count = (int) Math.ceil((double) length / singleLineMaxLength); dinyHeight += count * singleLineHeight; } // 计算是否有门诊号 String outpatientNumber = data.getString("outpatientNumber"); if (!StringUtils.isEmpty(outpatientNumber)) { dinyHeight += 28; } // 计算是否有就诊医生 String doctor = data.getString("doctor"); if (!StringUtils.isEmpty(doctor)) { dinyHeight += 28; } // 计算是否有就诊科室 String department = data.getString("department"); if (!StringUtils.isEmpty(department)) { dinyHeight += 28; } } height += dinyHeight; // 进行模板填充 // String testData = "{\"hospitalName\":\"澜沧县中医医院\",\"registeTerminalName\":\"中国农业银行自助终端\",\"registeType\":\"自助挂号\",\"name\":\"刘博雅\",\"gender\":\"男\",\"age\":28,\"birthDate\":\"1996-06-31\",\"cardNumber\":\"6221**********0731\",\"outpatientNumber\":\"2501150038\",\"department\":\"普外科门诊\",\"visitLevel\":\"普通号\",\"doctor\":\"普通门诊\",\"sequence\":\"1\",\"registerDate\":\"2025-01-15\",\"totalFee\":4.00,\"paymentMethod\":\"微信扫码支付\",\"orderNumber\":\"\",\"transactionNumber\":\"2025011513090412092794szztzzj\",\"qrCodeBase64_2base64Type_1_250_250\":\"maby this is a Base64 code data if has\",\"terminalNumber\":\"12092794\",\"printTime\":\"2025-01-15 13:10:08\"}"; StringBuilder filePath = new StringBuilder(request.getFileDir()); // 校验是否选中了模板,如果没选中模板的话则不需要另外生成了 if (!StringUtils.isEmpty(request.getTemplateName()) && !StringUtils.isEmpty(request.getFileDir())) { byte[] image = templateService.generateReceiptImage( data, templateName, request.getWidth(), height, filePath); } else { throw new RRException("模板渲染错误"); } usbImagePrintService.imagePrintFromPath(devName, request.getWidth(), height, filePath.toString(), 1, 0); // 删除图片 File file = new File(filePath.toString()); // 检查文件是否存在 if (file.exists()) { // 尝试删除文件 if (file.delete()) { log.info("文件删除成功: " + filePath); } else { log.info("文件删除失败: " + filePath); } } else { log.info("文件不存在: " + filePath); } return Result.ok(); } @PostMapping("/getStatus") public Result print() { String devName = "VID:0x0FE6,PID:0x811E"; // 采用默认的devName,不进行入参传值了 return Result.ok(this.usbImagePrintService.getStatus(devName)); } }