From 4c80b3e53fefeec6cddd240ae25bd416987fddf6 Mon Sep 17 00:00:00 2001
From: jieyuu <645634619@qq.com>
Date: Mon, 23 Sep 2024 21:53:49 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E8=AE=A2=E5=8D=95=E6=B6=88?=
=?UTF-8?q?=E6=81=AF=E5=85=B3=E5=8D=95=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/net/jieyuu/model/OrderMessage.java | 18 ++++++
.../net/jieyuu/mapper/ProductOrderMapper.java | 4 +-
.../net/jieyuu/mq/ProductOrderMQListener.java | 50 +++++++++++++++++
.../jieyuu/service/ProductOrderService.java | 8 +++
.../service/impl/ProductOrderServiceImpl.java | 56 ++++++++++++++++---
.../resources/mapper/ProductOrderMapper.xml | 40 ++++++++-----
.../test/java/biz/DemoApplicationTests.java | 6 +-
7 files changed, 156 insertions(+), 26 deletions(-)
create mode 100644 xdclass-common/src/main/java/net/jieyuu/model/OrderMessage.java
create mode 100644 xdclass-order-service/src/main/java/net/jieyuu/mq/ProductOrderMQListener.java
diff --git a/xdclass-common/src/main/java/net/jieyuu/model/OrderMessage.java b/xdclass-common/src/main/java/net/jieyuu/model/OrderMessage.java
new file mode 100644
index 0000000..827974c
--- /dev/null
+++ b/xdclass-common/src/main/java/net/jieyuu/model/OrderMessage.java
@@ -0,0 +1,18 @@
+package net.jieyuu.model;
+
+
+import lombok.Data;
+
+@Data
+public class OrderMessage {
+ /**
+ * 消息id
+ */
+ private Long messageId;
+
+ /**
+ * 订单号
+ */
+ private String outTradeNo;
+
+}
diff --git a/xdclass-order-service/src/main/java/net/jieyuu/mapper/ProductOrderMapper.java b/xdclass-order-service/src/main/java/net/jieyuu/mapper/ProductOrderMapper.java
index 3874ff0..384d740 100644
--- a/xdclass-order-service/src/main/java/net/jieyuu/mapper/ProductOrderMapper.java
+++ b/xdclass-order-service/src/main/java/net/jieyuu/mapper/ProductOrderMapper.java
@@ -2,10 +2,11 @@ package net.jieyuu.mapper;
import net.jieyuu.model.ProductOrderDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
/**
*
- * Mapper 接口
+ * Mapper 接口
*
*
* @author jieyuu
@@ -13,4 +14,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface ProductOrderMapper extends BaseMapper {
+ void updateOrderPayState(@Param("outTradeNo") String outTradeNo, @Param("newState") String newState, @Param("oldState") String oldState);
}
diff --git a/xdclass-order-service/src/main/java/net/jieyuu/mq/ProductOrderMQListener.java b/xdclass-order-service/src/main/java/net/jieyuu/mq/ProductOrderMQListener.java
new file mode 100644
index 0000000..31dd6ba
--- /dev/null
+++ b/xdclass-order-service/src/main/java/net/jieyuu/mq/ProductOrderMQListener.java
@@ -0,0 +1,50 @@
+package net.jieyuu.mq;
+
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import net.jieyuu.model.OrderMessage;
+import net.jieyuu.service.ProductOrderService;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.RabbitHandler;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+
+
+@Slf4j
+@Component
+@RabbitListener(queues = "${mqconfig.order_close_queue}")
+public class ProductOrderMQListener {
+
+
+ @Autowired
+ private ProductOrderService productOrderService;
+
+ /**
+ * 消息重复消费,幂等性保障
+ *
+ * @param orderMessage
+ * @param message
+ * @param channel
+ * @throws IOException
+ */
+ @RabbitHandler
+ public void closeProductOrder(OrderMessage orderMessage, Message message, Channel channel) throws IOException {
+ log.info("监听到消息:closeProductOrder:{} ", orderMessage);
+ long msgTag = message.getMessageProperties().getDeliveryTag();
+
+ try {
+ boolean flag = productOrderService.closeProductOrder(orderMessage);
+ if (flag) {// 关单成功
+ channel.basicAck(msgTag, false);
+ } else {// 失败
+ channel.basicAck(msgTag, true);// 重新入队
+ }
+ } catch (IOException e) {
+ log.error("定时关单失败:{}", orderMessage);
+ channel.basicReject(msgTag, true);
+ }
+ }
+}
diff --git a/xdclass-order-service/src/main/java/net/jieyuu/service/ProductOrderService.java b/xdclass-order-service/src/main/java/net/jieyuu/service/ProductOrderService.java
index 1f8e492..a5032e7 100644
--- a/xdclass-order-service/src/main/java/net/jieyuu/service/ProductOrderService.java
+++ b/xdclass-order-service/src/main/java/net/jieyuu/service/ProductOrderService.java
@@ -1,5 +1,6 @@
package net.jieyuu.service;
+import net.jieyuu.model.OrderMessage;
import net.jieyuu.model.ProductOrderDO;
import com.baomidou.mybatisplus.extension.service.IService;
import net.jieyuu.request.ConfirmOrderRequest;
@@ -31,4 +32,11 @@ public interface ProductOrderService extends IService {
* @return
*/
String queryProductOrderState(String outTradeNo);
+
+ /**
+ * 队列监听定时关单接口
+ *
+ * @param orderMessage
+ */
+ boolean closeProductOrder(OrderMessage orderMessage);
}
diff --git a/xdclass-order-service/src/main/java/net/jieyuu/service/impl/ProductOrderServiceImpl.java b/xdclass-order-service/src/main/java/net/jieyuu/service/impl/ProductOrderServiceImpl.java
index 61191ed..8bcc926 100644
--- a/xdclass-order-service/src/main/java/net/jieyuu/service/impl/ProductOrderServiceImpl.java
+++ b/xdclass-order-service/src/main/java/net/jieyuu/service/impl/ProductOrderServiceImpl.java
@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
+import net.jieyuu.config.RabbitMQConfig;
import net.jieyuu.enums.*;
import net.jieyuu.exception.BizException;
import net.jieyuu.feign.CouponFeignService;
@@ -11,11 +12,8 @@ import net.jieyuu.feign.ProductFeignService;
import net.jieyuu.feign.UserFeignService;
import net.jieyuu.interceptor.LoginInterceptor;
import net.jieyuu.mapper.ProductOrderItemMapper;
-import net.jieyuu.model.LoginUser;
-import net.jieyuu.model.OrderItemVO;
-import net.jieyuu.model.ProductOrderDO;
+import net.jieyuu.model.*;
import net.jieyuu.mapper.ProductOrderMapper;
-import net.jieyuu.model.ProductOrderItemDO;
import net.jieyuu.request.ConfirmOrderRequest;
import net.jieyuu.request.LockCouponRecordRequest;
import net.jieyuu.request.LockProductRequest;
@@ -26,6 +24,8 @@ import net.jieyuu.utils.CommonUtil;
import net.jieyuu.utils.JsonData;
import net.jieyuu.vo.CouponRecordVO;
import net.jieyuu.vo.ProductOrderAddressVO;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -62,6 +62,12 @@ public class ProductOrderServiceImpl extends ServiceImpl orderItemList) {
+ private void saveProductOrderItems(String orderOutTradeNo, Long orderId, List orderItemList) {
List orderItemDOList = orderItemList.stream().map(obj -> {
ProductOrderItemDO itemDO = new ProductOrderItemDO();
@@ -361,4 +372,35 @@ public class ProductOrderServiceImpl extends ServiceImpl().eq("out_trade_no", orderMessage.getOutTradeNo()));
+
+ if (productOrderDO == null) {
+ log.warn("直接确认消息,订单不存在:{}", orderMessage);
+ return true;
+ }
+
+ if (productOrderDO.getState().equalsIgnoreCase(ProductOrderStateEnum.PAY.name())) {// 成功消费
+ log.info("直接确认消息,订单支付成功:{}", orderMessage);
+ return true;
+ }
+ // 向第三方支付查询支付情况 todo
+
+
+
+ String payResult = "";
+ // 订单结果为空,支付不成功,取消订单
+ if (StringUtils.isBlank(payResult)) {
+ productOrderMapper.updateOrderPayState(orderMessage.getOutTradeNo(), ProductOrderStateEnum.CANCEL.name(), ProductOrderStateEnum.NEW.name());
+ log.info("结果为空,则未支付成功,本地取消订单:{}", orderMessage);
+ return true;
+ } else {
+ // 将订单状态改为已经支付
+ log.warn("支付成功,主动修改订单状态为已支付,造成该元婴的情况可能是支付通道回调有问题:{}", orderMessage);
+ productOrderMapper.updateOrderPayState(orderMessage.getOutTradeNo(), ProductOrderStateEnum.PAY.name(), ProductOrderStateEnum.NEW.name());
+ return true;
+ }
+ }
}
diff --git a/xdclass-order-service/src/main/resources/mapper/ProductOrderMapper.xml b/xdclass-order-service/src/main/resources/mapper/ProductOrderMapper.xml
index 09180ff..f97f11a 100644
--- a/xdclass-order-service/src/main/resources/mapper/ProductOrderMapper.xml
+++ b/xdclass-order-service/src/main/resources/mapper/ProductOrderMapper.xml
@@ -4,25 +4,35 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- id, out_trade_no, state, create_time, total_amount, pay_amount, pay_type, nickname, head_img, user_id, del, update_time, order_type, receiver_address
+ id
+ , out_trade_no, state, create_time, total_amount, pay_amount, pay_type, nickname, head_img, user_id, del, update_time, order_type, receiver_address
+
+
+
+ update product_order
+ set `state` = #{newState}
+ where out_trade_no = #{outTradeNo}
+ and `state` = #{oldState}
+
+
diff --git a/xdclass-order-service/src/test/java/biz/DemoApplicationTests.java b/xdclass-order-service/src/test/java/biz/DemoApplicationTests.java
index d513fa9..c892610 100644
--- a/xdclass-order-service/src/test/java/biz/DemoApplicationTests.java
+++ b/xdclass-order-service/src/test/java/biz/DemoApplicationTests.java
@@ -3,6 +3,7 @@ package biz;
import lombok.extern.slf4j.Slf4j;
import net.jieyuu.OrderApplication;
import net.jieyuu.model.CouponRecordMessage;
+import net.jieyuu.model.OrderMessage;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
@@ -21,14 +22,13 @@ public class DemoApplicationTests {
@Test
public void send() {
rabbitTemplate.convertAndSend("order.event.exchange", "order.close.delay.routing.key", "this is a new order");
-
}
@Test
public void testCouponRecordRelease() {
- CouponRecordMessage message = new CouponRecordMessage();
+ OrderMessage message = new OrderMessage();
message.setOutTradeNo("123456abc");
- message.setTaskId(1l);
+ message.setMessageId(1l);
rabbitTemplate.convertAndSend("order.event.exchange", "order.close.delay.routing.key", message);
}