This commit is contained in:
Leo
2025-12-06 17:08:38 +08:00
parent eb53915bcd
commit 632b9f7eb1

View File

@@ -14,6 +14,8 @@ import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
@@ -127,6 +129,43 @@ public class LogisticsServiceImpl implements ILogisticsService {
logger.info("检测到waybill_no: {} - 订单ID: {}", waybillNo, orderId);
// 兼容处理检查Redis中是否已有该订单的运单号记录
// 如果存在且运单号一致,说明之前已经推送过了(可能是之前没有配置接收人但推送成功的情况)
String redisKey = REDIS_WAYBILL_KEY_PREFIX + orderId;
String existingWaybillNo = stringRedisTemplate.opsForValue().get(redisKey);
if (existingWaybillNo != null && existingWaybillNo.trim().equals(waybillNo.trim())) {
// 运单号一致,说明之前已经推送过了,直接标记为已处理,跳过推送
logger.info("订单运单号已存在且一致,说明之前已推送过,跳过重复推送 - 订单ID: {}, waybill_no: {}", orderId, waybillNo);
// 更新过期时间,确保记录不会过期
stringRedisTemplate.opsForValue().set(redisKey, waybillNo, 30, TimeUnit.DAYS);
return true;
}
// 兼容处理如果Redis中没有记录但订单创建时间在30天之前且获取到了运单号
// 说明可能是之前推送过但没标记的情况(比如之前没有配置接收人但推送成功,响应解析失败)
// 这种情况下,直接标记为已处理,跳过推送,避免重复推送旧订单
if (existingWaybillNo == null && order.getCreateTime() != null) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -30); // 30天前
Date thresholdDate = calendar.getTime();
if (order.getCreateTime().before(thresholdDate)) {
// 订单创建时间在30天之前且Redis中没有记录但获取到了运单号
// 视为之前已推送过但未标记,直接标记为已处理,跳过推送
logger.info("订单创建时间较早({}且Redis中无记录但已获取到运单号视为之前已推送过直接标记为已处理跳过推送 - 订单ID: {}, waybill_no: {}",
order.getCreateTime(), orderId, waybillNo);
stringRedisTemplate.opsForValue().set(redisKey, waybillNo, 30, TimeUnit.DAYS);
return true;
}
}
// 如果Redis中有记录但运单号不一致记录警告
if (existingWaybillNo != null && !existingWaybillNo.trim().equals(waybillNo.trim())) {
logger.warn("订单运单号发生变化 - 订单ID: {}, 旧运单号: {}, 新运单号: {}, 将重新推送",
orderId, existingWaybillNo, waybillNo);
}
// 调用企业应用推送,只有推送成功才记录状态
boolean pushSuccess = sendEnterprisePushNotification(order, waybillNo);
if (!pushSuccess) {
@@ -135,12 +174,13 @@ public class LogisticsServiceImpl implements ILogisticsService {
}
// 保存运单号到Redis避免重复处理- 使用原子操作确保只写入一次
String redisKey = REDIS_WAYBILL_KEY_PREFIX + orderId;
Boolean setSuccess = stringRedisTemplate.opsForValue().setIfAbsent(redisKey, waybillNo, 30, TimeUnit.DAYS);
if (Boolean.FALSE.equals(setSuccess)) {
// 如果Redis中已存在说明可能被其他线程处理了记录警告但不算失败
logger.warn("订单运单号已存在(可能被并发处理),但推送已成功 - 订单ID: {}, waybill_no: {}", orderId, waybillNo);
// 更新过期时间,确保记录不会过期
stringRedisTemplate.opsForValue().set(redisKey, waybillNo, 30, TimeUnit.DAYS);
}
logger.info("物流信息获取并推送成功 - 订单ID: {}, waybill_no: {}", orderId, waybillNo);