Chiriri's blog Chiriri's blog
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)

Iekr

苦逼后端开发
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)
  • JavaSE

  • JavaEE

  • Linux

  • MySQL

  • NoSQL

  • Python

  • Python模块

  • 机器学习

  • 设计模式

  • 传智健康

  • 畅购商城

    • Day01 项目搭建
    • Day02 FastDFS
    • Day03 微服务鉴权
    • Day04 新增和修改商品
    • Day05 广告缓存
    • Day06 监听数据库更新广告缓存
    • Day07 ES搜索
    • Day08 Thymeleaf
    • Day09 Oauth2
    • Day10 购物车渲染
    • Day11 订单结算
    • Day12 分布式事务解决方案
    • Day13 微信支付
    • Day14 订单处理
      • 超时未支付订单处理
        • 延迟消息队列(死信队列)
        • 消息的TTL(Time To Live)
        • 死信交换器 Dead Letter Exchanges
        • 创建死信队列
        • 代码实现
        • 微信支付-查询订单
        • 微信支付-关闭订单
        • 回滚库存
        • 消息队列发送和接受
      • 订单批量发货
        • 对接第三方物流查询
      • 确认收货和自动收货
        • 手动确认收货
        • 自动收货
        • Cron表达式
        • 代码实现
        • 发送消息
        • 接受消息
    • Day15 秒杀前端
    • Day16 秒杀后端
  • 博客项目

  • JVM

  • JUC

  • Golang

  • Kubernetes

  • 硅谷课堂

  • C

  • 源码

  • 神领物流

  • RocketMQ

  • 短链平台

  • 后端
  • 畅购商城
Iekr
2022-03-26
目录

Day14 订单处理

# Day14 订单处理

# 超时未支付订单处理

超过限定时间并未支付的订单,我们需要进行超时订单的处理:先调用微信支付 api,查询该订单的支付状态。如果未支付调用关闭订单的 api,并修改订单状态为已关闭,并回滚库存数。如果该订单已经支付,则做补偿操作(修改订单状态和记录)。

# 延迟消息队列 (死信队列)

延迟消息队列,就是消息的生产者发送的消息并不会立刻被消费,而是在设定的时间之后才可以消费。

我们可以在订单创建时发送一个延迟消息,消息为订单号,系统会在限定时间之后取出这个消息,然后查询订单的支付状态,根据结果做出相应的处理。

rabbitmq 中并没有提供延迟队列功能 但是我们可以通过使用 TTL + 死信队列 组合实现延迟队列的效果

# 消息的 TTL(Time To Live)

消息的 TTL 就是消息的存活时间。RabbitMQ 可以对队列和消息分别设置 TTL。对队列设置就是队列没有消费者连着的保留时间,也可以对每一个单独的消息做单独的设置。超过了这个时间,我们认为这个消息就死了,称之为死信。

# 死信交换器 Dead Letter Exchanges

一个消息在满足如下条件下,会进死信交换机,记住这里是交换机而不是队列,一个交换机可以对应很多队列。

(1) 一个消息被 Consumer 拒收了,并且 reject 方法的参数里 requeue 是 false (不把消息重新放入原目标队列.requeue=false)。也就是说不会被再次放在队列里,被其他消费者使用。

(2)上面的消息的 TTL 到了,消息过期了。

(3)队列的长度限制满了。排在前面的消息会被丢弃或者扔到死信交换机上。

# 创建死信队列

进入 MQ web 管理页面 http://192.168.130.128:15672/

  1. 创建死信交换器 exchange.ordertimeout (fanout)

    1648289673376.png

  2. 创建队列 queue.ordertimeout

    1648289765224.png

  3. 建立死信交换器 exchange.ordertimeout 与队列 queue.ordertimeout 之间的绑定

    1648289861858.png

  4. 创建队列 queue.ordercreate ,Arguments 添加

​ x-message-ttl = 10000

​ x-dead-letter-exchange : exchange.ordertimeout

