diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopTableService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopTableService.java index dd7b7fa9f..9ffb13cc1 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopTableService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/ShopTableService.java @@ -25,7 +25,9 @@ public interface ShopTableService extends IService { Boolean add(Long shopId, ShopTableAddDTO shopTableAddDTO); - ShopTable getOneByTableCode(@NotNull Long shopId,@NotBlank String tableCode); + ShopTable getOneByTableCode(@NotNull Long shopId, @NotBlank String tableCode); + + String getTableAreaAndName(Long shopId, String tableCode, String tableName); void createQrCode(Long shopId, Integer num, HttpServletResponse response, HttpServletRequest request) throws IOException; @@ -39,6 +41,7 @@ public interface ShopTableService extends IService { Boolean updateStatus(long shopId, Long tableId, String tableCode, String status); Boolean clear(long shopId, ShopTableClearDTO shopTableClearDTO); + Boolean expiredTable(long tableId); Page pageInfo(Long shopId, Integer areaId, String tableCode, String status, String name, Boolean isBind); diff --git a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java index 50fb9adce..4933103ef 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/order/dto/OrderInfoRefundDTO.java @@ -37,6 +37,8 @@ public class OrderInfoRefundDTO implements Serializable { */ @NotNull(message = "退单金额不能为空") private BigDecimal refundAmount; + //操作人 + private String operator; /** * 退款金额 默认为 退单数量*单价* 订单 discount_ratio diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopStaffServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopStaffServiceImpl.java index 4c2728ca8..4cecc690b 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopStaffServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopStaffServiceImpl.java @@ -16,6 +16,7 @@ import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.spring.service.impl.ServiceImpl; import jakarta.annotation.Resource; +import org.apache.dubbo.config.annotation.DubboService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,7 +30,7 @@ import java.util.List; * @author Administrator * @since 2025-02-10 */ -@Service +@DubboService public class ShopStaffServiceImpl extends ServiceImpl implements ShopStaffService { @Resource private SysUserService sysUserService; diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java index 09b9bd801..d10641636 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/ShopTableServiceImpl.java @@ -116,6 +116,22 @@ public class ShopTableServiceImpl extends ServiceImpl") - .setCut("") + .setCut("") + .setOut("OUT") .setCenterBold(new String[]{"", ""}) .setF(new String[]{"", ""}) .setL(new String[]{"", ""}) .setS(new String[]{"", ""}) .setS(new String[]{"", ""}) - .setRight(new String[]{"", ""}) .setQr(new String[]{"", ""}) .setCenter(new String[]{"", ""}) .setBold(new String[]{"", ""}); diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java index 067573e3f..32069be50 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterHandler.java @@ -74,6 +74,10 @@ public abstract class PrinterHandler { @DubboReference protected ShopInfoService shopInfoService; @DubboReference + private ShopTableService shopTableService; + @DubboReference + private ShopStaffService shopStaffService; + @DubboReference protected ProductService productService; @DubboReference protected ProdSkuService prodSkuService; @@ -238,17 +242,19 @@ public abstract class PrinterHandler { /** * 处理退菜退款订单打印 - * @param printTitle 退菜单 / 退款单 - * @param operator 操作人 - * @param refundAmount 退款金额 - * @param refundReason 退款原因 - * @param refundType 退款方式 - * @param orderInfo 订单信息 - * @param detailList 退菜/退款 列表 + * + * @param printTitle 退菜单 / 退款单 + * @param operator 操作人 + * @param refundAmount 退款金额 + * @param refundReason 退款原因 + * @param refundType 退款方式 + * @param orderInfo 订单信息 + * @param detailList 退菜/退款 列表 */ public void refundOrderHandler(String printTitle, String operator, String refundAmount, String refundReason, String refundType, OrderInfo orderInfo, List detailList) { getPrintMachine(orderInfo.getShopId(), "cash", "normal", "").forEach(machine -> { + orderInfo.setTableName(getTableAreaAndName(orderInfo.getShopId(), orderInfo.getTableCode(), orderInfo.getTableName())); refundHandleRequest(machine, printTitle, operator, refundAmount, refundReason, refundType, orderInfo, detailList); }); } @@ -641,6 +647,10 @@ public abstract class PrinterHandler { return StrUtil.isBlank(orderInfo.getTableName()) ? orderInfo.getTakeCode() : orderInfo.getTableName(); } + public String getTableAreaAndName(Long shopId, String tableCode, String tableName) { + return shopTableService.getTableAreaAndName(shopId, tableCode, tableName); + } + public PrintInfoDTO returnOrderPrint(String printTitle, String operator, String refundAmount, String refundReason, String refundType, OrderInfo orderInfo, PrintMachine machine, List detailList) { @@ -704,9 +714,9 @@ public abstract class PrinterHandler { .subtract(orderInfo.getDiscountAllAmount()).setScale(2, RoundingMode.HALF_UP).toPlainString()); if (orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0) { - printInfoDTO.setSeatNum(orderInfo.getSeatNum()+"人"); + printInfoDTO.setSeatNum(orderInfo.getSeatNum() + "人"); printInfoDTO.setSeatAmount(orderInfo.getSeatAmount().divide(BigDecimal.valueOf(orderInfo.getSeatNum()), 2, RoundingMode.DOWN).toPlainString()); - }else { + } else { printInfoDTO.setSeatNum(""); } if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) { @@ -722,8 +732,10 @@ public abstract class PrinterHandler { printInfoDTO.setOriginalAmount(originalAmount.toPlainString()); printInfoDTO.setPayAmount(originalAmount.subtract(orderInfo.getDiscountAllAmount()).setScale(2, RoundingMode.HALF_UP).toPlainString()); if (orderInfo.getSeatNum() != null && orderInfo.getSeatAmount().compareTo(BigDecimal.ZERO) > 0) { - printInfoDTO.setSeatNum(orderInfo.getSeatNum().toString()); + printInfoDTO.setSeatNum(orderInfo.getSeatNum() + "人"); printInfoDTO.setSeatAmount(orderInfo.getSeatAmount().divide(BigDecimal.valueOf(orderInfo.getSeatNum()), 2, RoundingMode.DOWN).toPlainString()); + } else { + printInfoDTO.setSeatNum(""); } if (orderInfo.getPackFee().compareTo(BigDecimal.ZERO) > 0) { printInfoDTO.setPackFee(orderInfo.getPackFee().toPlainString()); @@ -737,15 +749,20 @@ public abstract class PrinterHandler { .eq(OrderInfo::getStatus, OrderStatusEnums.DONE.getCode()) .eq(OrderInfo::getShopId, orderInfo.getShopId()) .le(OrderInfo::getCreateTime, orderInfo.getCreateTime())); + PrintInfoDTO printInfoDTO = new PrintInfoDTO().setShopName(shopInfo.getShopName()) - .setPrintTitle(printTitle).setPrintType("收银-堂食").setPickupNum(getPickupNum(orderInfo)) - .setOrderNo(orderInfo.getOrderNo()) - .setOperator(operator).setPayAmount(orderInfo.getPayAmount().toPlainString()).setReturn(false) + .setPrintTitle(printTitle).setPrintType("收银-堂食") + .setPickupNum(getTableAreaAndName(orderInfo.getShopId(), orderInfo.getTableCode(), orderInfo.getTableName())) + .setOrderNo(orderInfo.getOrderNo()).setPayAmount(orderInfo.getPayAmount().toPlainString()).setReturn(false) .setOutNumber(orderInfo.getTakeCode()).setCount(count).setRemark(orderInfo.getRemark()) // 使用累计的总优惠金额,null 表示没有优惠 .setDiscountAmount(orderInfo.getDiscountAllAmount() != null ? orderInfo.getDiscountAllAmount().toPlainString() : "0.00"); + if (orderInfo.getStaffId() != null) { + ShopStaff detail = shopStaffService.detail(orderInfo.getShopId(), orderInfo.getStaffId()); + printInfoDTO.setOperator(detail.getName()); + } if ("结算单".equals(printTitle)) { if (StrUtil.isNotBlank(orderInfo.getPayType())) { switch (orderInfo.getPayType()) { diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java index c9c6bff30..ad24cc1d1 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/PrinterImpl.java @@ -1,5 +1,6 @@ package com.czg.service.order.print; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.NumberUtil; @@ -18,6 +19,7 @@ import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * 打印机具体打印方法接口,提供打印元数据获取,具体打印机实现对应方法即可 @@ -58,11 +60,12 @@ public interface PrinterImpl { private String[] centerBold; private String[] bold; private String br; + //f 的行数字符为 30 private String[] s; + //f 的行数字符为 14 private String[] f; private String[] l; private String[] qr; - private String[] Right; private String cut; private String out; private String rs; @@ -254,18 +257,18 @@ public interface PrinterImpl { data.append(getFormatLabel(printInfoDTO.getShopName(), signLabelInfo.s, signLabelInfo.center)).append(signLabelInfo.br); data.append(getFormatLabel(printInfoDTO.getPrintTitle(), signLabelInfo.s, signLabelInfo.center)).append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("桌台号: {}", printInfoDTO.getPickupNum()), signLabelInfo.f)).append(signLabelInfo.br); - data.append(getFormatLabel(getFormatLabel(StrUtil.format("{} {}", printInfoDTO.getPrintType(), printInfoDTO.getSeatNum())), signLabelInfo.s)).append(signLabelInfo.br); + data.append(getFormatLabel(getFormatLabel(leftRightAlign(printInfoDTO.getPrintType(), printInfoDTO.getSeatNum(), 32)), signLabelInfo.s)).append(signLabelInfo.br); if (StrUtil.isNotBlank(printInfoDTO.getTradeDate())) { data.append(getFormatLabel(StrUtil.format("结账时间:{}", printInfoDTO.getTradeDate()), signLabelInfo.s)).append(signLabelInfo.br); } data.append(getFormatLabel("--------------------------------", signLabelInfo.s)).append(signLabelInfo.br); - data.append(getFormatLabel("品名 单价 数量 ", signLabelInfo.s)).append(signLabelInfo.br); + data.append(getFormatLabel(formatItemLine("品名", "单价", "数量", 18, 9), signLabelInfo.s)).append(signLabelInfo.br); for (OrderDetail detail : detailList) { String number = detail.getNum().stripTrailingZeros().toPlainString(); - String row = getRow(detail.getProductName(), toPlainStr(detail.getUnitPrice().stripTrailingZeros().toPlainString()), number, toPlainStr(detail.getPayAmount().toPlainString()) - , 18, 0, 5, 5); - data.append(row); + String unitPrice = toPlainStr(detail.getUnitPrice().stripTrailingZeros().toPlainString()); + data.append(getFormatLabel(formatItemLine(detail.getProductName(), unitPrice, number, 18, 7), signLabelInfo.s)).append(signLabelInfo.br); + if (StrUtil.isNotBlank(detail.getSkuName())) { data.append(getFormatLabel(StrUtil.format("规格:{}", detail.getSkuName()), signLabelInfo.s)) .append(signLabelInfo.br); @@ -283,44 +286,39 @@ public interface PrinterImpl { jsonObject.getJSONArray("goods").forEach(item -> { String proName = ((JSONObject) item).getString("proName"); String qty = ((JSONObject) item).getString("number"); - String subRow = getRow(" - " + proName, "", qty, "0.00", 21, 0, 5, 6); - data.append(subRow); + data.append(getFormatLabel(formatItemLine(" - " + proName, "", qty, 18, 9), signLabelInfo.s)).append(signLabelInfo.br); }); } } if (StrUtil.isNotBlank(printInfoDTO.getSeatAmount())) { - String row = getRow("餐位费", "", StrUtil.format("{}{}", printInfoDTO.getSeatNum(), ""), - toPlainStr(printInfoDTO.getSeatAmount()), 21, 0, 5, 6); - data.append(row); + data.append(getFormatLabel(formatItemLine("餐位费", printInfoDTO.getSeatNum(), printInfoDTO.getSeatAmount(), 18, 9), signLabelInfo.s)).append(signLabelInfo.br); } if (StrUtil.isNotBlank(printInfoDTO.getPackFee())) { - String row = getRow("打包费", "", "", - toPlainStr(printInfoDTO.getPackFee()), 21, 0, 5, 6); - data.append(row); + data.append(getFormatLabel(formatItemLine("打包费", toPlainStr(printInfoDTO.getPackFee()), "", 18, 9), signLabelInfo.s)).append(signLabelInfo.br); + } data.append(getFormatLabel("--------------------------------", signLabelInfo.s)) .append(signLabelInfo.br); - data.append(getFormatLabel("原价:", signLabelInfo.s)); - data.append(getFormatLabel(toPlainStr(printInfoDTO.getOriginalAmount()), signLabelInfo.Right, signLabelInfo.s)); - - data.append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("原价:", printInfoDTO.getOriginalAmount(), 32), signLabelInfo.s)).append(signLabelInfo.br); if (ObjectUtil.isNotNull(printInfoDTO.getDiscountAmount())) { - data.append(getFormatLabel(StrUtil.format("优惠金额: -{}", toPlainStr(printInfoDTO.getDiscountAmount())), signLabelInfo.s)) - .append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("优惠金额:", "-" + printInfoDTO.getDiscountAmount(), 32), signLabelInfo.s)).append(signLabelInfo.br); } if (StrUtil.isNotBlank(printInfoDTO.getRemark())) { data.append(getFormatLabel(StrUtil.format("备注:{}", printInfoDTO.getRemark()), signLabelInfo.s)).append(signLabelInfo.br); } data.append(getFormatLabel("--------------------------------", signLabelInfo.s)).append(signLabelInfo.br); - data.append(getFormatLabel(StrUtil.format("应付金额: {}", printInfoDTO.getPayAmount()), signLabelInfo.s, signLabelInfo.bold)).append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("应付:", printInfoDTO.getPayAmount(), 16), signLabelInfo.f)).append(signLabelInfo.br); + if (StrUtil.isNotBlank(printInfoDTO.getPrintTitle())) { data.append(getFormatLabel("--------------------------------", signLabelInfo.s)).append(signLabelInfo.br); - data.append(getFormatLabel(StrUtil.format("已付金额: {}", printInfoDTO.getPayAmount()), signLabelInfo.s, signLabelInfo.bold)).append(signLabelInfo.br); - data.append(getFormatLabel(StrUtil.format("支付方式: {}", printInfoDTO.getPayType()), signLabelInfo.s)).append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("已付:", printInfoDTO.getPayAmount(), 16), signLabelInfo.f)).append(signLabelInfo.br); + + data.append(signLabelInfo.br); + data.append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("支付方式:", "支付宝小程序", 32), signLabelInfo.s)).append(signLabelInfo.br); } - data.append(getFormatLabel("--------------------------------", signLabelInfo.s)) - .append(signLabelInfo.br); + data.append(getFormatLabel("--------------------------------", signLabelInfo.s)).append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("操作员:{}", printInfoDTO.getOperator()), signLabelInfo.s)).append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("打印时间:{}", DateUtil.date().toString()), signLabelInfo.s)).append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("订单号:{}", printInfoDTO.getOrderNo()), signLabelInfo.s)).append(signLabelInfo.br); @@ -329,6 +327,7 @@ public interface PrinterImpl { return data.toString(); } + /** * 构建客看单订单打印元数据 * @@ -342,15 +341,15 @@ public interface PrinterImpl { data.append(getFormatLabel(printInfoDTO.getShopName(), signLabelInfo.s, signLabelInfo.center)).append(signLabelInfo.br); data.append(getFormatLabel("客看单", signLabelInfo.s, signLabelInfo.center)).append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("桌台号: {}", printInfoDTO.getPickupNum()), signLabelInfo.f)).append(signLabelInfo.br); - data.append(getFormatLabel(getFormatLabel(StrUtil.format("{} {}", printInfoDTO.getPrintType(), printInfoDTO.getSeatNum())), signLabelInfo.s)).append(signLabelInfo.br); + data.append(getFormatLabel(getFormatLabel(leftRightAlign(printInfoDTO.getPrintType(), printInfoDTO.getSeatNum(), 32)), signLabelInfo.s)).append(signLabelInfo.br); data.append(getFormatLabel("--------------------------------", signLabelInfo.s)).append(signLabelInfo.br); - data.append(getFormatLabel("品名 单价 数量 ", signLabelInfo.s)).append(signLabelInfo.br); + data.append(getFormatLabel(formatItemLine("品名", "单价", "数量", 18, 9), signLabelInfo.s)).append(signLabelInfo.br); for (OrderDetail detail : detailList) { String number = detail.getNum().stripTrailingZeros().toPlainString(); - String row = getRow(detail.getProductName(), toPlainStr(detail.getUnitPrice().toPlainString()), number, toPlainStr(detail.getPayAmount().toPlainString()) - , 18, 0, 5, 6); - data.append(row); + String unitPrice = toPlainStr(detail.getUnitPrice().stripTrailingZeros().toPlainString()); + data.append(getFormatLabel(formatItemLine(detail.getProductName(), unitPrice, number, 18, 7), signLabelInfo.s)).append(signLabelInfo.br); + if (StrUtil.isNotBlank(detail.getSkuName())) { data.append(getFormatLabel(StrUtil.format("规格:{}", detail.getSkuName()), signLabelInfo.s)) .append(signLabelInfo.br); @@ -368,35 +367,27 @@ public interface PrinterImpl { jsonObject.getJSONArray("goods").forEach(item -> { String proName = ((JSONObject) item).getString("proName"); String qty = ((JSONObject) item).getString("number"); - String subRow = getRow(" - " + proName, "", qty, "0.00", 21, 0, 5, 6); - data.append(subRow); + data.append(getFormatLabel(formatItemLine(" - " + proName, "", qty, 18, 9), signLabelInfo.s)).append(signLabelInfo.br); }); } } if (StrUtil.isNotBlank(printInfoDTO.getSeatAmount())) { - String row = getRow("餐位费", "", StrUtil.format("{}{}", printInfoDTO.getSeatNum(), ""), - toPlainStr(printInfoDTO.getSeatAmount()), 21, 0, 5, 6); - data.append(row); + data.append(getFormatLabel(formatItemLine("餐位费", printInfoDTO.getSeatNum(), printInfoDTO.getSeatAmount(), 18, 9), signLabelInfo.s)).append(signLabelInfo.br); } if (StrUtil.isNotBlank(printInfoDTO.getPackFee())) { - String row = getRow("打包费", "", "", - toPlainStr(printInfoDTO.getPackFee()), 21, 0, 5, 6); - data.append(row); + data.append(getFormatLabel(formatItemLine("打包费", toPlainStr(printInfoDTO.getPackFee()), "", 18, 9), signLabelInfo.s)).append(signLabelInfo.br); } - data.append(getFormatLabel("--------------------------------", signLabelInfo.s)) - .append(signLabelInfo.br); - data.append(getFormatLabel(StrUtil.format("原价: {}", toPlainStr(printInfoDTO.getOriginalAmount())), signLabelInfo.s)) + data.append(getFormatLabel("-------------------------------", signLabelInfo.s)) .append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("原价:", printInfoDTO.getOriginalAmount(), 32), signLabelInfo.s)).append(signLabelInfo.br); if (ObjectUtil.isNotNull(printInfoDTO.getDiscountAmount())) { - data.append(getFormatLabel(StrUtil.format("优惠金额: -{}", toPlainStr(printInfoDTO.getDiscountAmount())), signLabelInfo.s)) - .append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("优惠金额:", "-" + printInfoDTO.getDiscountAmount(), 32), signLabelInfo.s)).append(signLabelInfo.br); } if (StrUtil.isNotBlank(printInfoDTO.getRemark())) { - data.append(getFormatLabel(StrUtil.format("备注:{}", printInfoDTO.getRemark()), signLabelInfo.l, signLabelInfo.bold)) - .append(signLabelInfo.br); + data.append(getFormatLabel(StrUtil.format("备注:{}", printInfoDTO.getRemark()), signLabelInfo.s)).append(signLabelInfo.br); } data.append(getFormatLabel("--------------------------------", signLabelInfo.s)).append(signLabelInfo.br); - data.append(getFormatLabel(StrUtil.format("应付金额:{}", printInfoDTO.getPayAmount()), signLabelInfo.s, signLabelInfo.bold)).append(signLabelInfo.br); + data.append(getFormatLabel(leftRightAlign("应付金额:", printInfoDTO.getPayAmount(), 16), signLabelInfo.f)).append(signLabelInfo.br); data.append(getFormatLabel("--------------------------------", signLabelInfo.s)) .append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("操作员:{}", printInfoDTO.getOperator()), signLabelInfo.s)); @@ -408,7 +399,7 @@ public interface PrinterImpl { } /** - * 构建结算单 预结算单订单打印元数据 + * 构建退款订单打印元数据 * * @param printInfoDTO 打印信息 * @param detailList 订单详情 @@ -420,46 +411,44 @@ public interface PrinterImpl { data.append(getFormatLabel(printInfoDTO.getShopName(), signLabelInfo.s, signLabelInfo.center)).append(signLabelInfo.br); data.append(getFormatLabel(printInfoDTO.getPrintTitle(), signLabelInfo.s, signLabelInfo.center)).append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("桌台号: {}", printInfoDTO.getPickupNum()), signLabelInfo.f)).append(signLabelInfo.br); - data.append(getFormatLabel(getFormatLabel(StrUtil.format("{} {}人", printInfoDTO.getPrintType(), printInfoDTO.getSeatNum())), signLabelInfo.s)).append(signLabelInfo.br); + data.append(getFormatLabel(getFormatLabel(leftRightAlign(printInfoDTO.getPrintType(), printInfoDTO.getSeatNum(), 32)), signLabelInfo.s)).append(signLabelInfo.br); data.append(getFormatLabel("--------------------------------", signLabelInfo.s)).append(signLabelInfo.br); - data.append(getFormatLabel("退款明细 数量 小计 ", signLabelInfo.s)).append(signLabelInfo.br); + if(CollUtil.isNotEmpty(detailList)){ + data.append(getFormatLabel(formatItemLine("退款明细", "数量", "小计", 18, 9), signLabelInfo.s)).append(signLabelInfo.br); - for (OrderDetail detail : detailList) { - String number = detail.getNum().stripTrailingZeros().toPlainString(); - String amount = ""; - if ("退款单".equals(printInfoDTO.getPrintTitle())) { - amount = detail.getReturnAmount().stripTrailingZeros().toPlainString(); + for (OrderDetail detail : detailList) { + String number = detail.getNum().stripTrailingZeros().toPlainString(); + String amount = ""; + if ("退款单".equals(printInfoDTO.getPrintTitle())) { + amount = detail.getReturnAmount().stripTrailingZeros().toPlainString(); + } + data.append(getFormatLabel(formatItemLine(detail.getProductName(), amount, number, 18, 7), signLabelInfo.s)).append(signLabelInfo.br); + if (StrUtil.isNotBlank(detail.getSkuName())) { + data.append(getFormatLabel(StrUtil.format("规格:{}", detail.getSkuName()), signLabelInfo.s)) + .append(signLabelInfo.br); + } + String proGroupInfo = detail.getProGroupInfo(); + if (StrUtil.isBlank(proGroupInfo)) { + continue; + } + if (!JSONUtil.isTypeJSONArray(proGroupInfo)) { + continue; + } + JSONArray subItems = com.alibaba.fastjson2.JSONArray.parseArray(proGroupInfo); + for (Object subItem : subItems) { + JSONObject jsonObject = (JSONObject) subItem; + jsonObject.getJSONArray("goods").forEach(item -> { + String proName = ((JSONObject) item).getString("proName"); + String qty = ((JSONObject) item).getString("number"); + data.append(getFormatLabel(formatItemLine(" - " + proName, "", qty, 18, 9), signLabelInfo.s)).append(signLabelInfo.br); + }); + } } - String row = getRow(detail.getProductName(), "", number, amount - , 18, 0, 5, 6); - data.append(row); - if (StrUtil.isNotBlank(detail.getSkuName())) { - data.append(getFormatLabel(StrUtil.format("规格:{}", detail.getSkuName()), signLabelInfo.s)) - .append(signLabelInfo.br); - } - String proGroupInfo = detail.getProGroupInfo(); - if (StrUtil.isBlank(proGroupInfo)) { - continue; - } - if (!JSONUtil.isTypeJSONArray(proGroupInfo)) { - continue; - } - JSONArray subItems = com.alibaba.fastjson2.JSONArray.parseArray(proGroupInfo); - for (Object subItem : subItems) { - JSONObject jsonObject = (JSONObject) subItem; - jsonObject.getJSONArray("goods").forEach(item -> { - String proName = ((JSONObject) item).getString("proName"); - String qty = ((JSONObject) item).getString("number"); - String subRow = getRow(" - " + proName, "", qty, "0.00", 21, 0, 5, 6); - data.append(subRow); - }); - } - } - data.append(getFormatLabel("--------------------------------", signLabelInfo.s)) - .append(signLabelInfo.br); - if ("退款单".equals(printInfoDTO.getPrintTitle())) { - data.append(getFormatLabel(StrUtil.format("退款总计 {}", toPlainStr(printInfoDTO.getRefundAmount())), signLabelInfo.s, signLabelInfo.bold)) + data.append(getFormatLabel("--------------------------------", signLabelInfo.s)) .append(signLabelInfo.br); + } + if ("退款单".equals(printInfoDTO.getPrintTitle())) { + data.append(getFormatLabel(leftRightAlign("退款总计:", printInfoDTO.getRefundAmount(), 16), signLabelInfo.f)).append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("退款方式:{}", toPlainStr(printInfoDTO.getRefundType())), signLabelInfo.s)) .append(signLabelInfo.br); data.append(getFormatLabel(StrUtil.format("退款原因:{}", printInfoDTO.getRefundReason()), signLabelInfo.l, signLabelInfo.bold)) @@ -709,4 +698,71 @@ public interface PrinterImpl { } return NumberUtil.round(new BigDecimal(str), 2).toPlainString(); } + + + // 两个内容 左 右对齐 + default String leftRightAlign(String leftText, String rightText, int totalWidth) { + if (leftText == null) leftText = ""; + if (rightText == null) rightText = ""; + + // 1. 计算真实打印宽度(汉字=2,英文=1) + int leftWidth = getStringWidth(leftText); + int rightWidth = getStringWidth(rightText); + // 总长度 - 右边长度 = 左边可用长度 + // 2. 计算中间需要填充的空格数 + int spaceNum = totalWidth - leftWidth - rightWidth; + if (spaceNum < 0) spaceNum = 0; // 防止负数 + + // 3. 生成空格 + String spaces = " ".repeat(spaceNum); + // 4. 三段式拼接:左边 + 空格 + 右边 + return leftText + spaces + rightText; + } + + /** + * 获取字符串实际打印宽度(汉字=2,字母/数字=1) + */ + static int getStringWidth(String str) { + if (str == null || str.isEmpty()) return 0; + int width = 0; + for (char c : str.toCharArray()) { + if (String.valueOf(c).getBytes().length > 1) { + width += 2; // 中文 + } else { + width += 1; // 英文/数字 + } + } + return width; + } + + /** + * 通用三列对齐方法(严格总长度) + * 规则:key1=左对齐,key2=左对齐,key3=右对齐 + * 整行总长度 = totalWidth,绝不超界 + */ + default String formatItemLine(String key1, String key2, String key3, + int key1Width, + int key2Width) { + // 1. 空值安全处理 + key1 = Objects.toString(key1, ""); + key2 = Objects.toString(key2, ""); + key3 = Objects.toString(key3, ""); + + int w1 = getStringWidth(key1); + int w2 = getStringWidth(key2); + int w3 = getStringWidth(key3); + + int space1 = Math.max(key1Width - w1, 0); + int space2 = Math.max(key2Width - w2, 0); + + // 6. 最终按总显示宽度截断(100%不超界) + int usedWidth = key1Width + key2Width + w3; + int space3 = Math.max(32 - usedWidth, 0); + + // 5. 拼接:左1 + 空格 + 左2 + 空格 + (靠右空格) + 右3 + return key1 + " ".repeat(space1) + + key2 + " ".repeat(space2) + + " ".repeat(space3) + + key3; + } } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java index ce1a057bd..a3b389c3c 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/print/YxyPrinter.java @@ -58,11 +58,8 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { .setQr(new String[]{"", ""}) .setCenter(new String[]{"", ""}) .setCenterBold(new String[]{"", ""}) - - .setRight(new String[]{"", ""}) .setRs("RS") .setBr("
") - .setCut("") .setBold(new String[]{"", ""}); @Override @@ -134,7 +131,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl { public PrintInfoDTO returnOrderPrint(String printTitle, String operator, String refundAmount, String refundReason, String refundType, OrderInfo orderInfo, PrintMachine machine, List detailList) { PrintInfoDTO printInfoDTO = super.returnOrderPrint(printTitle, operator, refundAmount, refundReason, refundType, orderInfo, machine, detailList); - String data = buildOrderPrintData(printInfoDTO, detailList); + String data = buildRefundOrderPrintData(printInfoDTO, detailList); sendOrderPrint(data, orderInfo.getId(), machine, "退款单"); return null; } diff --git a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java index 52d2da5ed..8ae8bd7d6 100644 --- a/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java +++ b/cash-service/order-service/src/main/java/com/czg/service/order/service/impl/OrderPayServiceImpl.java @@ -44,6 +44,7 @@ import com.czg.resp.CzgResult; import com.czg.service.RedisService; import com.czg.service.order.dto.OrderPayParamDTO; import com.czg.service.order.enums.OrderStatusEnums; +import com.czg.service.order.print.PrinterHandler; import com.czg.service.order.service.OrderPayService; import com.czg.service.order.service.PayService; import com.czg.utils.AssertUtil; @@ -93,6 +94,8 @@ public class OrderPayServiceImpl implements OrderPayService { @Resource private RabbitPublisher rabbitPublisher; @Resource + private PrinterHandler printerHandler; + @Resource private MkShopRechargeService shopRechargeService; @Resource private MkShopRechargeDetailService shopRechargeDetailService; @@ -402,12 +405,19 @@ public class OrderPayServiceImpl implements OrderPayService { //退款数量 BigDecimal refNum = refundDetail.getNum(); OrderDetail orderDetail = orderDetailService.getById(refundDetail.getId()); + if (orderDetail == null) { + throw new CzgException("退单失败,订单明细不存在"); + } + refundDetail.setProductName(orderDetail.getProductName()); + refundDetail.setSkuName(orderDetail.getSkuName()); + //可退数量=订单数量-退单数量-退菜数量 BigDecimal returnNum = orderDetail.getNum().subtract(orderDetail.getRefundNum()).subtract(orderDetail.getReturnNum()); if (returnNum.compareTo(BigDecimal.ZERO) <= 0 || returnNum.compareTo(refundDetail.getNum()) < 0) { throw new CzgException("退单失败," + orderDetail.getProductName() + "可退数量不足"); } refundDetail.setReturnAmount(refundDetail.getNum().multiply(orderDetail.getUnitPrice()).setScale(2, RoundingMode.UP)); + BigDecimal yuanReturnAmount = orderDetail.getReturnAmount(); if (isPay) { orderDetail.setRefundNum(orderDetail.getRefundNum().add(refNum)); if (orderDetail.getNum().compareTo(orderDetail.getRefundNum().add(orderDetail.getReturnNum())) == 0) { @@ -426,6 +436,7 @@ public class OrderPayServiceImpl implements OrderPayService { orderDetail.setRefundRemark(orderDetail.getRefundRemark() + param.getRefundReason()); if (orderDetail.getReturnAmount().compareTo(orderDetail.getPayAmount()) > 0) { orderDetail.setReturnAmount(orderDetail.getPayAmount()); + refundDetail.setReturnAmount(orderDetail.getPayAmount().subtract(yuanReturnAmount)); } orderDetailService.updateById(orderDetail); if (orderDetail.getProductId() != null && orderDetail.getProductId() > 0) { @@ -439,8 +450,7 @@ public class OrderPayServiceImpl implements OrderPayService { } else if (isPay) { orderInfo.setStatus(OrderStatusEnums.REFUND.getCode()); } - } - else { + } else { orderInfo.setStatus(OrderStatusEnums.REFUND.getCode()); List orderDetails = orderDetailService.list( QueryWrapper.create().select(OrderDetail::getId, OrderDetail::getProductId, OrderDetail::getNum, OrderDetail::getReturnNum, OrderDetail::getPackAmount, OrderDetail::getReturnNum) @@ -464,8 +474,10 @@ public class OrderPayServiceImpl implements OrderPayService { orderDetailService.updateBatch(orderDetails); } //总退款金额 + String printTitle = "退菜单"; //TODO 退款 券 未处理 if (isPay) { + printTitle = "退款单"; orderInfo.setRefundType("cash"); //非现金退款 if (!param.isCash()) { @@ -497,8 +509,9 @@ public class OrderPayServiceImpl implements OrderPayService { } orderInfo.setRefundRemark(orderInfo.getRefundRemark() + param.getRefundReason()); orderInfoService.updateById(orderInfo); - //退款后续 - + //退款后续 退款单/退菜单 + printerHandler.refundOrderHandler(printTitle, param.getOperator(), isPay ? param.getRefundAmount().toPlainString() : "0" + , param.getRefundReason(), orderInfo.getRefundType(), orderInfo, param.getRefundDetails()); //退款返还库存 if (!returnProMap.isEmpty()) { rabbitPublisher.sendOrderRefundMsg(JSONObject.toJSONString(Map.of("orderId", orderInfo.getId(), "returnProMap", returnProMap)));