From 61dedee5f412d8a29f5e3030216c67d4d89f98e3 Mon Sep 17 00:00:00 2001
From: Helius <wangdoubleone@gmail.com>
Date: Sat, 25 Sep 2021 18:45:21 +0800
Subject: [PATCH] fix order auto cancel rabbit

---
 src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java             |   24 ++++++++
 src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java              |   43 +++++++++++++-
 src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java                 |   14 ++++
 src/test/java/cc/mrbird/febs/AgentTest.java                                     |    2 
 src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java         |    2 
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java |   19 ++++++
 src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java                |   16 +++++
 src/main/java/cc/mrbird/febs/common/listener/RedisKeyExpirationListener.java    |   44 +++++++-------
 8 files changed, 137 insertions(+), 27 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java b/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
index 96a523b..cdca235 100644
--- a/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
+++ b/src/main/java/cc/mrbird/febs/common/configure/RabbitConfigure.java
@@ -3,10 +3,8 @@
 import cc.mrbird.febs.rabbit.constants.ExchangeConstants;
 import cc.mrbird.febs.rabbit.constants.QueueConstants;
 import cc.mrbird.febs.rabbit.constants.RouteKeyConstants;
-import org.springframework.amqp.core.Binding;
-import org.springframework.amqp.core.BindingBuilder;
-import org.springframework.amqp.core.DirectExchange;
-import org.springframework.amqp.core.Queue;
+import cc.mrbird.febs.rabbit.enumerates.RabbitQueueEnum;
+import org.springframework.amqp.core.*;
 import org.springframework.amqp.rabbit.connection.ConnectionFactory;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@@ -47,4 +45,41 @@
     public Binding defaultBind() {
         return BindingBuilder.bind(defaultQueue()).to(defaultExchange()).with(RouteKeyConstants.ROUTE_KEY_DEFAULT);
     }
+
+    @Bean
+    public DirectExchange delayTtlExchange() {
+        return new DirectExchange(RabbitQueueEnum.ORDER_CANCEL_DELAY_TTL.getExchange());
+    }
+
+    @Bean
+    public DirectExchange orderDelayExchange() {
+        return new DirectExchange(RabbitQueueEnum.ORDER_CANCEL_DELAY.getExchange());
+    }
+
+    @Bean
+    public Queue orderDelayQueue() {
+        return new Queue(RabbitQueueEnum.ORDER_CANCEL_DELAY.getQueue());
+    }
+
+    @Bean
+    public Queue orderDelayQueueTtl() {
+        return QueueBuilder.durable(RabbitQueueEnum.ORDER_CANCEL_DELAY_TTL.getQueue())
+                //到期后转发的交换机
+                .withArgument("x-dead-letter-exchange", RabbitQueueEnum.ORDER_CANCEL_DELAY.getExchange())
+                //到期后转发的路由键
+                .withArgument("x-dead-letter-routing-key", RabbitQueueEnum.ORDER_CANCEL_DELAY.getRoute())
+                .build();
+    }
+
+    @Bean
+    public Binding orderDelayBind() {
+        return BindingBuilder.bind(orderDelayQueue()).to(orderDelayExchange()).with(RabbitQueueEnum.ORDER_CANCEL_DELAY.getRoute());
+    }
+
+    @Bean
+    public Binding orderDelayBindTtl() {
+        return BindingBuilder.bind(orderDelayQueueTtl()).to(delayTtlExchange()).with(RabbitQueueEnum.ORDER_CANCEL_DELAY_TTL.getRoute());
+    }
+
+
 }
