From c1ff2084f691a7755d86ebd4cff2fd798cd87b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=9D=BE?= <8605635+zhang3064194730@user.noreply.gitee.com> Date: Tue, 25 Feb 2025 16:54:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=9C=BA=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/czg/mq/PrintMqListener.java | 2 +- .../czg/account/dto/print/PrinterEditDTO.java | 3 + .../czg/service/account/print/FeiPrinter.java | 227 +++++++++--------- .../service/account/print/PrinterImpl.java | 111 ++++++--- .../czg/service/account/print/YxyPrinter.java | 215 ++--------------- .../service/impl/PrintMachineServiceImpl.java | 2 +- 6 files changed, 217 insertions(+), 343 deletions(-) diff --git a/cash-api/account-server/src/main/java/com/czg/mq/PrintMqListener.java b/cash-api/account-server/src/main/java/com/czg/mq/PrintMqListener.java index 02e70826..d8e1b4b1 100644 --- a/cash-api/account-server/src/main/java/com/czg/mq/PrintMqListener.java +++ b/cash-api/account-server/src/main/java/com/czg/mq/PrintMqListener.java @@ -52,7 +52,7 @@ public class PrintMqListener { throw new RuntimeException("订单信息不存在"); } - getPrintMachine(orderInfo.getShopId(), "cash", "normal", "order").forEach(machine -> { + getPrintMachine(orderInfo.getShopId(), "cash", "one", "order").forEach(machine -> { printerHandler.handleRequest(machine, orderInfo); // printPlaceTicket(isReturn, machine, orderInfo, shopInfo); }); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/print/PrinterEditDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/print/PrinterEditDTO.java index ae7510ba..33914e70 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/print/PrinterEditDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/print/PrinterEditDTO.java @@ -1,5 +1,6 @@ package com.czg.account.dto.print; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -23,6 +24,7 @@ public class PrinterEditDTO { /** * ip地址 */ + @NotBlank(message = "地址不为空") private String address; /** @@ -39,6 +41,7 @@ public class PrinterEditDTO { /** * 打印机品牌 */ + @NotBlank(message = "打印机品牌不为空") private String contentType; diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/print/FeiPrinter.java b/cash-service/account-service/src/main/java/com/czg/service/account/print/FeiPrinter.java index 8564c31b..4f743c32 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/print/FeiPrinter.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/print/FeiPrinter.java @@ -66,12 +66,27 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl{ super("fePrinter"); } + private final PrintSignLabel printSignLabel = new PrintSignLabel() + .setBr("
") + .setCut("") + .setF(new String[]{"", ""}) + .setL(new String[]{"", ""}) + .setS(new String[]{"", ""}) + .setF(new String[]{"", ""}) + .setQr(new String[]{"", ""}) + .setCenter(new String[]{"", ""}) + .setBold(new String[]{"", ""}); + @Override + public PrintSignLabel getSignLabelInfo() { + return printSignLabel; + } + @Override protected void normalDishesPrint(OrderInfo orderInfo, OrderDetail orderDetail, PrintMachine machine) { String remark = orderDetail.getRemark(); - String content = buildDishPrintData(getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), - orderDetail.getProductName(), orderDetail.getNum(), remark, orderDetail.getProGroupInfo()); - sendPrintRequest(machine.getAddress(), content, "1"); + String content = buildDishPrintData(false, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), + orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getNum(), remark, orderDetail.getProGroupInfo()); + sendPrintRequest(machine.getAddress(), content, null,"1"); // shopPrintLogService.save(machine, "新订单", resp[0], resp[1]); // 可以解开注释用于日志存储 } @@ -100,7 +115,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl{ .setOutNumber(orderInfo.getTakeCode()).setPrintTitle("结算单") .setRemark(orderInfo.getRemark()).setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString()); String string = buildOrderPrintData(printInfoDTO, detailList); - sendPrintRequest(machine.getAddress(), string, printerNum); + sendPrintRequest(machine.getAddress(), string, null, printerNum); // shopPrintLogService.save(machine, "结算单", resp[0], resp[1]); } @@ -116,128 +131,102 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl{ return DigestUtils.sha1Hex(FeiPrinter.USER + FeiPrinter.UKEY + timeStamp); } - - @Override - public String getStartSplitSign() { - return ""; - } - - @Override - public String getEndSplitSign() { - return ""; - } - - private PrintSignLabel printSignLabel = new PrintSignLabel() - .setBr("
") - .setCut("PCUT") - .setF(new String[]{"", ""}) - .setL(new String[]{"", ""}) - .setS(new String[]{"", ""}) - .setF(new String[]{"", ""}) - .setQr(new String[]{"", ""}) - .setCenter(new String[]{"", ""}) - .setBold(new String[]{"", ""}); - @Override - public PrintSignLabel getSignLabelInfo() { - return printSignLabel; - } - - @Override - public String buildOrderPrintData(PrintInfoDTO printInfoDTO, List detailList) { - StringBuilder data = new StringBuilder(); - data.append(StrUtil.format("{}
", printInfoDTO.getShopName())); - data.append("
"); - data.append(StrUtil.format("{}【{}】
", printInfoDTO.getPrintTitle(), printInfoDTO.getPickupNum())); - data.append("
"); - data.append(StrUtil.format("订单号:{}
", printInfoDTO.getOrderNo())); - data.append(StrUtil.format("交易时间:{}
", printInfoDTO.getTradeDate())); - data.append(StrUtil.format("收银员:{}
", printInfoDTO.getOperator())); - data.append("
"); - data.append("品名 数量 小计
"); - data.append("--------------------------------
"); - for (OrderDetail detail : detailList) { - String productName = detail.getProductName(); - String number = detail.getNum().stripTrailingZeros().toPlainString(); - String amount = toPlainStr(detail.getPayAmount().toPlainString()); - //58mm的机器,一行打印16个汉字,32个字母; 80mm的机器,一行打印24个汉字,48个字母 - //展示4列 b1代表名称列占用(14个字节) b2单价列(6个字节) b3数量列(3个字节) b4金额列(6个字节)-->这里的字节数可按自己需求自由改写,14+6+3+6再加上代码写的3个空格就是32了,58mm打印机一行总占32字节 - //String row = FeieYunUtil.getRow(productName, "",number, amount, 14, 6,3, 6) - //展示3列 b1代表名称列占用(20个字节) b2单价列(0个字节) b3数量列(3个字节) b4金额列(6个字节)-->这里的字节数可按自己需求自由改写,20+0+3+6再加上代码写的3个空格就是32了,58mm打印机一行总占32字节 - String row = getRow(productName, "", number, amount, 20, 0, 3, 6); - data.append(row); - if (StrUtil.isNotBlank(detail.getSkuName())) { - data.append("规格:").append(detail.getSkuName()).append("
"); - } - String proGroupInfo = detail.getProGroupInfo(); - if (StrUtil.isBlank(proGroupInfo)) { - continue; - } - if (!JSONUtil.isTypeJSONArray(proGroupInfo)) { - continue; - } - JSONArray subItems = JSONUtil.parseArray(proGroupInfo); - for (int i = 0; i < subItems.size(); i++) { - String proName = subItems.getJSONObject(i).getStr("proName"); - int qty = subItems.getJSONObject(i).getInt("number"); - String subRow = getRow(" - %s".formatted(proName), "", "%d.00".formatted(qty), "0.00", 20, 0, 3, 6); - data.append(subRow); - } - } - if (ObjectUtil.isNotNull(printInfoDTO.getDiscountAmount())) { - data.append("--------------------------------
"); - data.append(StrUtil.format("原价:{}
", toPlainStr(printInfoDTO.getOriginalAmount()))); - data.append(StrUtil.format("折扣:-{}
", toPlainStr(printInfoDTO.getDiscountAmount()))); - } - data.append("--------------------------------
"); - String t = "¥" + printInfoDTO.getPayAmount(); - if (printInfoDTO.isReturn()) { - data.append(StrUtil.format("应退:{}
", t)); - } else { - data.append(StrUtil.format("应收:{}
", t)); - } - data.append("--------------------------------
"); - if (ObjectUtil.isNotEmpty(printInfoDTO.getPayType()) && ObjectUtil.isNotNull(printInfoDTO.getPayType()) && printInfoDTO.getPayType().equals("deposit")) { - data.append(StrUtil.format("储值:{}
", toPlainStr(printInfoDTO.getOriginalAmount()))); - data.append(StrUtil.format("积分:{}
", printInfoDTO.getIntegral())); - } - data.append(StrUtil.format("余额:{}
", toPlainStr(printInfoDTO.getBalance()))); - data.append("--------------------------------
"); - if (StrUtil.isNotBlank(printInfoDTO.getRemark())) { - data.append(StrUtil.format("备注:{}
", printInfoDTO.getRemark())); - } - data.append("打印时间:").append(DateUtil.date().toDateStr()).append("
"); - data.append(""); - return data.toString(); - } +// @Override +// public String buildOrderPrintData(PrintInfoDTO printInfoDTO, List detailList) { +// StringBuilder data = new StringBuilder(); +// data.append(StrUtil.format("{}
", printInfoDTO.getShopName())); +// data.append("
"); +// data.append(StrUtil.format("{}【{}】
", printInfoDTO.getPrintTitle(), printInfoDTO.getPickupNum())); +// data.append("
"); +// data.append(StrUtil.format("订单号:{}
", printInfoDTO.getOrderNo())); +// data.append(StrUtil.format("交易时间:{}
", printInfoDTO.getTradeDate())); +// data.append(StrUtil.format("收银员:{}
", printInfoDTO.getOperator())); +// data.append("
"); +// data.append("品名 数量 小计
"); +// data.append("--------------------------------
"); +// for (OrderDetail detail : detailList) { +// String productName = detail.getProductName(); +// String number = detail.getNum().stripTrailingZeros().toPlainString(); +// String amount = toPlainStr(detail.getPayAmount().toPlainString()); +// //58mm的机器,一行打印16个汉字,32个字母; 80mm的机器,一行打印24个汉字,48个字母 +// //展示4列 b1代表名称列占用(14个字节) b2单价列(6个字节) b3数量列(3个字节) b4金额列(6个字节)-->这里的字节数可按自己需求自由改写,14+6+3+6再加上代码写的3个空格就是32了,58mm打印机一行总占32字节 +// //String row = FeieYunUtil.getRow(productName, "",number, amount, 14, 6,3, 6) +// //展示3列 b1代表名称列占用(20个字节) b2单价列(0个字节) b3数量列(3个字节) b4金额列(6个字节)-->这里的字节数可按自己需求自由改写,20+0+3+6再加上代码写的3个空格就是32了,58mm打印机一行总占32字节 +// String row = getRow(productName, "", number, amount, 20, 0, 3, 6); +// data.append(row); +// if (StrUtil.isNotBlank(detail.getSkuName())) { +// data.append("规格:").append(detail.getSkuName()).append("
"); +// } +// String proGroupInfo = detail.getProGroupInfo(); +// if (StrUtil.isBlank(proGroupInfo)) { +// continue; +// } +// if (!JSONUtil.isTypeJSONArray(proGroupInfo)) { +// continue; +// } +// JSONArray subItems = JSONUtil.parseArray(proGroupInfo); +// for (int i = 0; i < subItems.size(); i++) { +// String proName = subItems.getJSONObject(i).getStr("proName"); +// int qty = subItems.getJSONObject(i).getInt("number"); +// String subRow = getRow(" - %s".formatted(proName), "", "%d.00".formatted(qty), "0.00", 20, 0, 3, 6); +// data.append(subRow); +// } +// } +// if (ObjectUtil.isNotNull(printInfoDTO.getDiscountAmount())) { +// data.append("--------------------------------
"); +// data.append(StrUtil.format("原价:{}
", toPlainStr(printInfoDTO.getOriginalAmount()))); +// data.append(StrUtil.format("折扣:-{}
", toPlainStr(printInfoDTO.getDiscountAmount()))); +// } +// data.append("--------------------------------
"); +// String t = "¥" + printInfoDTO.getPayAmount(); +// if (printInfoDTO.isReturn()) { +// data.append(StrUtil.format("应退:{}
", t)); +// } else { +// data.append(StrUtil.format("应收:{}
", t)); +// } +// data.append("--------------------------------
"); +// if (ObjectUtil.isNotEmpty(printInfoDTO.getPayType()) && ObjectUtil.isNotNull(printInfoDTO.getPayType()) && printInfoDTO.getPayType().equals("deposit")) { +// data.append(StrUtil.format("储值:{}
", toPlainStr(printInfoDTO.getOriginalAmount()))); +// data.append(StrUtil.format("积分:{}
", printInfoDTO.getIntegral())); +// } +// data.append(StrUtil.format("余额:{}
", toPlainStr(printInfoDTO.getBalance()))); +// data.append("--------------------------------
"); +// if (StrUtil.isNotBlank(printInfoDTO.getRemark())) { +// data.append(StrUtil.format("备注:{}
", printInfoDTO.getRemark())); +// } +// data.append("打印时间:").append(DateUtil.date().toDateStr()).append("
"); +// data.append(""); +// return data.toString(); +// } /** * 构建打印内容 */ - @Override - public String buildDishPrintData(String pickupNumber, String date, String productName, - BigDecimal number, String remark, String proGroupInfo) { - StringBuilder builder = new StringBuilder() - .append("").append(pickupNumber).append("
") - .append("时间: ").append(date).append("
") - .append("").append(productName).append(" x ") - .append(number.stripTrailingZeros().toPlainString()).append("
") - .append("").append(StrUtil.emptyToDefault(remark, "")).append("
"); - - if (StrUtil.isNotBlank(proGroupInfo) && JSONUtil.isTypeJSONArray(proGroupInfo)) { - JSONArray subItems = JSONUtil.parseArray(proGroupInfo); - for (int i = 0; i < subItems.size(); i++) { - builder.append("(").append(i + 1).append(")") - .append(subItems.getJSONObject(i).getStr("proName")) - .append(" x ").append(subItems.getJSONObject(i).getInt("number")) - .append("
"); - } - } - return builder.toString(); - } +// @Override +// public String buildDishPrintData(String pickupNumber, String date, String productName, +// BigDecimal number, String remark, String proGroupInfo) { +// StringBuilder builder = new StringBuilder() +// .append("").append(pickupNumber).append("
") +// .append("时间: ").append(date).append("
") +// .append("").append(productName).append(" x ") +// .append(number.stripTrailingZeros().toPlainString()).append("
") +// .append("").append(StrUtil.emptyToDefault(remark, "")).append("
"); +// +// if (StrUtil.isNotBlank(proGroupInfo) && JSONUtil.isTypeJSONArray(proGroupInfo)) { +// JSONArray subItems = JSONUtil.parseArray(proGroupInfo); +// for (int i = 0; i < subItems.size(); i++) { +// builder.append("(").append(i + 1).append(")") +// .append(subItems.getJSONObject(i).getStr("proName")) +// .append(" x ").append(subItems.getJSONObject(i).getInt("number")) +// .append("
"); +// } +// } +// return builder.toString(); +// } @Override - public R sendPrintRequest(String address, String metaPrintData, String printerNum) { + public R sendPrintRequest(String address, String metaPrintData, String voiceData, String printerNum) { log.info("飞蛾打印机开始发送打印请求, 设备地址: {}, 元数据: {}", address, metaPrintData); String time = String.valueOf(System.currentTimeMillis() / 1000); MultiValueMap formData = new LinkedMultiValueMap<>(); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/print/PrinterImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/print/PrinterImpl.java index f7155563..753e50cb 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/print/PrinterImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/print/PrinterImpl.java @@ -34,7 +34,6 @@ public interface PrinterImpl { private String[] l; private String[] qr; private String cut; - } @@ -46,45 +45,26 @@ public interface PrinterImpl { */ // String buildOrderPrintData(PrinterHandler.PrintInfoDTO printInfoDTO, List detailList); - /** - * 构建菜品单打印数据 - * - * @param pickupNumber 取餐号 - * @param date 时间 - * @param productName 商品名 - * @param number 数量 - * @param remark 备注 - * @param proGroupInfo 套餐信息 - * @return 元数据 - */ - String buildDishPrintData(String pickupNumber, String date, String productName, BigDecimal number, String remark, String proGroupInfo); /** * 发送打印请求 * * @param address 打印地址 * @param metaPrintData 打印元数据 + * @param voiceData 语音信息 * @param printNum 打印联数 * @param 返回数据类型 * @return 打印结果 */ - R sendPrintRequest(String address, String metaPrintData, String printNum); + R sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum); + /** + * 获取当前打印机标签信息 + * + * @return 标签信息 + */ PrintSignLabel getSignLabelInfo(); - /** - * 分割起始标签 如 - * - * @return 标签 - */ - String getStartSplitSign(); - - /** - * 分割结束标签 - * - * @return 标签 - */ - String getEndSplitSign(); /** * 获取对齐后的小票明细行数据 @@ -170,7 +150,7 @@ public interface PrinterImpl { // data.append(""); // data.append("
"); data.append(getFormatLabel(StrUtil.format("订单号:{}", printInfoDTO.getOrderNo()), signLabelInfo.s)) - .append(signLabelInfo.br); + .append(signLabelInfo.br); // data.append(StrUtil.format("订单号:{}
", printInfoDTO.getOrderNo())); data.append(getFormatLabel(StrUtil.format("交易时间:{}", printInfoDTO.getTradeDate()), signLabelInfo.s)) .append(signLabelInfo.br); @@ -193,7 +173,7 @@ public interface PrinterImpl { String row = getRow(detail.getProductName(), "", number, toPlainStr(detail.getPayAmount().stripTrailingZeros().toPlainString()), 20, 0, 3, 6); data.append(row); if (StrUtil.isNotBlank(detail.getSkuName())) { - data.append(getFormatLabel(detail.getSkuName(), signLabelInfo.s)) + data.append(getFormatLabel(StrUtil.format("规格:{}", detail.getSkuName()), signLabelInfo.s)) .append(signLabelInfo.br); // data.append("规格:").append(detail.getSkuName()).append("
"); } @@ -232,7 +212,7 @@ public interface PrinterImpl { .append(signLabelInfo.br); // data.append("应退").append(t).append("
"); } else { - data.append(getFormatLabel(StrUtil.format("应收:{}", t) , signLabelInfo.f)) + data.append(getFormatLabel(StrUtil.format("应收:{}", t), signLabelInfo.f)) .append(signLabelInfo.br); // data.append(StrUtil.format("应收:{}
", t)); } @@ -273,6 +253,74 @@ public interface PrinterImpl { return data.toString(); } + /** + * 构建菜品单打印数据 + * + * @param pickupNumber 取餐号 + * @param date 时间 + * @param productName 商品名 + * @param skuName 规格名称 + * @param number 数量 + * @param remark 备注 + * @param proGroupInfo 套餐信息 + * @return 元数据 + */ + default String buildDishPrintData(boolean isReturn, String pickupNumber, String date, String productName, String skuName, BigDecimal number, String remark, String proGroupInfo) { + PrintSignLabel signLabelInfo = getSignLabelInfo(); + StringBuilder builder = new StringBuilder(); + if (isReturn) { + builder.append(getFormatLabel(StrUtil.format("{}【退】", pickupNumber), signLabelInfo.center, signLabelInfo.bold)) + .append(signLabelInfo.br) + .append(signLabelInfo.br); +// builder.append("").append(pickupNumber).append("【退】

"); + } else { + builder.append(getFormatLabel(pickupNumber, signLabelInfo.center, signLabelInfo.bold)) + .append(signLabelInfo.br) + .append(signLabelInfo.br); +// builder.append("").append(pickupNumber).append("

"); + } + builder.append(getFormatLabel(StrUtil.format("时间: {}", date), signLabelInfo.l, signLabelInfo.s)) + .append(signLabelInfo.br) + .append(signLabelInfo.br); +// builder.append("时间: ").append(date).append("


"); + if (productName.length() > 4 || skuName.length() > 4) { + builder.append(getFormatLabel(StrUtil.format("{} x {}", productName, number.stripTrailingZeros().toPlainString()), signLabelInfo.bold, signLabelInfo.l)) + .append(signLabelInfo.br); +// builder.append("").append(productName).append(" x ").append(number).append("
"); + if (StrUtil.isNotBlank(skuName)) { + builder.append(getFormatLabel(skuName, signLabelInfo.bold, signLabelInfo.l)).append(signLabelInfo.br); +// builder.append("").append(skuName).append("
"); + } + } else { + builder.append(getFormatLabel(StrUtil.format("{} x ", productName), signLabelInfo.bold)); +// builder.append("").append(productName).append(" x ").append(number).append("
"); + if (StrUtil.isNotBlank(skuName)) { + builder.append(getFormatLabel(skuName, signLabelInfo.bold)) + .append(signLabelInfo.br); +// builder.append("").append(skuName).append("
"); + } + } + if (StrUtil.isNotBlank(remark)) { + builder.append(signLabelInfo.br); + builder.append(getFormatLabel(StrUtil.format("备注:{}", remark), signLabelInfo.s, signLabelInfo.l)) + .append(signLabelInfo.br); +// builder.append("备注: ").append(note).append("
"); + } + if (!StrUtil.isBlank(proGroupInfo) && JSONUtil.isTypeJSONArray(proGroupInfo)) { + JSONArray subItems = cn.hutool.json.JSONUtil.parseArray(proGroupInfo); + for (int i = 0; i < subItems.size(); i++) { + String proName = subItems.getJSONObject(i).getStr("proName"); + int qty = subItems.getJSONObject(i).getInt("number"); + builder.append(StrUtil.format("({}) x ", proName)) + .append(signLabelInfo.br); +// builder.append("(").append(i + 1).append(")").append(proName).append(" x ").append(qty).append("
"); + } + } + builder.append(signLabelInfo.br); +// builder.append(""); +// builder.append(""); + return builder.toString(); + } /** * 按字符数补足空格(英文、数字时使用) @@ -331,6 +379,7 @@ public interface PrinterImpl { * @return */ default String getStringByEnter(String string, int length) { + PrintSignLabel signLabelInfo = getSignLabelInfo(); StringBuilder result = new StringBuilder(); while (!string.isEmpty()) { int pos = 0, byteCount = 0; @@ -340,7 +389,7 @@ public interface PrinterImpl { byteCount += charByteLen; pos = i + 1; } - result.append(getStartSplitSign()).append(string, 0, pos).append(getEndSplitSign()); + result.append(signLabelInfo.s[0]).append(string, 0, pos).append(signLabelInfo.s[1]); string = string.substring(pos); if (!string.isEmpty()) { result.append("
"); diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/print/YxyPrinter.java b/cash-service/account-service/src/main/java/com/czg/service/account/print/YxyPrinter.java index b6333317..ba2183b3 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/print/YxyPrinter.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/print/YxyPrinter.java @@ -26,9 +26,14 @@ import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; +/** + * 云享印打印机 + * + * @author Administrator + */ @Slf4j @Component -public class YxyPrinter extends PrinterHandler { +public class YxyPrinter extends PrinterHandler implements PrinterImpl { //请求地址 private static final String URL_STR = "https://ioe.car900.com/v1/openApi/dev/customPrint.json"; @@ -42,6 +47,9 @@ public class YxyPrinter extends PrinterHandler { @Resource private ShopInfoService shopInfoService; + @Resource + private RestTemplate restTemplate; + public YxyPrinter() { super("yxyPrinter"); } @@ -55,20 +63,20 @@ public class YxyPrinter extends PrinterHandler { .setQr(new String[]{"", ""}) .setCenter(new String[]{"", ""}) .setBold(new String[]{"", ""}); + + @Override public PrinterImpl.PrintSignLabel getSignLabelInfo() { return printSignLabel; } - /** - * 打印票据 - */ - public static String printTickets(String voiceJson, Integer actWay, Integer cn, String devName, String data) { - log.info("开始请求云享印,请求数据:{}, {}", voiceJson, data); + @Override + public R sendPrintRequest(String address, String metaPrintData, String voiceData, String printNum) { + log.info("开始请求云享印,请求数据:{}, {}", voiceData, metaPrintData); //设备名称 //行为方式 1:只打印数据 2:只播放信息 3:打印数据并播放信息 // actWay = 3; -// //打印联数 + //打印联数 // int cn = 1; //打印内容 //播报语音数据体,字段参考文档IOT_XY_API11001 @@ -79,16 +87,15 @@ public class YxyPrinter extends PrinterHandler { //参数 MultiValueMap multiValueMap = new LinkedMultiValueMap<>(); multiValueMap.add("token", param.get("TOKEN")); - multiValueMap.add("devName", devName); - multiValueMap.add("actWay", actWay); - multiValueMap.add("cn", cn); - multiValueMap.add("data", data); - multiValueMap.add("voiceJson", voiceJson); + multiValueMap.add("devName", address); + multiValueMap.add("actWay", 3); + multiValueMap.add("cn", printNum); + multiValueMap.add("data", metaPrintData); + multiValueMap.add("voiceJson", voiceData); multiValueMap.add("appId", APP_ID); multiValueMap.add("timestamp", time); multiValueMap.add("requestId", uuid); multiValueMap.add("userCode", USER_CODE); - RestTemplate restTemplate = new RestTemplate(); HttpHeaders header = new HttpHeaders(); header.setContentType(MediaType.APPLICATION_FORM_URLENCODED); @@ -97,7 +104,7 @@ public class YxyPrinter extends PrinterHandler { httpEntity, String.class); log.info("请求云享印成功,响应数据: {}", httpResponse); - return httpResponse; + return (R) httpResponse; } @Override @@ -108,7 +115,7 @@ public class YxyPrinter extends PrinterHandler { orderDetail.getNum().intValue(), orderDetail.getSkuName(), orderDetail.getRemark(), orderDetail.getProGroupInfo()); // String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; - printTickets(voiceJson, 3, 1, machine.getAddress(), data); +// sendPrintRequest(voiceJson, 3, 1, machine.getAddress(), data); } @Override @@ -131,14 +138,14 @@ public class YxyPrinter extends PrinterHandler { .setOutNumber(orderInfo.getTakeCode()).setPrintTitle("结算单") .setRemark(orderInfo.getRemark()).setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString()); - String data = getCashPrintData(printInfoDTO, detailList); + String data = buildOrderPrintData(printInfoDTO, detailList); String voiceJson = "{\"PbizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}"; // String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}"; String printerNum = "1"; if (StrUtil.isNotBlank(machine.getPrintQty())) { printerNum = machine.getPrintQty().split("\\^")[1]; } - String resp = printTickets(voiceJson, 3, Integer.valueOf(printerNum), machine.getAddress(), data); + String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum); // shopPrintLogService.save(machine, printType, data, resp); } @@ -222,178 +229,4 @@ public class YxyPrinter extends PrinterHandler { } - // 按字符数补足空格(英文、数字时使用) - public static String addSpace(String str, int size) { - return StrUtil.fillAfter(str, ' ', size); - } - - // 按固定长度拆分字符串(按字符拆分) - public static List getStrList(String inputString, int length) { - List list = new ArrayList<>(); - for (int i = 0; i < inputString.length(); i += length) { - list.add(StrUtil.sub(inputString, i, Math.min(i + length, inputString.length()))); - } - return list; - } - - // 根据 GBK 字节数补空格(用于中文排版) - public static String titleAddSpace(String str, int b1) { - int byteLen = StrUtil.bytes(str, CharsetUtil.CHARSET_GBK).length; - return StrUtil.fillAfter(str, ' ', b1 - byteLen); - } - - // 判断字符串是否全为英文(GBK编码下,每个字符均为 1 字节) - public static boolean isEn(String str) { - return StrUtil.bytes(str, CharsetUtil.CHARSET_GBK).length == str.length(); - } - - // 将字符串按 GBK 字节长度拆分,每段包装在 标签内,并用
换行 - public static String getStringByEnter(int length, String string) { - StringBuilder result = new StringBuilder(); - while (!string.isEmpty()) { - int pos = 0, byteCount = 0; - for (int i = 0; i < string.length(); i++) { - int charByteLen = StrUtil.bytes(string.substring(i, i + 1), CharsetUtil.CHARSET_GBK).length; - if (byteCount + charByteLen > length) break; - byteCount += charByteLen; - pos = i + 1; - } - result.append("").append(string, 0, pos).append(""); - string = string.substring(pos); - if (!string.isEmpty()) { - result.append("
"); - } - } - return result.toString(); - } - - /** - * 获取对齐后的小票明细行数据 - * 例如:58mm 机器一行打印16个汉字/32个字母;80mm机器打印24个汉字/48个字母。 - * - * @param title 品名 - * @param price 单价 - * @param num 数量 - * @param total 小计 - * @param b1 品名占用字节数 - * @param b2 单价占用字节数 - * @param b3 数量占用字节数 - * @param b4 小计占用字节数 - * @return 格式化后的行数据(带
标签) - */ - public static String getRow(String title, String price, String num, String total, - int b1, int b2, int b3, int b4) { - price = addSpace(price, b2); - num = addSpace(num, b3); - total = addSpace(total, b4); - String otherStr = " %s%s %s".formatted(price, num, total); - - int titleByteLen = StrUtil.bytes(title, CharsetUtil.CHARSET_GBK).length; - StringBuilder sb = new StringBuilder(); - - if (titleByteLen <= b1) { - // 品名可以在一行显示,直接补足空格 - title = titleAddSpace(title, b1); - sb.append("").append(title).append(otherStr).append(""); - } else { - // 品名超出一行,进行拆分 - List lines = isEn(title) - // 英文按 b1 个字符拆分 - ? getStrList(title, b1) - // 中文按 b1/2 个字符拆分 - : getStrList(title, b1 / 2); - - // 第一行拼接其它字段 - String firstLine = titleAddSpace(lines.getFirst(), b1); - sb.append("").append(firstLine).append(otherStr).append("
"); - - // 剩余的行单独换行输出 - for (int i = 1; i < lines.size(); i++) { - sb.append("").append(lines.get(i)).append("
"); - } - } - sb.append("
"); - return sb.toString(); - } - - - private static String toPlainStr(String str) { - if (StrUtil.isBlank(str)) { - return "0"; - } - return NumberUtil.roundDown(new BigDecimal(str), 2).toPlainString(); - } - - - public static String getCashPrintData(PrintInfoDTO printInfoDTO, List detailList) { - StringBuilder data = new StringBuilder(); - data.append(StrUtil.format("{}
", printInfoDTO.getShopName())); - data.append("
"); - data.append(""); - data.append(StrUtil.format("{}【{}】
", printInfoDTO.getPrintTitle(), printInfoDTO.getPickupNum())); - //if (Objects.nonNull(printInfoDTO.getOutNumber())) { - // data.append(StrUtil.format("{}",printInfoDTO.getOutNumber())); - //} - data.append(""); - data.append("
"); - data.append(StrUtil.format("订单号:{}
", printInfoDTO.getOrderNo())); - data.append(StrUtil.format("交易时间:{}
", printInfoDTO.getTradeDate())); - data.append(StrUtil.format("收银员:{}
", printInfoDTO.getOperator())); - data.append(""); - data.append("
"); - data.append("品名 数量 小计
"); - data.append("--------------------------------
"); - for (OrderDetail detail : detailList) { - String number = detail.getNum().stripTrailingZeros().toPlainString(); - String row = getRow(detail.getProductName(), "", number, toPlainStr(detail.getPayAmount().stripTrailingZeros().toPlainString()), 20, 0, 3, 6); - data.append(row); - if (StrUtil.isNotBlank(detail.getSkuName())) { - data.append("规格:").append(detail.getSkuName()).append("
"); - } - String proGroupInfo = detail.getProGroupInfo(); - if (StrUtil.isBlank(proGroupInfo)) { - continue; - } - if (!JSONUtil.isTypeJSONArray(proGroupInfo)) { - continue; - } - JSONArray subItems = cn.hutool.json.JSONUtil.parseArray(proGroupInfo); - for (int i = 0; i < subItems.size(); i++) { - String proName = subItems.getJSONObject(i).getStr("proName"); - int qty = subItems.getJSONObject(i).getInt("number"); - String subRow = getRow(" - " + proName, "", qty + ".00", "0.00", 20, 0, 3, 6); - data.append(subRow); - } - } - if (ObjectUtil.isNotNull(printInfoDTO.getDiscountAmount())) { - data.append("--------------------------------
"); - data.append(StrUtil.format("原价:{}
", toPlainStr(printInfoDTO.getOriginalAmount()))); - data.append(StrUtil.format("折扣:-{}
", toPlainStr(printInfoDTO.getDiscountAmount()))); - } - data.append("--------------------------------
"); - String t = "¥" + printInfoDTO.getPayAmount(); - if (printInfoDTO.isReturn()) { - data.append("应退").append(t).append("
"); - data.append(StrUtil.format("应收:{}
", t)); - } else { - data.append(StrUtil.format("应收:{}
", t)); - } - data.append("--------------------------------
"); - if (ObjectUtil.isNotEmpty(printInfoDTO.getPayType()) && ObjectUtil.isNotNull(printInfoDTO.getPayType()) && "deposit".equals(printInfoDTO.getPayType())) { - data.append(StrUtil.format("储值:{}
", toPlainStr(printInfoDTO.getOriginalAmount()))); - data.append(StrUtil.format("积分:{}
", printInfoDTO.getIntegral())); - } - data.append(StrUtil.format("余额:{}
", toPlainStr(printInfoDTO.getBalance()))); - data.append("--------------------------------
"); - if (StrUtil.isNotBlank(printInfoDTO.getRemark())) { - data.append(StrUtil.format("备注:{}
", printInfoDTO.getRemark())); - } - if (Objects.nonNull(printInfoDTO.getOutNumber())) { - data.append("".concat(printInfoDTO.getOutNumber()).concat("
")); - } - data.append("打印时间:").append(DateUtil.date().toDateStr()).append("
"); - data.append(""); - data.append(""); - return data.toString(); - } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PrintMachineServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PrintMachineServiceImpl.java index b7c83347..4025df74 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PrintMachineServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/PrintMachineServiceImpl.java @@ -52,7 +52,7 @@ public class PrintMachineServiceImpl extends ServiceImpl