zoukankan      html  css  js  c++  java
  • springboot中模拟实现订单未支付取消订单

    1)先写一个日志订单的消费者;

    OrderConsumer.java

    package com.seecen.redis.rabbitmq;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.amqp.rabbit.annotation.RabbitListener;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    
    @Component
    @Slf4j
    public class OrderConsumer {
        @Autowired
        private RedisTemplate redisTemplate;
    
        @RabbitListener(queues = {"order.queue"},
                containerFactory = "rabbitListenerContainerFactory")
        public void insertLog(Map<String,String> msg){
            log.info("接收到超时消息:{}",msg);
            if (msg!=null){
                String orderId=msg.get("orderId");
                //获取状态
                String status = (String) redisTemplate.opsForHash().get("order:" + orderId, "status");
                if ("0".equals(status)){//如果还是未付款状态,则取消订单
                    redisTemplate.opsForHash().put("order:"+orderId,"status","-1");
                    log.warn("订单:{},因超时未支付而取消",orderId);
                }
            }
        }
    }

    2)在RabbitConfig.java中配置相关需要的配置文件;

    RabbitConfig.java

     //=========死信队列实现订单超时取消=============
        /**
         * 订单延迟队列的交换机(下单之后存入的交换机)
         * @return
         */
        @Bean
        public DirectExchange orderTtlDirect(){
            return (DirectExchange)
                    ExchangeBuilder
                            .directExchange("order.ttl.exchange")
                            .durable(true).build();
        }
        /**
         * 订单延迟队列()
         * @return
         */
        @Bean
        public Queue orderTtlQueue(){
            Map<String,Object> params=new HashMap<>();
            //指定超时之后转发到的交换机
            params.put("x-dead-letter-exchange","order.exchange");
            //指定超时之后的routing key
            params.put("x-dead-letter-routing-key","order.cancel");
            //params.put("x-expires",1000*60*30);//设置队列超时时间
            params.put("x-message-ttl",30000);//设置队列中的队列的超时时间
            return new Queue(
                    "order.ttl.queue",
                    true,//持久化
                    false,
                    false,
                    params
            );
        }
        @Bean
        public Binding orderTtlBinding(){
            return BindingBuilder.bind(orderTtlQueue())//绑定队列
                    .to(orderTtlDirect())//指定交换机
                    .with("order.ttl.cancel");//路由规则
        }
        /**
         *  订单超时后处理的交换机(处理订单取消的交换机)
         * @return
         */
        @Bean
        public DirectExchange orderDirect(){
            return (DirectExchange)
                    ExchangeBuilder
                            .directExchange("order.exchange")
                            .durable(true).build();
        }
        /**
         * 取消订单处理队列
         * @return
         */
        @Bean
        public Queue orderQueue(){
            return new Queue("order.queue");
        }
        /**
         *  绑定订单取消队列到交换机
         * @return
         */
        @Bean
        public Binding orderBinding(){
            return BindingBuilder.bind(orderQueue())//绑定队列
                    .to(orderDirect())//指定交换机
                    .with("order.cancel");//路由规则
        }

    3)控制层方法;

    IndexController.java

    package com.seecen.redis.controller;
    
    import com.seecen.redis.aop.Log;
    import com.seecen.redis.aop.LogType;
    import com.seecen.redis.entity.TAdmin;
    import com.seecen.redis.service.AdminService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.amqp.rabbit.core.RabbitTemplate;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.annotation.Resource;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    
    /**
     * @author bigpeng
     * @create 2020-07-21-16:18
     */
    @Controller
    @Slf4j
    public class IndexController {
        @Autowired
        private RedisTemplate redisTemplate;
        @Autowired
        private AdminService adminService;
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
        @ResponseBody
        @GetMapping("/order/{product}")
        public String order(@PathVariable("product") String product){
            //模拟一个订单,使用map存储数据
            Map map = new HashMap<>();
            map.put("product",product);
            String orderId=UUID.randomUUID().toString();
            map.put("orderId",orderId);
            map.put("status","0");//只发状态  0:未支付  1:已支付  -1:已取消
            //todo 将订单记录插入数据库
            //redisTemplate.opsForValue().set("order:"+orderId,map);
            redisTemplate.opsForHash().putAll("order:"+orderId,map);
            //发送mq消息到超时队列
            rabbitTemplate.convertAndSend(
                    "order.ttl.exchange",
                    "order.ttl.cancel",
                    map);
            log.info("下单成功,订单号:"+orderId);
            return "下单成功,订单号:"+orderId;
        }
        @ResponseBody
        @GetMapping("/order/pay/{orderId}")
        public String pay(@PathVariable("orderId") String orderId){
            Boolean hasKey = redisTemplate.hasKey("order:" + orderId);
            if (hasKey){
                redisTemplate.opsForHash().put("order:"+orderId,"status","1");
                log.info("订单:{}支付成功",orderId);
            }
            return "订单:"+orderId+"支付成功!";
        }
    
    }
  • 相关阅读:
    奥运圣火在家乡传递
    Please stop reinventing the wheel (请不要重复发明轮子)
    使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
    To invoke and to begin invoke, that is a question.
    XML和JSON(JavaScript Object Notation)
    Cloud Computing Is a Big Whiteboard
    TRIE Data Structure
    ASP.NET AJAX UpdatePanel 控件实现剖析
    分布式计算、网格计算和云计算
    系统架构设计师考试大纲(2009版)
  • 原文地址:https://www.cnblogs.com/xie-qi/p/13364014.html
Copyright © 2011-2022 走看看