diff --git a/src/main/java/cc/mrbird/febs/common/listener/RedisKeyExpirationListener.java b/src/main/java/cc/mrbird/febs/common/listener/RedisKeyExpirationListener.java
index 737c005..612cfb2 100644
--- a/src/main/java/cc/mrbird/febs/common/listener/RedisKeyExpirationListener.java
+++ b/src/main/java/cc/mrbird/febs/common/listener/RedisKeyExpirationListener.java
@@ -32,27 +32,27 @@
 
     @Override
     public void onMessage(Message message, byte[] pattern) {
-        String expireKey = message.toString();
-        if (expireKey.startsWith(AppContants.REDIS_ORDER_OVERTIME_PREFIX)) {
-            List<String> split = StrUtil.split(expireKey, '_');
-            if (split.size() < 4) {
-                log.error("自动取消订单失效:{}", expireKey);
-                return;
-            }
-            Long memberId = Long.valueOf(split.get(2));
-            Long orderId = Long.valueOf(split.get(3));
-
-            MallOrderInfo orderInfo = mallOrderInfoMapper.selectOrderByMemberIdAndId(memberId, orderId);
-            if (orderInfo == null) {
-                log.error("自动取消订单参数错误:{}", expireKey);
-                return;
-            }
-            if (orderInfo.getStatus() == OrderStatusEnum.WAIT_PAY.getValue()) {
-                log.info("自动取消订单:{},{}", memberId, orderId);
-                orderInfo.setStatus(OrderStatusEnum.CANCEL.getValue());
-                orderInfo.setCancelType(MallOrderInfo.CANCEL_OVERTIME_NO_PAY);
-                mallOrderInfoMapper.updateById(orderInfo);
-            }
-        }
+//        String expireKey = message.toString();
+//        if (expireKey.startsWith(AppContants.REDIS_ORDER_OVERTIME_PREFIX)) {
+//            List<String> split = StrUtil.split(expireKey, '_');
+//            if (split.size() < 4) {
+//                log.error("自动取消订单失效:{}", expireKey);
+//                return;
+//            }
+//            Long memberId = Long.valueOf(split.get(2));
+//            Long orderId = Long.valueOf(split.get(3));
+//
+//            MallOrderInfo orderInfo = mallOrderInfoMapper.selectOrderByMemberIdAndId(memberId, orderId);
+//            if (orderInfo == null) {
+//                log.error("自动取消订单参数错误:{}", expireKey);
+//                return;
+//            }
+//            if (orderInfo.getStatus() == OrderStatusEnum.WAIT_PAY.getValue()) {
+//                log.info("自动取消订单:{},{}", memberId, orderId);
+//                orderInfo.setStatus(OrderStatusEnum.CANCEL.getValue());
+//                orderInfo.setCancelType(MallOrderInfo.CANCEL_OVERTIME_NO_PAY);
+//                mallOrderInfoMapper.updateById(orderInfo);
+//            }
+//        }
     }
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java b/src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java
index 8c343f1..3fb971d 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IApiMallOrderInfoService.java
@@ -28,4 +28,6 @@
     void applyRefund(AddRefundDto addRefundDto);
 
     void refundExpress(RefundExpressDto refundExpressDto);
+
+    void autoCancelOrder(Long id);
 }
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
index 7ae82f7..0df5d0f 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
@@ -20,6 +20,7 @@
 import cc.mrbird.febs.mall.vo.OrderDetailVo;
 import cc.mrbird.febs.mall.vo.OrderListVo;
 import cc.mrbird.febs.mall.vo.OrderRefundVo;
+import cc.mrbird.febs.rabbit.producter.AgentProducer;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUnit;
 import cn.hutool.core.date.DateUtil;
@@ -58,6 +59,8 @@
     private final MallShoppingCartMapper mallShoppingCartMapper;
     private final IApiMallMemberService memberService;
     private final RedisUtils redisUtils;
+
+    private final AgentProducer agentProducer;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -129,6 +132,7 @@
         String redisKey = StrUtil.format(AppContants.REDIS_ORDER_OVERTIME, member.getId(), orderInfo.getId());
         redisUtils.set(redisKey, orderInfo.getId(), 900);
 
+        agentProducer.sendOrderCancelDelayMsg(orderInfo.getId(), 15 * 60 * 1000L);
         return orderInfo.getId();
     }
 
@@ -359,4 +363,19 @@
         operation.setContent(StrUtil.format("用户:{}提交物流信息,快递公司:{},单号:{}", member.getName(), refundExpressDto.getExpressCom(), refundExpressDto.getExpressNo()));
         mallOrderRefundOperationMapper.insert(operation);
     }
