From 1d328b38f7eaed5848c0362c707432324f0d27ba Mon Sep 17 00:00:00 2001
From: Jack <46790855@qq.com>
Date: Sat, 29 Nov 2025 02:27:02 +0800
Subject: [PATCH] =?UTF-8?q?=E9=80=80=E6=AC=BE=E6=89=93=E5=8D=B0=E6=96=B9?=
=?UTF-8?q?=E6=B3=95=E8=B0=83=E8=AF=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../mall/common/pojo/vo/OrderPrintVO.java | 5 +-
.../mall/common/utils/FreeMakerUtils.java | 6 +-
.../controller/mobile/LakalaController.java | 5 +-
.../service/ShopStorePrinterService.java | 9 ++
.../impl/ShopStorePrinterLogServiceImpl.java | 51 +++++--
.../impl/ShopStorePrinterServiceImpl.java | 139 +++++++++++++++++-
.../mapper/order/ShopOrderReturnMapper.xml | 3 +-
.../templates/refund_order_printer.txt | 10 +-
8 files changed, 202 insertions(+), 26 deletions(-)
diff --git a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java
index 9c7db24a..d1f166ab 100644
--- a/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java
+++ b/mall-common/src/main/java/com/suisung/mall/common/pojo/vo/OrderPrintVO.java
@@ -29,6 +29,9 @@ public class OrderPrintVO implements Serializable {
@ApiModelProperty(value = "退单编号")
private String return_id;
+ @ApiModelProperty(value = "店铺Id")
+ private Integer store_id;
+
@ApiModelProperty(value = "店铺名称")
private String store_name;
@@ -132,7 +135,7 @@ public class OrderPrintVO implements Serializable {
private String cashier = "收银员";
@ApiModelProperty(value = "订单商品详情打印对象列表")
- private List orderItemPrintVOList;
+ private List order_items;
}
diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java
index 90877d3c..955df822 100644
--- a/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java
+++ b/mall-common/src/main/java/com/suisung/mall/common/utils/FreeMakerUtils.java
@@ -39,7 +39,7 @@ public class FreeMakerUtils {
* @throws IOException
* @throws TemplateException
*/
- public static String processTemplate(Configuration configuration, String templateName, String templateValue, Map binding) {
+ public static String processTemplate(Configuration configuration, String templateName, String templateValue, Object binding) {
StringWriter stringWriter = new StringWriter();
try {
Template template = new Template(templateName, templateValue, configuration);
@@ -63,4 +63,8 @@ public class FreeMakerUtils {
public static String processTemplate(String templateName, String templateValue, Map binding) {
return processTemplate(stringTempConfiguration(), templateName, templateValue, binding);
}
+
+ public static String processTemplate(String templateName, String templateValue, Object binding) {
+ return processTemplate(stringTempConfiguration(), templateName, templateValue, binding);
+ }
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java
index 7d5f3e00..43ee78a6 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/lakala/controller/mobile/LakalaController.java
@@ -20,6 +20,7 @@ import com.suisung.mall.shop.message.service.PushMessageService;
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
import com.suisung.mall.shop.order.service.ShopOrderReturnService;
import com.suisung.mall.shop.sfexpress.service.SFExpressApiService;
+import com.suisung.mall.shop.store.service.ShopStorePrinterService;
import com.suisung.mall.shop.store.service.ShopStoreSameCityTransportBaseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -77,7 +78,7 @@ public class LakalaController extends BaseControllerImpl {
@Lazy
@Resource
- private LakalaApiService lakalaApiService;
+ private ShopStorePrinterService shopStorePrinterService;
@Resource
private LklLedgerEcService lklLedgerEcService;
@@ -93,7 +94,7 @@ public class LakalaController extends BaseControllerImpl {
// return lakalaApiService.tradeQuery(paramsJSON.getInt("storeId"), paramsJSON.getStr("orderId"));
- return JSONUtil.parseObj(shopOrderReturnService.fetchReturnOrderPrintInfo("", "FX_20251127_9"));
+ return shopStorePrinterService.printShopStoreReturnOrder(paramsJSON.getStr("orderId"), paramsJSON.getStr("returnId"));
}
@ApiOperation(value = "批量发送推送消息 - 测试案例", notes = "批量发送推送消息 - 测试案例")
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java
index 833c0e35..7aa53d9f 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/ShopStorePrinterService.java
@@ -80,6 +80,15 @@ public interface ShopStorePrinterService extends IBaseService
*/
Boolean printShopStoreOrder(Integer storeId, String orderId);
+ /**
+ * 退货成功后,立即打印门店的退货信息
+ *
+ * @param orderId
+ * @param returnId
+ * @return
+ */
+ Boolean printShopStoreReturnOrder(String orderId, String returnId);
+
/**
* 获取店铺所有有效打印机
*
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java
index 413bd440..8257424e 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterLogServiceImpl.java
@@ -5,11 +5,9 @@ import cn.hutool.core.util.StrUtil;
import com.suisung.mall.common.modules.store.ShopStorePrinterLog;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.store.mapper.ShopStorePrinterLogMapper;
-import com.suisung.mall.shop.store.mapper.ShopStorePrinterMapper;
import com.suisung.mall.shop.store.service.ShopStorePrinterLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -19,41 +17,70 @@ import java.util.List;
public class ShopStorePrinterLogServiceImpl extends BaseServiceImpl implements ShopStorePrinterLogService {
private static final Logger logger = LoggerFactory.getLogger(ShopStorePrinterLogServiceImpl.class);
- @Autowired
- private ShopStorePrinterMapper shopStorePrinterMapper;
@Override
public Boolean insertShopStorePrinterLog(ShopStorePrinterLog record) {
+ // 参数校验
if (record == null) {
+ logger.warn("插入打印日志失败:记录为空");
return false;
}
+ // 必要字段校验
if (record.getStore_id() == null ||
StrUtil.isBlank(record.getOrder_id()) ||
StrUtil.isBlank(record.getTemplate_value()) ||
StrUtil.isBlank(record.getPrint_content())) {
+ logger.warn("插入打印日志失败:必要字段缺失,storeId={}, orderId={}",
+ record.getStore_id(), record.getOrder_id());
return false;
}
- return add(record);
+ try {
+ // 执行插入操作
+ return add(record);
+ } catch (Exception e) {
+ logger.error("插入打印日志时发生异常,storeId={}, orderId={}",
+ record.getStore_id(), record.getOrder_id(), e);
+ return false;
+ }
}
+
@Override
public void insertShopStorePrinterLogBatch(List records) {
+ // 参数校验
if (CollUtil.isEmpty(records)) {
+ logger.debug("批量插入打印日志失败:记录列表为空");
return;
}
- for (ShopStorePrinterLog record : records) {
- if (record.getStore_id() == null ||
- StrUtil.isBlank(record.getOrder_id()) ||
- StrUtil.isBlank(record.getTemplate_value()) ||
- StrUtil.isBlank(record.getPrint_content())) {
- continue;
+ try {
+ for (ShopStorePrinterLog record : records) {
+ // 单条记录校验
+ if (record == null) {
+ logger.warn("批量插入打印日志跳过:记录为空");
+ continue;
+ }
+
+ if (record.getStore_id() == null ||
+ StrUtil.isBlank(record.getOrder_id()) ||
+ StrUtil.isBlank(record.getTemplate_value()) ||
+ StrUtil.isBlank(record.getPrint_content())) {
+ logger.warn("批量插入打印日志跳过:必要字段缺失,storeId={}, orderId={}",
+ record.getStore_id(), record.getOrder_id());
+ continue;
+ }
+
+ // 执行插入操作
+ add(record);
}
- add(record);
+ logger.debug("批量插入打印日志完成,共处理 {} 条记录", records.size());
+ } catch (Exception e) {
+ logger.error("批量插入打印日志时发生异常,记录数: {}", records.size(), e);
}
}
+
}
diff --git a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java
index 1efc3c6a..a1debf34 100644
--- a/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java
+++ b/mall-shop/src/main/java/com/suisung/mall/shop/store/service/impl/ShopStorePrinterServiceImpl.java
@@ -14,13 +14,15 @@ import com.suisung.mall.common.domain.UserDto;
import com.suisung.mall.common.modules.store.ShopStorePrinter;
import com.suisung.mall.common.modules.store.ShopStorePrinterLog;
import com.suisung.mall.common.modules.store.ShopStorePrinterTemplate;
+import com.suisung.mall.common.pojo.vo.OrderItemPrintVO;
+import com.suisung.mall.common.pojo.vo.OrderPrintVO;
import com.suisung.mall.common.pojo.vo.ShopStorePrinterVO;
import com.suisung.mall.common.utils.CheckUtil;
import com.suisung.mall.common.utils.FreeMakerUtils;
import com.suisung.mall.common.utils.JsonUtil;
import com.suisung.mall.core.web.service.impl.BaseServiceImpl;
import com.suisung.mall.shop.order.service.ShopOrderBaseService;
-import com.suisung.mall.shop.order.service.impl.ShopOrderInfoServiceImpl;
+import com.suisung.mall.shop.order.service.ShopOrderReturnService;
import com.suisung.mall.shop.store.mapper.ShopStorePrinterMapper;
import com.suisung.mall.shop.store.service.ShopStorePrinterLogService;
import com.suisung.mall.shop.store.service.ShopStorePrinterService;
@@ -49,15 +51,13 @@ public class ShopStorePrinterServiceImpl extends BaseServiceImpl
+ * 该方法通过调用飞鹅打票机接口,完成指定订单的退货小票打印功能。主要流程包括:
+ * 1. 校验订单号是否合法;
+ * 2. 获取订单及店铺相关信息;
+ * 3. 查询对应店铺绑定的打印机列表与打印模板;
+ * 4. 渲染打印内容并发送至所有绑定的打印机;
+ * 5. 记录打印日志。
+ *
+ *
+ * @param orderId 订单编号,不能为空
+ * @param returnId 退货单编号,用于标识具体的退货记录
+ * @return 打印操作是否成功,成功返回 true,否则返回 false
+ */
+ @Override
+ public Boolean printShopStoreReturnOrder(String orderId, String returnId) {
+ logger.debug("#### 调用飞鹅打票机的打印退款订单操作开始 ####");
+
+ // 参数校验
+ if (StrUtil.isBlank(returnId)) {
+ logger.error("退款订单为空,无法打印小票。");
+ return false;
+ }
+
+ try {
+ // 获取打印的订单信息,并检查订单是否存在且已支付
+ OrderPrintVO binding = shopOrderReturnService.fetchReturnOrderPrintInfo(orderId, returnId);
+ if (binding == null) {
+ logger.error("退款订单Id{}信息无法获取,无法打印小票。", returnId);
+ return false;
+ }
+
+ logger.debug("退款订单信息:{}", binding);
+
+ orderId = binding.getOrder_id();
+ Integer storeId = binding.getStore_id();
+ if (CheckUtil.isEmpty(storeId) || CheckUtil.isEmpty(orderId)) {
+ logger.warn("订单Id:{},店铺ID:{}为空,无法打印小票。", orderId, storeId);
+ return false;
+ }
+
+ // 查询店铺配置的打印机列表
+ List printerList = selectPrinterList(storeId);
+ if (CollUtil.isEmpty(printerList)) {
+ // 店铺没有打印机,不再继续执行打印逻辑
+ logger.error("店铺{}未添加打票机,无法打印小票。", storeId);
+ return false;
+ }
+
+ // 获取适用于退货场景的打印模板
+ ShopStorePrinterTemplate template = shopStorePrinterTemplateService.getShopStorePrinterTemplateInner(storeId, StateCode.PRINTER_TEMP_CATE_REFUND);
+ if (template == null || StrUtil.isBlank(template.getTemplate_name()) || StrUtil.isBlank(template.getTemplate_value())) {
+ // 模板缺失或无效,终止打印流程
+ logger.error("店铺{}未添加打票机打印模版,无法打印小票。", storeId);
+ return false;
+ }
+
+ // 重要:重构实体类,处理标题,数量,价格适应长度
+ List orderItems = binding.getOrder_items();
+ if (CollUtil.isEmpty(orderItems)) {
+ logger.error("订单{}商品信息为空,无法打印小票。", orderId);
+ return false;
+ }
+
+ List rebuiltItems = new ArrayList<>(orderItems.size());
+ for (OrderItemPrintVO item : orderItems) {
+ if (item != null) {
+ rebuiltItems.add(item.rebuild());
+ }
+ }
+ binding.setOrder_items(rebuiltItems);
+
+ // 使用 FreeMarker 模板引擎渲染实际要打印的内容
+ String printContent = FreeMakerUtils.processTemplate(template.getTemplate_name(), template.getTemplate_value(), binding);
+ if (StrUtil.isBlank(printContent)) {
+ logger.error("订单{}信息模版渲染异常,无法打印小票。", orderId);
+ return false;
+ }
+ logger.debug("打印内容长度:{}", printContent.length());
+
+ // 提取所有打印机设备序列号,准备批量打印
+ List printerSnList = new ArrayList<>(printerList.size());
+ for (ShopStorePrinter printer : printerList) {
+ if (printer != null && StrUtil.isNotBlank(printer.getPrinter_sn())) {
+ printerSnList.add(printer.getPrinter_sn());
+ }
+ }
+
+ if (CollUtil.isEmpty(printerSnList)) {
+ logger.error("订单{}没有有效的打印机设备,无法打印小票。", orderId);
+ return false;
+ }
+
+ // 向飞鹅打票机发送打印任务
+ List> respList = feieUtil.printContentByList(printerSnList, printContent);
+ if (CollUtil.isEmpty(respList)) {
+ // 所有打印机均未能响应,视为失败
+ logger.error("订单{}信息打印,调用飞鹅打印机打印失败。", orderId);
+ return false;
+ }
+
+ // 遍历每台打印机的响应结果,记录打印日志
+ for (Pair respSn : respList) {
+ if (respSn != null) {
+ // 构造并保存本次打印的日志记录
+ ShopStorePrinterLog shopStorePrinterLog = new ShopStorePrinterLog(
+ template.getCategory(),
+ storeId,
+ orderId,
+ template.getTemplate_id(),
+ template.getTemplate_value(),
+ JsonUtil.object2json(binding),
+ printContent,
+ respSn.getSecond(),
+ respSn.getFirst()
+ );
+ shopStorePrinterLogService.insertShopStorePrinterLog(shopStorePrinterLog);
+ }
+ }
+
+ logger.debug("#### 调用飞鹅打票机的打印操作结束 ####");
+ return true;
+
+ } catch (Exception e) {
+ logger.error("打印退货订单小票时发生异常,订单ID: {}, 退货单ID: {}", orderId, returnId, e);
+ return false;
+ }
+ }
+
+
@Override
public List selectPrinterList(Integer storeId) {
if (storeId == null) {
diff --git a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml
index 3cfd21a3..8ae0e6c9 100644
--- a/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml
+++ b/mall-shop/src/main/resources/mapper/order/ShopOrderReturnMapper.xml
@@ -92,6 +92,7 @@
+
@@ -123,7 +124,7 @@
-
+
diff --git a/mall-shop/src/main/resources/templates/refund_order_printer.txt b/mall-shop/src/main/resources/templates/refund_order_printer.txt
index 43bcf846..f4aa09e7 100644
--- a/mall-shop/src/main/resources/templates/refund_order_printer.txt
+++ b/mall-shop/src/main/resources/templates/refund_order_printer.txt
@@ -47,16 +47,16 @@
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
-配送时间:${payment_time}(之后20-30分钟)
+配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(之后20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
-付款时间:${payment_time}
-申请退款:${return_add_time}
-确认退款:${return_finish_time}
+付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}
+申请退款:${return_add_time?string('yyyy-MM-dd HH:mm:ss')}
+确认退款:${return_finish_time?string('yyyy-MM-dd HH:mm:ss')}
--------------------------------
******* 退款商品 ******
--------------------------------
@@ -78,4 +78,4 @@
${store_name}
--------------------------------
#${order_pickup_num_str}
买家备注:${order_message!'-'}
配送时间:${delivery_time}
--------------------------------
订单编号:${order_id}
订单来源:微信小程序
支付方式:微信支付
配送来源:顺丰同城
付款时间:${payment_time}
--------------------------------
商品名称 数量 金额
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
#list>#if><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
#if>#list>--------------------------------
商品总件数:${order_items_count!0}
商品总额:¥${order_product_amount?string('0.00')}
押金:¥${(yajin!0)?string('0.00')}
运费:¥${order_shipping_fee?string('0.00')}
会员权益:-¥${(quanyi!0)?string('0.00')}
秒杀:-¥${(miaosha!0)?string('0.00')}
实付金额:¥${order_payment_amount?string('0.00')}
<#if seller_message?default("")?trim?length gt 1>--------------------------------
商家备注:${seller_message!'---'}
#if>--------------------------------
收货人:${buyer_user_name!''}
收货人手机:${store_tel!''}
收货地址:${da_province!'-'}${da_city!'-'}${da_address!'-'}
--------------------------------
门店:${store_name}
门店电话:${store_tel!'-'}
收银员:${cashier!'-'}
带参模版:
-用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
配送时间:${payment_time}(之后20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
付款时间:${payment_time}
申请退款:${return_add_time}
确认退款:${return_finish_time}
--------------------------------
******* 退款商品 ******
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
#list>#if><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
#if>#list>--------------------------------
实付金额:¥${order_payment_amount?string('0.00')}元
配送费:¥${order_shipping_fee?string('0.00')}元
申请退款:¥${return_refund_amount?string('0.00')}
退款方式:${return_flag_str}
商家审批备注:${return_store_message!'-'}
--------------------------------
会员名称:${buyer_user_name}
会员手机:${return_tel}
--------------------------------
操作员:${cashier!'-'}
+用户退款订单
${store_name}
--------------------------------
#${order_pickup_num_str}
退款原因:${return_buyer_message!'-'}
配送时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}(20-30分钟)
--------------------------------
订单编号:${order_id}
退单编号:${return_id}
订单来源:${order_channel_name!'微信小程序'}
支付方式:${payment_type_name!'微信支付'}
配送来源:${deliver_type_name!'顺丰同城'}
付款时间:${payment_time?string('yyyy-MM-dd HH:mm:ss')}
申请退款:${return_add_time?string('yyyy-MM-dd HH:mm:ss')}
确认退款:${return_finish_time?string('yyyy-MM-dd HH:mm:ss')}
--------------------------------
******* 退款商品 ******
--------------------------------
<#list order_items as item>${item.s_name}${item.s_quantity}${item.s_amount}
<#if item.s_name_segs??><#list item.s_name_segs as seg>${seg}
#list>#if><#if item.product_sn?default("")?trim?length gt 1>${item.product_sn}
#if>#list>--------------------------------
实付金额:¥${order_payment_amount?string('0.00')}元
配送费:¥${order_shipping_fee?string('0.00')}元
申请退款:¥${return_refund_amount?string('0.00')}
退款方式:${return_flag_str}
商家审批备注:${return_store_message!'-'}
--------------------------------
会员名称:${buyer_user_name}
会员手机:${return_tel}
--------------------------------
操作员:${cashier!'-'}