springboot中模拟实现订单未支付取消订单

Posted 等你的夏天

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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+"支付成功!";
    }

}

 

以上是关于springboot中模拟实现订单未支付取消订单的主要内容,如果未能解决你的问题,请参考以下文章

订单30分钟未支付自动取消怎么实现?

生成订单30分钟未支付,则自动取消,该怎么实现?

订单30分钟未支付自动取消怎么实现?

生成订单30分钟未支付,则自动取消,该怎么实现?

订单超时未支付自动取消8种实现方案

订单超时未支付自动取消8种实现方案