1
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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)。
|
||||
* <p>
|
||||
* 在此线程内同步执行 {@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<String> {
|
||||
|
||||
@Resource
|
||||
private GoofishNotifyAsyncFacade goofishNotifyAsyncFacade;
|
||||
private GoofishOrderPipeline goofishOrderPipeline;
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
@@ -36,6 +39,6 @@ public class GoofishOrderNotifyConsumer implements RocketMQListener<String> {
|
||||
if (body == null) {
|
||||
body = new JSONObject();
|
||||
}
|
||||
goofishNotifyAsyncFacade.afterNotify(m.getAppid(), body);
|
||||
goofishOrderPipeline.runFullPipeline(m.getAppid(), body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,10 +84,10 @@ public class GoofishOrderChangeLogger {
|
||||
|
||||
List<String> 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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) + "…";
|
||||
}
|
||||
|
||||
@@ -824,19 +824,19 @@ 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()) {
|
||||
@@ -848,8 +848,22 @@ 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("闲鱼"));
|
||||
|
||||
@@ -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);
|
||||
String typeLabel = humanEventType(eventType);
|
||||
String srcLabel = humanSource(source);
|
||||
if (StringUtils.hasText(typeLabel)) {
|
||||
sb.append(typeLabel);
|
||||
if (StringUtils.hasText(srcLabel)) {
|
||||
sb.append(" · ").append(srcLabel);
|
||||
}
|
||||
if (StringUtils.hasText(source)) {
|
||||
sb.append(" | ").append(source);
|
||||
} 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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user