打印问题
This commit is contained in:
@@ -25,7 +25,30 @@ spring:
|
||||
port: 5672
|
||||
username: chaozg
|
||||
password: chaozg123
|
||||
|
||||
# 关键优化:解决MissedHeartbeatException 心跳超时问题
|
||||
connection-timeout: 10000 # 连接超时时间(10秒,避免连接建立过慢)
|
||||
requested-heartbeat: 30 # 心跳间隔调整为30秒(原60秒过长,降低超时概率;过短易误触发)
|
||||
# 高级配置:连接池 & 自动重连(核心优化,避免连接断开后无法恢复)
|
||||
cache:
|
||||
connection:
|
||||
mode: channel # 连接池模式(默认channel,推荐)
|
||||
size: 10 # 最大连接数,根据业务调整
|
||||
channel:
|
||||
size: 50 # 每个连接的最大通道数
|
||||
# 自动重连配置(Spring AMQP 自带,关键兜底)
|
||||
publisher-returns: true
|
||||
template:
|
||||
retry:
|
||||
enabled: true # 开启消息发送重试
|
||||
max-attempts: 3 # 最大重试次数
|
||||
initial-interval: 2000 # 首次重试间隔2秒
|
||||
multiplier: 1.5 # 重试间隔倍增因子
|
||||
listener:
|
||||
simple:
|
||||
retry:
|
||||
enabled: true # 开启消费者重试
|
||||
max-attempts: 3 # 消费者最大重试次数
|
||||
acknowledge-mode: auto # 确认模式(可根据业务改为manual)
|
||||
dubbo:
|
||||
application:
|
||||
name: order-server
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.czg.order.entity;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.order.dto.LimitRateDTO;
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
@@ -346,15 +347,38 @@ public class OrderInfo implements Serializable {
|
||||
// .add(this.getRoundAmount() != null ? this.getRoundAmount() : BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
private JSONArray getPrintStatusAsArray() {
|
||||
if (StrUtil.isBlank(printStatus)) {
|
||||
return new JSONArray();
|
||||
}
|
||||
try {
|
||||
return JSONArray.parseArray(printStatus.trim());
|
||||
} catch (Exception e) {
|
||||
return new JSONArray();
|
||||
}
|
||||
}
|
||||
|
||||
// public JSONArray getPrintStatus() {
|
||||
// if (StrUtil.isBlank(printStatus)) {
|
||||
// return new JSONArray();
|
||||
// }
|
||||
// try {
|
||||
// return JSONArray.parseArray(printStatus.trim());
|
||||
// } catch (Exception e) {
|
||||
// return new JSONArray();
|
||||
// }
|
||||
// }
|
||||
public void upPrintStatus(JSONObject printStatus, boolean isPrintSuccess) {
|
||||
String currentDeviceId = printStatus.getString("id");
|
||||
JSONArray oldPrintStatusArray = getPrintStatusAsArray();
|
||||
// 3. 初始化新的打印状态JSON数组(用于存储处理后的结果)
|
||||
JSONArray newPrintStatusArray = new JSONArray();
|
||||
// 场景1:打印成功 - 移除原有数组中与当前设备ID一致的记录,保留其余记录
|
||||
if (oldPrintStatusArray != null && !oldPrintStatusArray.isEmpty()) {
|
||||
for (int i = 0; i < oldPrintStatusArray.size(); i++) {
|
||||
JSONObject deviceObj = oldPrintStatusArray.getJSONObject(i);
|
||||
String deviceId = deviceObj.getString("id");
|
||||
// 仅保留非当前设备ID的记录
|
||||
if (currentDeviceId != null && !currentDeviceId.equals(deviceId)) {
|
||||
newPrintStatusArray.add(deviceObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isPrintSuccess) {
|
||||
newPrintStatusArray.add(printStatus);
|
||||
}
|
||||
if(newPrintStatusArray.isEmpty()){
|
||||
this.setPrintStatus(newPrintStatusArray.toJSONString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import com.czg.order.entity.PrintMachineLog;
|
||||
* @since 2025-03-11
|
||||
*/
|
||||
public interface PrintMachineLogService extends IService<PrintMachineLog> {
|
||||
void save(Long orderId, PrintMachine config, String bizType, String printContent, String respJson);
|
||||
|
||||
void save(PrintMachine config, String bizType, String printContent, String respJson);
|
||||
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
|
||||
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(), orderDetail.getId(), orderDetail.isUrgent());
|
||||
String o = sendPrintRequest(machine.getAddress(), content, null, "1");
|
||||
printMachineLogService.save(machine, "新订单", content, o);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "新订单", content, o);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
|
||||
String content = buildDishPrintData(true, getPickupNum(orderInfo), orderInfo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
|
||||
orderDetail.getProductName(), orderDetail.getSkuName(), orderDetail.getReturnNum(), remark, orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent());
|
||||
String o = sendPrintRequest(machine.getAddress(), content, null, "1");
|
||||
printMachineLogService.save(machine, "退款单", content, o);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "退款单", content, o);
|
||||
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
|
||||
.setDiscountAmount(orderInfo.getOriginAmount().subtract(orderInfo.getPayAmount()).toPlainString());
|
||||
String string = buildOrderPrintData(printInfoDTO, detailList);
|
||||
String o = sendPrintRequest(machine.getAddress(), string, null, printerNum);
|
||||
printMachineLogService.save(machine, "结算单", string, o);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "结算单", string, o);
|
||||
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public class FeiPrinter extends PrinterHandler implements PrinterImpl {
|
||||
|
||||
String string = buildOrderPrintData(printInfoDTO, detailList);
|
||||
String resp = sendPrintRequest(machine.getAddress(), string, null, printerNum);
|
||||
printMachineLogService.save(machine, "结算单", string, resp);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "结算单", string, resp);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -342,6 +342,7 @@ public abstract class PrinterHandler {
|
||||
case PrintTypeEnum.ORDER:
|
||||
log.info("准备开始打印订单");
|
||||
if (data instanceof OrderInfo orderInfo) {
|
||||
redisService.set("order:print:" + orderInfo.getId(),"", 180);
|
||||
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
|
||||
onlyFrontDesk(machine, false, orderInfo, orderDetailList);
|
||||
} else {
|
||||
@@ -351,6 +352,7 @@ public abstract class PrinterHandler {
|
||||
case PrintTypeEnum.PRE_ORDER:
|
||||
log.info("准备开始打印预结算订单");
|
||||
if (data instanceof OrderInfo orderInfo) {
|
||||
redisService.set("order:print:" + orderInfo.getId(),"", 180);
|
||||
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
|
||||
onlyFrontDesk(machine, true, orderInfo, orderDetailList);
|
||||
} else {
|
||||
@@ -360,6 +362,7 @@ public abstract class PrinterHandler {
|
||||
case PrintTypeEnum.ONE:
|
||||
log.info("准备开始打印菜品单");
|
||||
if (data instanceof OrderInfo orderInfo) {
|
||||
redisService.set("order:print:" + orderInfo.getId(),"", 180);
|
||||
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
|
||||
onlyKitchen(machine, orderInfo, orderDetailList);
|
||||
} else {
|
||||
@@ -377,6 +380,7 @@ public abstract class PrinterHandler {
|
||||
case PrintTypeEnum.ONE_AND_ORDER:
|
||||
log.info("准备开始打印菜品以及结算单");
|
||||
if (data instanceof OrderInfo orderInfo) {
|
||||
redisService.set("order:print:" + orderInfo.getId(),"", 180);
|
||||
List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper().eq(OrderDetail::getOrderId, orderInfo.getId()));
|
||||
switch (machine.getPrintMethod()) {
|
||||
case "all":
|
||||
@@ -462,7 +466,7 @@ public abstract class PrinterHandler {
|
||||
OrderDetail orderDetail = detailMap.get(item.getId());
|
||||
redisService.set(RedisCst.getPrintOrderDetailKey(orderInfo.getId(), item.getId()),
|
||||
JSONObject.toJSONString(new PrintDetailInfo().setPrint(item.getIsPrint() == 1).setDetailId(item.getId())
|
||||
.setPrintNum(orderDetail.getNum()).setPrintReturnNum(orderDetail.getReturnNum())), 3600 * 24);
|
||||
.setPrintNum(orderDetail.getNum()).setPrintReturnNum(orderDetail.getReturnNum())), 3600 * 24);
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl {
|
||||
orderDetail.getNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent());
|
||||
String voiceJson = "{\"bizType\":\"2\",\"content\":\"您有一笔新的订单,请及时处理\"}";
|
||||
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1");
|
||||
printMachineLogService.save(machine, "新订单", buildDishPrintData, resp);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "新订单", buildDishPrintData, resp);
|
||||
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl {
|
||||
orderDetail.getReturnNum(), orderDetail.getRemark(), orderDetail.getProGroupInfo(), orderDetail.getId(), orderDetail.isUrgent());
|
||||
String voiceJson = "{\"bizType\":\"2\",\"content\":\"\"}";
|
||||
String resp = sendPrintRequest(machine.getAddress(), buildDishPrintData, voiceJson, "1");
|
||||
printMachineLogService.save(machine, "退款单", buildDishPrintData, resp);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "退款单", buildDishPrintData, resp);
|
||||
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl {
|
||||
printerNum = machine.getPrintQty().split("\\^")[1];
|
||||
}
|
||||
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum);
|
||||
printMachineLogService.save(machine, "退款单", data, resp);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "退款单", data, resp);
|
||||
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ public class YxyPrinter extends PrinterHandler implements PrinterImpl {
|
||||
printerNum = machine.getPrintQty().split("\\^")[1];
|
||||
}
|
||||
String resp = sendPrintRequest(machine.getAddress(), data, voiceJson, printerNum);
|
||||
printMachineLogService.save(machine, "结算单", data, resp);
|
||||
printMachineLogService.save(orderInfo.getId(), machine, "结算单", data, resp);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1516,6 +1516,9 @@ public class OrderInfoCustomServiceImpl implements OrderInfoCustomService {
|
||||
|
||||
@Override
|
||||
public Boolean printOrder(Long shopId, OrderInfoPrintDTO orderInfoPrintDTO) {
|
||||
if (redisService.hasKey("order:print:" + orderInfoPrintDTO.getId())) {
|
||||
throw new CzgException("网络打印机正在尝试打印中。如需重打,请稍后再试!");
|
||||
}
|
||||
OrderInfo orderInfo = orderInfoService.getOne(new QueryWrapper().eq(OrderInfo::getShopId, shopId).eq(OrderInfo::getId, orderInfoPrintDTO.getId()));
|
||||
if (orderInfo == null) {
|
||||
throw new CzgException("订单信息不存在");
|
||||
|
||||
@@ -4,11 +4,14 @@ import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.czg.account.entity.PrintMachine;
|
||||
import com.czg.market.service.OrderInfoService;
|
||||
import com.czg.order.entity.OrderInfo;
|
||||
import com.czg.order.entity.PrintMachineLog;
|
||||
import com.czg.order.service.PrintMachineLogService;
|
||||
import com.czg.service.RedisService;
|
||||
import com.czg.service.order.mapper.PrintMachineLogMapper;
|
||||
import com.czg.service.order.print.FeiPrinter;
|
||||
import com.czg.service.order.print.YxyPrinter;
|
||||
@@ -20,6 +23,7 @@ import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -47,6 +51,8 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
@Lazy
|
||||
@Resource
|
||||
private FeiPrinter feiPrinter;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
Map<Integer, String> yxxStatusMap = Map.of(
|
||||
0, "离线(设备上线后自动补打)",
|
||||
@@ -55,9 +61,19 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
3, "未激活",
|
||||
4, "设备已禁用");
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void save(PrintMachine config, String bizType, String printContent, String respJson) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
save(null, config, bizType, printContent, respJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存打印记录
|
||||
*
|
||||
* @param orderId 订单Id
|
||||
* @param config 打印机配置
|
||||
* @param bizType 业务类型
|
||||
* @param printContent 打印内容
|
||||
@@ -65,7 +81,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
*/
|
||||
@Async
|
||||
@Override
|
||||
public void save(PrintMachine config, String bizType, String printContent, String respJson) {
|
||||
public void save(Long orderId, PrintMachine config, String bizType, String printContent, String respJson) {
|
||||
if (config == null) {
|
||||
return;
|
||||
}
|
||||
@@ -118,7 +134,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
entity.setRespCode(respCode);
|
||||
entity.setRespMsg(respMsg);
|
||||
super.save(entity);
|
||||
ThreadUtil.execAsync(() -> checkPrintStatus(config, entity));
|
||||
ThreadUtil.execAsync(() -> checkPrintStatus(orderId, config, entity));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,10 +149,11 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
/**
|
||||
* 打印机状态查询(解决 retryFuture 爆红问题 + 虚拟线程 + 轮询重试)
|
||||
*
|
||||
* @param config 打印机配置
|
||||
* @param entity 打印日志实体
|
||||
* @param orderId 订单Id
|
||||
* @param config 打印机配置
|
||||
* @param entity 打印日志实体
|
||||
*/
|
||||
public void checkPrintStatus(PrintMachine config, PrintMachineLog entity) {
|
||||
public void checkPrintStatus(Long orderId, PrintMachine config, PrintMachineLog entity) {
|
||||
// 最大重试次数
|
||||
int maxRetryTimes = 5;
|
||||
AtomicInteger executedTimes = new AtomicInteger(0);
|
||||
@@ -188,7 +205,7 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
entity.setRespMsg(StrUtil.concat(true, "打印失败,", "_", msg));
|
||||
}
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
log.info("打印类型为其他类型,终止打印状态查询轮询任务");
|
||||
ScheduledFuture<?> future = retryFutureRef.get();
|
||||
if (future != null && !future.isCancelled()) {
|
||||
@@ -230,7 +247,15 @@ public class PrintMachineLogServiceImpl extends ServiceImpl<PrintMachineLogMappe
|
||||
} finally {
|
||||
//仅当是最后一次任务时,才执行更新操作
|
||||
if (isLastTask) {
|
||||
redisService.del("order:print:" + orderId);
|
||||
super.updateById(entity);
|
||||
OrderInfo orderInfo = orderInfoService.getOne(query().select(OrderInfo::getPrintStatus).eq(OrderInfo::getId, orderId));
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", config.getId());
|
||||
jsonObject.put("name", config.getName());
|
||||
jsonObject.put("time", LocalDateTime.now());
|
||||
orderInfo.upPrintStatus(jsonObject, isPrintSuccess);
|
||||
orderInfoService.update(orderInfo, query().eq(OrderInfo::getId, orderId));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user