diff --git a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/listener/BuySuccessListener.java b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/listener/BuySuccessListener.java index 94ef599d..aa31be3f 100644 --- a/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/listener/BuySuccessListener.java +++ b/rc-service/rc-service-order/order-application/src/main/java/com/red/circle/order/app/listener/BuySuccessListener.java @@ -12,6 +12,7 @@ import com.red.circle.component.mq.config.RocketMqMessageListener; import com.red.circle.component.mq.service.Action; import com.red.circle.component.mq.service.ConsumerMessage; import com.red.circle.component.mq.service.MessageListener; +import com.red.circle.component.redis.service.RedisService; import com.red.circle.framework.dto.ResultResponse; import com.red.circle.mq.business.model.event.pay.BuySuccessEvent; import com.red.circle.mq.business.model.event.pay.PurchaseProductEvent; @@ -40,8 +41,11 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.time.Duration; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -64,6 +68,7 @@ public class BuySuccessListener implements MessageListener { private final MessageEventProcess messageEventProcess; private final UserOneTimeTaskClient userOneTimeTaskClient; private final CumulativeRechargeClient cumulativeRechargeClient; + private final RedisService redisService; @Override public Action consume(ConsumerMessage message) { @@ -97,7 +102,24 @@ public class BuySuccessListener implements MessageListener { } private void execute(BuySuccessEvent eventBody) { - if (!ArithmeticUtils.gt(eventBody.getCandyQuantity(), BigDecimal.ZERO) + // 防止短时间内重复处理同一订单 + String idempotentKey = "buy_success_idempotent:" + eventBody.getPurchaseHistoryId(); + if (!redisService.setIfAbsent(idempotentKey, "1", 1, TimeUnit.DAYS)) { + String duplicateKey = "buy_success_duplicate:" + eventBody.getPurchaseHistoryId(); + String duplicateInfo = String.format("purchaseHistoryId=%s, userId=%s, candyQuantity=%s, time=%s", + eventBody.getPurchaseHistoryId(), + eventBody.getUserId(), + eventBody.getCandyQuantity(), + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + redisService.listPush(duplicateKey, duplicateInfo); + redisService.expire(duplicateKey, 1, TimeUnit.DAYS); + + log.error("⚠️ [购买成功] 重复消费 - {}", duplicateInfo); + return; + } + + if (!ArithmeticUtils.gt(eventBody.getCandyQuantity(), BigDecimal.ZERO) || Objects.equals(eventBody.getTrialPeriod(), Boolean.TRUE)) { return; }