From de335831d4e301f460ce6c94c9ca83a7c639e012 Mon Sep 17 00:00:00 2001 From: van Date: Tue, 21 Apr 2026 23:37:18 +0800 Subject: [PATCH] 1 --- .../jarvis/config/GoofishAsyncConfig.java | 5 +- .../jarvis/mq/GoofishOrderNotifyConsumer.java | 11 ++-- .../goofish/GoofishOrderChangeLogger.java | 8 +-- .../service/goofish/GoofishOrderPipeline.java | 16 ++--- .../impl/ErpGoofishOrderServiceImpl.java | 2 +- .../service/impl/LogisticsServiceImpl.java | 38 ++++++++---- .../wecom/WxSendGoofishNotifyClient.java | 58 +++++++++++++++++-- 7 files changed, 102 insertions(+), 36 deletions(-) diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/config/GoofishAsyncConfig.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/config/GoofishAsyncConfig.java index fac81bf..13cf916 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/config/GoofishAsyncConfig.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/config/GoofishAsyncConfig.java @@ -12,8 +12,9 @@ public class GoofishAsyncConfig { @Bean("goofishTaskExecutor") public Executor goofishTaskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); - executor.setCorePoolSize(2); - executor.setMaxPoolSize(8); + // 仅用于未配置 RocketMQ 时 HTTP 回调路径的 @Async;过小易在拉单/回调并发时排队拖慢企微通知 + executor.setCorePoolSize(4); + executor.setMaxPoolSize(16); executor.setQueueCapacity(500); executor.setThreadNamePrefix("goofish-"); executor.initialize(); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mq/GoofishOrderNotifyConsumer.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mq/GoofishOrderNotifyConsumer.java index b1e0984..aef9acf 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/mq/GoofishOrderNotifyConsumer.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/mq/GoofishOrderNotifyConsumer.java @@ -3,7 +3,7 @@ package com.ruoyi.jarvis.mq; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.ruoyi.jarvis.dto.GoofishNotifyMessage; -import com.ruoyi.jarvis.service.goofish.GoofishNotifyAsyncFacade; +import com.ruoyi.jarvis.service.goofish.GoofishOrderPipeline; import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; import org.apache.rocketmq.spring.core.RocketMQListener; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -12,7 +12,10 @@ import org.springframework.stereotype.Component; import javax.annotation.Resource; /** - * 闲管家订单推送异步消费(需配置 rocketmq.name-server) + * 闲管家订单推送消费(需配置 rocketmq.name-server)。 + *

+ * 在此线程内同步执行 {@link GoofishOrderPipeline#runFullPipeline},避免再投递 {@code @Async} 线程池造成 + * 「MQ 堆积 + goofishTaskExecutor 排队」的双重延迟;回调 HTTP 已在 {@link com.ruoyi.jarvis.service.impl.ErpGoofishOrderServiceImpl#publishOrProcessNotify} 中快速返回。 */ @Component @ConditionalOnProperty(name = "rocketmq.name-server") @@ -24,7 +27,7 @@ import javax.annotation.Resource; public class GoofishOrderNotifyConsumer implements RocketMQListener { @Resource - private GoofishNotifyAsyncFacade goofishNotifyAsyncFacade; + private GoofishOrderPipeline goofishOrderPipeline; @Override public void onMessage(String message) { @@ -36,6 +39,6 @@ public class GoofishOrderNotifyConsumer implements RocketMQListener { if (body == null) { body = new JSONObject(); } - goofishNotifyAsyncFacade.afterNotify(m.getAppid(), body); + goofishOrderPipeline.runFullPipeline(m.getAppid(), body); } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderChangeLogger.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderChangeLogger.java index 812db18..3ad3999 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderChangeLogger.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderChangeLogger.java @@ -84,10 +84,10 @@ public class GoofishOrderChangeLogger { List orderParts = new ArrayList<>(); if (!Objects.equals(b.orderStatus, a.orderStatus)) { - orderParts.add("order_status " + str(b.orderStatus) + "→" + str(a.orderStatus)); + orderParts.add("订单状态 " + str(b.orderStatus) + "→" + str(a.orderStatus)); } if (!Objects.equals(b.refundStatus, a.refundStatus)) { - orderParts.add("refund_status " + str(b.refundStatus) + "→" + str(a.refundStatus)); + orderParts.add("退款状态 " + str(b.refundStatus) + "→" + str(a.refundStatus)); } if (!orderParts.isEmpty()) { append(afterRow.getId(), afterRow.getAppKey(), afterRow.getOrderNo(), TYPE_ORDER, source, @@ -99,10 +99,10 @@ public class GoofishOrderChangeLogger { logParts.add("平台运单 " + str(b.detailWaybillNo) + "→" + str(a.detailWaybillNo)); } if (!eqStr(b.detailExpressCode, a.detailExpressCode)) { - logParts.add("express_code " + str(b.detailExpressCode) + "→" + str(a.detailExpressCode)); + logParts.add("快递编码 " + str(b.detailExpressCode) + "→" + str(a.detailExpressCode)); } if (!eqStr(b.detailExpressName, a.detailExpressName)) { - logParts.add("express_name " + str(b.detailExpressName) + "→" + str(a.detailExpressName)); + logParts.add("快递名称 " + str(b.detailExpressName) + "→" + str(a.detailExpressName)); } if (!eqStr(b.localWaybillNo, a.localWaybillNo)) { logParts.add("本地运单 " + str(b.localWaybillNo) + "→" + str(a.localWaybillNo)); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderPipeline.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderPipeline.java index 87a0cba..c73fb04 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderPipeline.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/goofish/GoofishOrderPipeline.java @@ -143,15 +143,15 @@ public class GoofishOrderPipeline { if (existingBeforeUpdate == null) { goofishOrderChangeLogger.append(loaded.getId(), loaded.getAppKey(), loaded.getOrderNo(), GoofishOrderChangeLogger.TYPE_ORDER, upsertSource, - "新订单入库 order_status=" + loaded.getOrderStatus() + " refund_status=" + loaded.getRefundStatus()); + "新订单入库,订单状态 " + loaded.getOrderStatus() + ",退款状态 " + loaded.getRefundStatus()); return; } if (!Objects.equals(existingBeforeUpdate.getOrderStatus(), upsertPayload.getOrderStatus()) || !Objects.equals(existingBeforeUpdate.getRefundStatus(), upsertPayload.getRefundStatus())) { goofishOrderChangeLogger.append(loaded.getId(), loaded.getAppKey(), loaded.getOrderNo(), GoofishOrderChangeLogger.TYPE_ORDER, upsertSource, - "order_status " + existingBeforeUpdate.getOrderStatus() + "→" + upsertPayload.getOrderStatus() - + ";refund_status " + existingBeforeUpdate.getRefundStatus() + "→" + upsertPayload.getRefundStatus()); + "订单状态 " + existingBeforeUpdate.getOrderStatus() + "→" + upsertPayload.getOrderStatus() + + ";退款状态 " + existingBeforeUpdate.getRefundStatus() + "→" + upsertPayload.getRefundStatus()); } } @@ -424,7 +424,7 @@ public class GoofishOrderPipeline { if (goofishOrderChangeLogger != null) { goofishOrderChangeLogger.append(row.getId(), row.getAppKey(), row.getOrderNo(), GoofishOrderChangeLogger.TYPE_LOGISTICS, "REDIS_WAYBILL", - "本地运单 " + (prev == null || prev.isEmpty() ? "null" : prev) + "→" + wb.trim()); + "本地运单 " + (prev == null || prev.isEmpty() ? "无" : prev) + "→" + wb.trim()); } } @@ -489,7 +489,7 @@ public class GoofishOrderPipeline { if (goofishOrderChangeLogger != null) { goofishOrderChangeLogger.append(row.getId(), row.getAppKey(), row.getOrderNo(), GoofishOrderChangeLogger.TYPE_SHIP, "AUTO_SHIP", - "发货失败(缺地址) " + (row.getShipError() != null ? row.getShipError() : "")); + "发货失败(缺地址):" + (row.getShipError() != null ? row.getShipError() : "")); } return; } @@ -530,7 +530,7 @@ public class GoofishOrderPipeline { if (goofishOrderChangeLogger != null) { goofishOrderChangeLogger.append(row.getId(), row.getAppKey(), row.getOrderNo(), GoofishOrderChangeLogger.TYPE_SHIP, "AUTO_SHIP", - "发货成功 waybill=" + waybill.trim() + " expressCode=" + expressCode); + "发货成功,运单 " + waybill.trim() + ",快递编码 " + expressCode); } } else { String msg = r != null ? r.getString("msg") : "unknown"; @@ -538,7 +538,7 @@ public class GoofishOrderPipeline { if (goofishOrderChangeLogger != null) { goofishOrderChangeLogger.append(row.getId(), row.getAppKey(), row.getOrderNo(), GoofishOrderChangeLogger.TYPE_SHIP, "AUTO_SHIP", - "发货失败 " + (row.getShipError() != null ? row.getShipError() : msg)); + "发货失败:" + (row.getShipError() != null ? row.getShipError() : msg)); } } } catch (Exception ex) { @@ -546,7 +546,7 @@ public class GoofishOrderPipeline { if (goofishOrderChangeLogger != null) { goofishOrderChangeLogger.append(row.getId(), row.getAppKey(), row.getOrderNo(), GoofishOrderChangeLogger.TYPE_SHIP, "AUTO_SHIP", - "发货异常 " + (row.getShipError() != null ? row.getShipError() : ex.getMessage())); + "发货异常:" + (row.getShipError() != null ? row.getShipError() : ex.getMessage())); } log.warn("闲管家发货异常 orderNo={}", row.getOrderNo(), ex); } diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ErpGoofishOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ErpGoofishOrderServiceImpl.java index 2af4450..fd05b41 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ErpGoofishOrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/ErpGoofishOrderServiceImpl.java @@ -195,7 +195,7 @@ public class ErpGoofishOrderServiceImpl implements IErpGoofishOrderService { } String wb = waybillNo != null ? waybillNo.trim() : ""; String sum = summary != null ? summary : ""; - String msg = "jdOrderId=" + jdOrderId + " waybill=" + wb + ";" + sum; + String msg = "京东订单 " + jdOrderId + ",运单 " + wb + ";" + sum; if (msg.length() > 1000) { msg = msg.substring(0, 999) + "…"; } diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/LogisticsServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/LogisticsServiceImpl.java index 03d1802..423f684 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/LogisticsServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/LogisticsServiceImpl.java @@ -824,20 +824,20 @@ public class LogisticsServiceImpl implements ILogisticsService { // 构建推送消息内容 StringBuilder pushContent = new StringBuilder(); - // 第一行:分销标识(F或PDD) + // 第一行:分销标识(如 F-闲鱼) String distributionMark = order.getDistributionMark() != null ? order.getDistributionMark() : "未知"; pushContent.append(distributionMark).append("\n"); - + String thirdPartyOrderNo = order.getThirdPartyOrderNo(); if (thirdPartyOrderNo != null && !thirdPartyOrderNo.trim().isEmpty()) { - pushContent.append("第三方单号:").append(thirdPartyOrderNo).append("\n"); + pushContent.append("第三方单号:").append(thirdPartyOrderNo.trim()).append("\n"); } - - // 型号 - pushContent.append("型号:").append(order.getModelNumber() != null ? order.getModelNumber() : "无").append("\n"); - // 收货地址 - pushContent.append("收货地址:").append(order.getAddress() != null ? order.getAddress() : "无").append("\n"); - + + String modelStr = order.getModelNumber() != null ? order.getModelNumber() : "无"; + String addressStr = order.getAddress() != null ? order.getAddress() : "无"; + pushContent.append("型号:").append(modelStr).append("\n"); + pushContent.append("收货地址:").append(addressStr).append("\n"); + // 如果物流链接已更新,在推送消息中说明 if (logisticsLinkUpdated && newLogisticsLink != null && !newLogisticsLink.trim().isEmpty()) { pushContent.append("【物流链接已更新】").append("\n"); @@ -847,9 +847,23 @@ public class LogisticsServiceImpl implements ILogisticsService { } pushContent.append("\n"); } - - // 运单号 - pushContent.append("运单号:").append("\n").append("\n").append("\n").append("\n").append(waybillNo).append("\n"); + + // 运单号(首段:冒号后多行留白再写单号,便于复制) + pushContent.append("运单号:").append("\n").append("\n").append("\n").append("\n").append(waybillNo).append("\n\n\n"); + // 闲鱼自动发货段:运单号紧跟在冒号后同一行 + pushContent.append("闲鱼自动发货:").append("\n"); + String goofishOrderNo; + if (thirdPartyOrderNo != null && !thirdPartyOrderNo.trim().isEmpty()) { + goofishOrderNo = thirdPartyOrderNo.trim(); + } else if (order.getOrderId() != null && !order.getOrderId().trim().isEmpty()) { + goofishOrderNo = order.getOrderId().trim(); + } else { + goofishOrderNo = "无"; + } + pushContent.append("单号:").append(goofishOrderNo).append("\n"); + pushContent.append("型号:").append(modelStr).append("\n"); + pushContent.append("收货地址:").append(addressStr).append("\n"); + pushContent.append("运单号:").append(waybillNo).append("\n"); boolean useGoofishWecom = erpGoofishOrderService.hasLinkedGoofishOrder(order.getId()) || (distributionMark != null && distributionMark.contains("闲鱼")); diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java index 38dd212..f5e0c21 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/wecom/WxSendGoofishNotifyClient.java @@ -113,11 +113,15 @@ public class WxSendGoofishNotifyClient { private static String buildContent(String orderNo, String eventType, String source, String message) { StringBuilder sb = new StringBuilder(); sb.append("【闲鱼订单】").append(orderNo != null ? orderNo : "-").append("\n"); - if (StringUtils.hasText(eventType)) { - sb.append(eventType); - } - if (StringUtils.hasText(source)) { - sb.append(" | ").append(source); + String typeLabel = humanEventType(eventType); + String srcLabel = humanSource(source); + if (StringUtils.hasText(typeLabel)) { + sb.append(typeLabel); + if (StringUtils.hasText(srcLabel)) { + sb.append(" · ").append(srcLabel); + } + } else if (StringUtils.hasText(srcLabel)) { + sb.append(srcLabel); } sb.append("\n"); if (StringUtils.hasText(message)) { @@ -130,6 +134,50 @@ public class WxSendGoofishNotifyClient { return s; } + /** 企微展示用,与库内 event_type 枚举一致 */ + private static String humanEventType(String eventType) { + if (!StringUtils.hasText(eventType)) { + return ""; + } + switch (eventType.trim()) { + case "ORDER_SYNC": + return "订单同步"; + case "LOGISTICS_SYNC": + return "物流同步"; + case "SHIP": + return "发货"; + default: + return eventType.trim(); + } + } + + /** 企微展示用,与库内 source 一致 */ + private static String humanSource(String source) { + if (!StringUtils.hasText(source)) { + return ""; + } + switch (source.trim()) { + case "LIST_UPSERT": + return "列表拉单写入"; + case "NOTIFY_UPSERT": + return "推送回调写入"; + case "LIST": + return "列表摘要"; + case "DETAIL_REFRESH": + return "详情刷新"; + case "NOTIFY": + return "推送"; + case "REDIS_WAYBILL": + return "Redis 运单"; + case "AUTO_SHIP": + return "自动发货"; + case "JD_LOGISTICS_PUSH": + return "京东物流扫描"; + default: + return source.trim(); + } + } + /** * 逗号或 | 分隔的 UserID → 企微 API 要求的 user1|user2 */