+
+    @Override
+    public void autoCancelOrder(Long id) {
+        MallOrderInfo orderInfo = this.baseMapper.selectById(id);
+        if (orderInfo == null) {
+            log.error("自动取消订单参数错误:{}", id);
+            return;
+        }
+        if (orderInfo.getStatus() == OrderStatusEnum.WAIT_PAY.getValue()) {
+            log.info("自动取消订单:{},{}", orderInfo.getMemberId(), id);
+            orderInfo.setStatus(OrderStatusEnum.CANCEL.getValue());
+            orderInfo.setCancelType(MallOrderInfo.CANCEL_OVERTIME_NO_PAY);
+            this.baseMapper.updateById(orderInfo);
+        }
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java b/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
index 79f201f..c4d5a29 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/consumer/AgentConsumer.java
@@ -1,11 +1,16 @@
 package cc.mrbird.febs.rabbit.consumer;
 
+import cc.mrbird.febs.mall.service.IApiMallOrderInfoService;
 import cc.mrbird.febs.rabbit.constants.QueueConstants;
+import cc.mrbird.febs.rabbit.enumerates.RabbitQueueEnum;
 import com.rabbitmq.client.Channel;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.core.Message;
 import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+
+import java.util.Date;
 
 /**
  * @author wzy
@@ -15,8 +20,17 @@
 @Component
 public class AgentConsumer {
 
+    @Autowired
+    private IApiMallOrderInfoService orderInfoService;
+
     @RabbitListener(queues = QueueConstants.QUEUE_DEFAULT)
     public void agentReturn(Message message, Channel channel) {
         log.info("消费者:{}", new String(message.getBody()));
     }
+
+    @RabbitListener(queues = "queue_order_delay")
+    public void orderCancelDelay(String id) {
+        log.info("订单超时支付自动取消:{}", id);
+        orderInfoService.autoCancelOrder(Long.parseLong(id));
+    }
 }
diff --git a/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java b/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
new file mode 100644
index 0000000..b6cd963
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/rabbit/enumerates/RabbitQueueEnum.java
@@ -0,0 +1,24 @@
+package cc.mrbird.febs.rabbit.enumerates;
+
+import lombok.Getter;
+
+@Getter
+public enum RabbitQueueEnum {
+
+    DEFAULT("exchange_default", "route_key_default", "queue_default"),
+
+    ORDER_CANCEL_DELAY_TTL("exchange_order_delay_ttl", "route_key_order_delay_ttl", "queue_order_delay_ttl"),
+    ORDER_CANCEL_DELAY("exchange_order_delay", "route_key_order_delay", "queue_order_delay");
+
+    private String exchange;
+
+    private String route;
+
+    private String queue;
+
+    RabbitQueueEnum(String exchange, String route, String queue) {
+        this.exchange = exchange;
+        this.route = route;
+        this.queue = queue;
+    }
+}
diff --git a/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java b/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
index 8e4f150..dc6e308 100644
--- a/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
+++ b/src/main/java/cc/mrbird/febs/rabbit/producter/AgentProducer.java
@@ -2,12 +2,17 @@
 
 import cc.mrbird.febs.rabbit.constants.ExchangeConstants;
 import cc.mrbird.febs.rabbit.constants.RouteKeyConstants;
+import cc.mrbird.febs.rabbit.enumerates.RabbitQueueEnum;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.AmqpException;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.core.MessagePostProcessor;
 import org.springframework.amqp.rabbit.connection.CorrelationData;
 import org.springframework.amqp.rabbit.core.RabbitTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.util.Date;
 import java.util.UUID;
 
 /**
@@ -44,4 +49,15 @@
         CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
         rabbitTemplate.convertAndSend(ExchangeConstants.EXCHANGE_DEFAULT, RouteKeyConstants.ROUTE_KEY_DEFAULT, id, correlationData);
     }
+
+    public void sendOrderCancelDelayMsg(Long id, Long times) {
+        log.info("发送自动取消订单消息:{}, {}", id, times);
+        rabbitTemplate.convertAndSend(RabbitQueueEnum.ORDER_CANCEL_DELAY_TTL.getExchange(), RabbitQueueEnum.ORDER_CANCEL_DELAY_TTL.getRoute(), id, new MessagePostProcessor() {
+            @Override
+            public Message postProcessMessage(Message message) throws AmqpException {
+                message.getMessageProperties().setExpiration(String.valueOf(times));
+                return message;
+            }
+        });
+    }
 }
diff --git a/src/test/java/cc/mrbird/febs/AgentTest.java b/src/test/java/cc/mrbird/febs/AgentTest.java
index 9b1f167..1c6f049 100644
--- a/src/test/java/cc/mrbird/febs/AgentTest.java
+++ b/src/test/java/cc/mrbird/febs/AgentTest.java
@@ -19,6 +19,6 @@
 
     @Test
     public void agentTest() {
-        agentProducer.sendOrderReturn(1L);
+//        agentProducer.sendDelayMsg(1L, 10000L);
     }
 }

--
Gitblit v1.9.1