fix(wxpay): 修复 Kafka 生产者空指针异常

- 添加对 profitShareKafkaProducer 的空值检查
- 在发送消息前确保 Kafka 生产者已注入
- 使用 CompletableFuture 处理异步退款消息发送
- 设置 Kafka 生产者的注入模式为 required=false
- 避免因 Kafka 生产者缺失导致的服务启动失败
This commit is contained in:
2025-12-17 15:52:41 +08:00
parent 00890c764e
commit 6cd47649fc

View File

@@ -31,10 +31,12 @@ import com.ycwl.basic.repository.OrderRepository;
import com.ycwl.basic.service.mobile.WxPayService; import com.ycwl.basic.service.mobile.WxPayService;
import com.ycwl.basic.service.pc.ScenicService; import com.ycwl.basic.service.pc.ScenicService;
import com.ycwl.basic.utils.SnowFlakeUtil; import com.ycwl.basic.utils.SnowFlakeUtil;
import io.netty.util.concurrent.CompleteFuture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@@ -42,6 +44,7 @@ import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture;
/** /**
* @Author: songmingsong * @Author: songmingsong
@@ -74,7 +77,7 @@ public class WxPayServiceImpl implements WxPayService {
@Autowired @Autowired
@Lazy @Lazy
private RedisTemplate<String, String> redisTemplate; private RedisTemplate<String, String> redisTemplate;
@Autowired @Autowired(required = false)
private ProfitShareKafkaProducer profitShareKafkaProducer; private ProfitShareKafkaProducer profitShareKafkaProducer;
@Override @Override
@@ -126,6 +129,7 @@ public class WxPayServiceImpl implements WxPayService {
invalidateStatisticsCache(scenicId); invalidateStatisticsCache(scenicId);
} }
}); });
if (profitShareKafkaProducer != null) {
profitShareKafkaProducer.sendProfitShareMessage(OrderMessage.builder() profitShareKafkaProducer.sendProfitShareMessage(OrderMessage.builder()
.orderId(callbackResponse.getOrderNo()) .orderId(callbackResponse.getOrderNo())
.scenicId(scenicId) .scenicId(scenicId)
@@ -135,6 +139,7 @@ public class WxPayServiceImpl implements WxPayService {
.timestamp(System.currentTimeMillis() / 1000) .timestamp(System.currentTimeMillis() / 1000)
.build() .build()
); );
}
} catch (Exception e) { } catch (Exception e) {
throw new AppException(BizCodeEnum.ADVANCE_PAYMENT_CALLBACK_FAILED, e.toString()); throw new AppException(BizCodeEnum.ADVANCE_PAYMENT_CALLBACK_FAILED, e.toString());
} }
@@ -157,7 +162,9 @@ public class WxPayServiceImpl implements WxPayService {
IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(order.getScenicId()); IPayAdapter scenicPayAdapter = scenicService.getScenicPayAdapter(order.getScenicId());
BigDecimal payPrice = order.getPayPrice(); BigDecimal payPrice = order.getPayPrice();
int priceInCents = payPrice.multiply(new BigDecimal(NumberConstant.HUNDRED)).intValue(); // 转换为分(int) int priceInCents = payPrice.multiply(new BigDecimal(NumberConstant.HUNDRED)).intValue(); // 转换为分(int)
profitShareKafkaProducer.sendRefundMessage(RefundMessage.builder() CompletableFuture<SendResult<String, String>> future;
if (profitShareKafkaProducer != null) {
future = profitShareKafkaProducer.sendRefundMessage(RefundMessage.builder()
.refundOrderId(String.valueOf(order.getId())) .refundOrderId(String.valueOf(order.getId()))
.originalOrderId(String.valueOf(order.getId())) .originalOrderId(String.valueOf(order.getId()))
.refundAmount(payPrice.doubleValue()) .refundAmount(payPrice.doubleValue())
@@ -165,7 +172,11 @@ public class WxPayServiceImpl implements WxPayService {
.paymentSystem("wechat") .paymentSystem("wechat")
.timestamp(System.currentTimeMillis() / 1000) .timestamp(System.currentTimeMillis() / 1000)
.build() .build()
).whenComplete((result, throwable) -> { );
} else {
future = CompletableFuture.completedFuture(null);
}
future.whenComplete((result, throwable) -> {
RefundOrderRequest request = new RefundOrderRequest() RefundOrderRequest request = new RefundOrderRequest()
.setOrderNo(orderId) .setOrderNo(orderId)
.setPrice(priceInCents) .setPrice(priceInCents)