​ 1648290034111.png

  1. 测试:向 queue.ordercreate 队列添加消息,等待 10 秒后消息从 queue.ordercreate 队列消失

# 代码实现

1648292256080.png

# 微信支付 - 查询订单

在 changgou_service_pay 的 pay 下 controller 包的 WxPayController 类添加查询订单方法

//基于微信支付查询订单
@GetMapping("/query/{orderId}")
public Result queryOrder(@PathVariable("orderId") String orderId) {
    Map map = wxPayService.queryOrder(orderId);
    return new Result(true, StatusCode.OK, "查询订单成功", map);
}
1
2
3
4
5
6

将查询订单方法暴露给 feign

在 changgou_service_pay_api 里的 feign 包的 PayFeign 添加查询方法

//基于微信支付查询订单
@GetMapping("/wxpay/query/{orderId}")
public Result queryOrder(@PathVariable("orderId") String orderId);
1
2
3

# 微信支付 - 关闭订单

在 changgou_service_pay 的 pay 下 service 包的 WxpayService 接口 添加关闭订单方法定义

//基于微信支付关闭订单
Map closeOrder(String orderId);
1
2

实现方法 调用微信支付 sdk 中的 closeOrder 方法

    //基于微信支付关闭订单
    @Override
    public Map closeOrder(String orderId) {
        try {
            Map<String,String> map = new HashMap();
            map.put("out_trade_no",orderId);
            Map<String, String> resultMap = wxPay.closeOrder(map);
            return resultMap;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13

collection 层

//基于微信支付关闭订单
@PutMapping("/close/{orderID}")
public Result closeOrder(@PathVariable("orderId") String orderID){
    Map map = wxPayService.closeOrder(orderID);
    return new Result(true,StatusCode.OK,"关闭订单成功",map);
}
1
2
3
4
5
6

同样以 feign 形式声明

//基于微信支付关闭订单
@PutMapping("/wxpay/close/{orderID}")
public Result closeOrder(@PathVariable("orderId") String orderID);
1
2
3

# 回滚库存

在 changgou_service_goods 包 dao 层的 SkuMapper 实体接口 添加回滚库存的自定义 sql

//回滚库存(增加库存并扣减销量)
@Update("update tb_suk set num=num+#{num},sale_num=sale_num-#{num} where id=#{skuId}")
void resumeStockNum(@Param("skuId") String skuId,@Param("num") Integer num);
1
2
3

在 SkuService 中添加方法声明

//回滚库存
void resumeStockNum(String skuId, Integer num);
1
2

impl 实现方法

//回滚库存
@Override
@Transactional
public void resumeStockNum(String skuId, Integer num) {
    skuMapper.resumeStockNum(skuId,num);
}
1
2
3
4
5
6

collection 层

    //回滚库存
    @RequestMapping("/resumeStockNum")
    public Result resumeStockNum(@RequestParam("skuId") String skuId,@RequestParam("num") Integer num){
        skuService.resumeStockNum(skuId,num);
        return new Result(true,StatusCode.OK,"回滚库存成功");
    }
1
2
3
4
5
6

在 changgou_service_goods_api 包下声明 feign

//回滚库存
@RequestMapping("/sku/resumeStockNum")
public Result resumeStockNum(@RequestParam("skuId") String skuId,@RequestParam("num") Integer num);
1
2
3

# 消息队列发送和接受

在 changgou_service_order 项目下的 service.impl 包下的 OrderServiceImpl

注入 rabbitmq 模块

@Autowired
private RabbitTemplate rabbitTemplate;
1
2

在 add 方法最后一行添加代码

//发送延时消息
rabbitTemplate.convertAndSend("","queue.ordercreate",orderId);
1
2

1648294510171.png

在此项目的 listener 包添加 OrderTimeOutListener

@Component
public class OrderTimeOutListener {

    @Autowired
    private OrderService orderService;

    //监听死信队列
    @RabbitListener(queues = "queue.ordertimeout")
    public void receiveCloseOrderMessage(String orderId){
        System.out.println("接受到关闭订单的消息"+orderId);

        try {
            //调用业务层完成关闭订单操作
            orderService.closeOrder(orderId);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

在 OrderService 声明 closeOrder 方法

//关闭订单
void closeOrder(String oderId);
1
2

在 changgou_server_order 添加 pay 的 feign 依赖导入 在 pom.xml 添加依赖

        <dependency>
            <groupId>com.changgou</groupId>
            <artifactId>changgou_service_pay_api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
1
2
3
4
5

在启动类中扫描 feign 包注解添加 pay 包

@EnableFeignClients(basePackages = {"com.changgou.goods.feign" , "com.changgou.pay.feign"})
1

impl 实现接口声明的方法

@Autowired
private PayFeign payFeign;

@Override
@Transactional
public void closeOrder(String orderId) {
    System.out.println("关闭订单的业务开启" + orderId);
    Order order = orderMapper.selectByPrimaryKey(orderId);
    if (order == null) {
        throw new RuntimeException("订单不存在");
    }

    //1.根据订单id查询mysql的订单信息 判断订单是否存在 判断订单的支付状态
    //判断是否为已支付
    if (!"0".equals(order.getPayStatus())) {
        System.out.println("当前订单已支付,无需关闭");
        return;
    }

    System.out.println("关闭订单校验通过" + orderId);


    //2.基于微信查询订单信息
    Map wxQueryMap = (Map) payFeign.queryOrder(orderId).getData();
    System.out.println("查询微信支付订单成功" + wxQueryMap);

    //如果订单支付状态为已支付,进行数据补偿
    if ("SUCCESS".equals(wxQueryMap.get("trade_state"))) {
        String transactionId = String.valueOf(wxQueryMap.get("transaction_id"));
        this.updatePayStatus(orderId, transactionId); //订单支付成功 进行减少库存 添加销量操作
        System.out.println("完成数据补偿");
    }

    //如果订单支付状态为未支付 则回滚mysql中的订单信息 新增订单日志 恢复商品的库存 基于微信支付关闭订单
    if ("NOTPAY".equals(wxQueryMap.get("trade_state"))) {
        System.out.println("执行关闭操作");
        order.setUpdateTime(new Date());
        order.setOrderStatus("4"); //订单已关闭
        orderMapper.updateByPrimaryKeySelective(order); //修改mysql订单信息

        //订单日志
        OrderLog orderLog = new OrderLog();
        orderLog.setId(idWorker.nextId() + "");
        orderLog.setOperater("system");
        orderLog.setOperateTime(new Date());
        orderLog.setOrderStatus("4"); //订单已关闭
        orderLog.setOrderId(orderId);
        orderLogMapper.insert(orderLog);//写入日志

        //恢复商品库存
        OrderItem _orderItem = new OrderItem();
        _orderItem.setOrderId(orderId);
        List<OrderItem> orderItemList = orderItemMapper.select(_orderItem); //根据orderId查询orderItem
        for (OrderItem orderItem : orderItemList) {
            skuFeign.resumeStockNum(orderItem.getSkuId(), orderItem.getNum());
        }

        //基于微信关闭订单
        payFeign.closeOrder(orderId);

    }


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

# 订单批量发货

在 changgou_service_order 项目的 Service 包下的 OrderService 类添加方法声明

//批量发货
void batchSend(List<Order> orders);
1
2

OrderServiceImpl 实现该方法

@Override
@Transactional
public void batchSend(List<Order> orders) {
    //判断每个订单和物流公司的值是否存在
    for (Order order : orders) {
        if (order.getId() == null){
            throw new RuntimeException("订单号不存在")
        }
        if (order.getShippingCode() == null || order.getShippingName() == null) {
            throw new RuntimeException("请输入快递单号或物流公司名称");
        }
    }

    //进行订单状态的校验
    for (Order order : orders) {
        Order order1 = orderMapper.selectByPrimaryKey(order.getId());
        //发货状态 是否存在
        if (!"0".equals(order1.getConsignStatus()) || !"1".equals(order1.getConsignStatus())){
            throw new RuntimeException("订单状态不合法");
        }
    }

    //修改订单状态为已发货
    for (Order order : orders) {
        order.setOrderStatus("2"); // 已发货状态
        order.setConsignStatus("1"); //已发货
        order.setConsignTime(new Date());
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order); //写入数据

        //记录订单日志
        OrderLog orderLog =new OrderLog();
        orderLog.setId(String.valueOf(idWorker.nextId()));
        orderLog.setOperater("admin");
        orderLog.setOperateTime(new Date());
        orderLog.setOrderId(order.getId());
        orderLog.setOrderStatus("2");
        orderLog.setConsignStatus("1");
        orderLogMapper.insert(orderLog); //写入日志

    }



}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

OrderController 新增方法

@PostMapping("/batchSend")
public Result batchSend(@RequestBody List<Order> orders){
    orderService.batchSend(orders);
    return new Result(true,StatusCode.OK,"发货成功");
}
1
2
3
4
5

# 对接第三方物流查询

第三方的物流系统。比较常用的有菜鸟物流、快递鸟等。我们这里推荐使用快递鸟 http://www.kdniao.com

# 确认收货和自动收货

当物流公司将货物送到了用户收货地址之后,需要用户点击确认收货,当用户点击了确认收货之后,会修改订单状态为已完成

# 手动确认收货

在 changgou_service_order 项目的 Service 包下的 OrderService 类添加方法声明

//手动确认收货
void confirmTask(String orderId,String operator);
1
2

impl 实现

//手动确认收货
@Override
public void confirmTask(String orderId, String operator) {
    Order order = orderMapper.selectByPrimaryKey(orderId);
    if (order == null) {
        throw new RuntimeException("订单不存在");
    }
    if (!"1".equals(order.getConsignStatus())){
        throw new RuntimeException("订单未发货");
    }
    order.setConsignStatus("2"); //已送达
    order.setOrderStatus("3"); //已完成
    order.setUpdateTime(new Date());
    order.setEndTime(new Date());
    orderMapper.updateByPrimaryKeySelective(order);


    //订单日志
    OrderLog orderLog =new OrderLog();
    orderLog.setId(String.valueOf(idWorker.nextId()));
    orderLog.setOperater(operator);
    orderLog.setOperateTime(new Date());
    orderLog.setOrderId(order.getId());
    orderLog.setOrderStatus("3"); //订单已完成
    orderLog.setConsignStatus("2"); //订单已送达
    orderLogMapper.insert(orderLog); //写入日志
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 自动收货

如果用户在 15 天(可以在订单配置表中配置)没有确认收货,系统将自动收货。如何实现?我们这里采用定时任务 springTask 来实现.

# Cron 表达式

Cron 表达式是一个字符串,字符串分为七个部分,每一个域代表一个含义。

Cron 表达式 7 个域格式为: 秒 分 小时 日 月 星期几 年

Cron 表达式 6 个域格式为: 秒 分 小时 日 月 周

序号 说明 是否必填 允许填写的值 允许的通配符
1 秒 是 0-59 , - * /
2 分 是 0-59 , - * /
3 小时 是 0-23 , - * /
4 日 是 1-31 , - * ? / L W
5 月 是 1-12 或 JAN-DEC , - * /
6 星期几 是 1-7 或 SUN-SAT , - * ? / L W
7 年 否 empty 或 1970-2099 , - * /

通配符

通配符说明:
* 表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。

? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。

例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ?

- 表示区间。例如 在小时上设置 "10-12",表示 10,11,12点都会触发。

, 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发

/ 用于递增触发。如在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置'1/3'所示每月1号开始,每隔三天触发一次。

L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于"7"或"SAT"。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本月最后一个星期五"

W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 "1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,"W"前只能设置具体的数字,不允许区间"-").

# 序号(表示每月的第几个周几),例如在周字段上设置"6#3"表示在每月的第三个周六.注意如果指定"#5",正好第五周没有周六,则不会触发该配置(用在母亲节和父亲节再合适不过了) ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

常用表达式

0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时 
0 0 12 ? * WED 表示每个星期三中午12点 
"0 0 12 * * ?" 每天中午12点触发 
"0 15 10 ? * *" 每天上午10:15触发 
"0 15 10 * * ?" 每天上午10:15触发 
"0 15 10 * * ? *" 每天上午10:15触发 
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发 
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
"0 15 10 15 * ?" 每月15日上午10:15触发 
"0 15 10 L * ?" 每月最后一日的上午10:15触发 
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 代码实现

# 发送消息

创建工程 changgou_task ,引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
</dependency>
1
2
3
4
5
6
7
8

创建配置文件

server:
  port: 9202
spring:
  application:
    name: task
  rabbitmq:
    host: 192.168.130.128
1
2
3
4
5
6
7

创建 com.changgou 包 再创建启动类 TaskApplication

@SpringBootApplication
@EnableScheduling //开启定时任务
public class TaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(TaskApplication.class,args);
    }
}
1
2
3
4
5
6
7

创建 com.changgou.config 包 创建 RabbitMQConfig 类

注意 Queue 为 org.springframework.amqp.core.Queue 下的 Queue

@Configuration
public class RabbitMQConfig {

    public static final String ORDER_TACK="order_tack";

    @Bean
    public Queue queue(){
        return new Queue(ORDER_TACK);
    }


}
1
2
3
4
5
6
7
8
9
10
11
12

创建 com.changgou.task 包 创建 OrderTask 类

@Configuration
public class RabbitMQConfig {

    public static final String ORDER_TACK="order_tack";

    @Bean
    public Queue queue(){
        return new Queue(ORDER_TACK);
    }


}
1
2
3
4
5
6
7
8
9
10
11
12
# 接受消息

在 changgou_service_order 项目 order.config 包 的 RabbitMQConfig 添加自动收货消息队列

//自动收货消息队列
public static final String ORDER_TACK="order_tack";
1
2
@Bean
public Queue ORDER_TASK() {
    return new Queue(ORDER_TACK);
}
1
2
3
4

在 OrderService 添加方法声明

//自动确认收货
void autoTack();
1
2

impl 实现

 @Autowired
    private OrderConfigMapper orderConfigMapper;

    @Override
    @Transactional
    public void autoTack() {
        //1.从订单配置表获取到订单自动确认的时间点
        OrderConfig orderConfig = orderConfigMapper.selectByPrimaryKey(1); //目前只有1条写死为获取 id为1的
        //2.得到当前时间节点向前数 15(默认为) 天 作为过期的时间节点
        LocalDate now = LocalDate.now();
        LocalDate date = now.plusDays(-orderConfig.getTakeTimeout());
        //3.按条件查询 获取订单列表
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLessThan("consignTime",date); //发货时间小于过期时间
        criteria.andEqualTo("orderStatus","2"); //收货状态为未确认
        List<Order> orderList = orderMapper.selectByExample(example);
        for (Order order : orderList) {
            this.confirmTask(order.getId(),"system"); //调用手动确认方法
        }


    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

在 listener 包 创建 OrderTackListener 类

@Component
public class OrderTackListener  {

    @Autowired
    private OrderService orderService;

    @RabbitListener(queues = RabbitMQConfig.ORDER_TACK)
    public void receiveOrderTaskMessage(String message){
        System.out.println("收到自动确认收货消息");
        orderService.autoTack();
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
编辑 (opens new window)
上次更新: 2023/12/06, 01:31:48
Day13 微信支付
Day15 秒杀前端

← Day13 微信支付 Day15 秒杀前端→

最近更新
01
k8s
06-06
02
进程与线程
03-04
03
计算机操作系统概述
02-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Iekr | Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式