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+"支付成功!";
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM