完整版订单超时自动取消功能

        前几天对实习还是继续学习技术产生了抉择,问了一个前辈,他抛给我一个问题,怎么做15分钟订单自动取消,我说然后到时间之后,自动执行这个订单关闭业务,比如把锁了的库存给解开等等操作,然后在数据库里肯定要有体现,比如抖音,查我的订单内一块,在前段应该显示已过期,把支付的按钮变灰或者取消,支付的时候不能直接对库存进行操作,应该是支付模块调用订单模块调用库存模块。

        然后把理论予以实现,发现需要考虑的点还是有一些的。

功能架构

        该功能使用了三大模块解除耦合,保证高可用性,从高层到底层分别是支付模块->订单模块->商品模块,各司其职,支付模块主要负责支付,退款等相应功能;订单模块主要负责订单查询,订单创建,删除订单相关功能;商品模块主要负责商品上下架,补货,查货相关功能;是环环相扣的,支付模块通过操控订单实现支付,订单模块通过操控商品来实现订单创建等操作。

功能实现流程

        由于是全栈开发,本功能实现流程会涵盖前后端都有。由于管理模块,就是添加商品等等操作,在前端并没有实现,就先在数据库里加一些商品。sql如下:

 然后写一个接口获取商品列表,然后前端进行渲染,效果如下:

测试阶段,未接入微信支付等,但有字段标识,后期方便扩展,渲染的时候只需要有一点,判断支付类型,如果是钱支付就渲染成¥的形式,如果是积分就渲染成积分的形式。然后点击兑换会弹出一个弹出框如下:

 扩展一些信息也会变得非常简单,由于数据库里设置了两个字段一个是销售价(也就是优惠后的价格),一个是原价,直接在前端算出优惠金额即可。然后点击提交订单,就会向后端去发送一个创建的请求,java代码如下所示:

        // 这里先把订单持续事件设置成15秒// 1.1 先校验参数,看看该商品是否有库存CommonGoodPo good = goodMapper.queryGoodById(dto.getGoodId());if (good == null) return Result.error("已查询不到该商品");Boolean isPut = good.getIsPut();if (!isPut) return Result.error("无法对已下架的商品下订单");// 1.2 看看库存还够不够Boolean haveStore = good.getHaveStore();Integer store = good.getStore();if (haveStore && store <= 0) return Result.error("库存不足,无法下单");// 库存足就锁定一个库存if (haveStore) goodMapper.lockStore(good.getId());// 1.3 todo 如果有一个人只能买一单等等限制,可继续扩展// 2.1 然后就要生成订单的信息了,比如订单的id,这里起始应该使用杂乱的数字字母等作为id,图方便就直接使用自增id// 2.2 然后生成开始时间和结束时间LocalDateTime now = LocalDateTime.now();LocalDateTime end = LocalDateTime.now().plusMinutes(15); // 15分钟写死PopOrderVo popOrderVo = new PopOrderVo(null, good.getId(), now, end, 15 * 60, dto.getAccount());orderMapper.creatOrder(popOrderVo);// 3 准备对象,发送消息String mes = JSON.toJSONString(popOrderVo);sendDelayMessage(mes, 60 * 15, RabbitConstants.DELAY_ORDER_DEL_DIRECT_EXCHANGE, RabbitConstants.DELAY_ORDER_KEY);// 然后封装一下给前端,然后前端得到信息后,弹出弹出层,在我的订单里也可以找到该信息return Result.ok(popOrderVo);

 代码逻辑主要分为三部分,校验参数;然后去执行sql,就是向数据库的order表里去添加一条订单消息,并且要锁库存;最后向rabbitMQ里发一条延迟消息,这个是封装好的方法。到期执行的方法如下所示:

        log.error("我要开始喽!");// 把msg转成对象PopOrderVo popOrderVo = null;try {popOrderVo = JSON.parseObject(msg, PopOrderVo.class);} catch (Exception e) {throw new RuntimeException("请调用符合规定的api,类型转换错误,无法转换为PopOrderVo");}// 自动取消订单逻辑LocalDateTime now = LocalDateTime.now();Integer orderId = popOrderVo.getOrderId();Integer goodId = popOrderVo.getGoodId();// 修改订单状态orderMapper.finishOrder(orderId, now, ORDER_STATUS_OVERTIME);// 把锁了的库存释放goodMapper.unLockStore(goodId);log.error("我结束喽!");

就是去校验一下参数,然后去解锁库存,然后修改订单状态。

订单表如下所示:

然后在点击提交订单后,弹出支付页面,并有前端实现的倒计时。 

 然后会显示一些订单信息,倒计时到了之后,按钮会变成灰色,并无法点击,点击支付按钮后,进入到后端逻辑。代码如下:

    @Override@Transactionalpublic Result payOrder(PayOrderDto dto) {Integer orderId = dto.getOrderId();OrderPo orderInfo = orderMapper.getOrderInfo(orderId);Integer goodId = orderInfo.getGoodId();LocalDateTime now = LocalDateTime.now();CommonGoodPo good = goodMapper.queryGoodById(goodId);// 1 先需要校验参数// 1.1 看过没过期,如果现在的时间在截止时间之后,则证明过期了if (now.isAfter(orderInfo.getEndTime())) {return Result.error("该订单已经过期,请重新下单!");}// 1.2 看一下状态是不是待支付状态if (orderInfo.getStatus() != 0) return Result.error("该订单已被处理,请刷新重试");// 1.3 看余额够不够Boolean isEnough = payMapper.checkBalance(orderInfo.getAccount(), good.getSalePrice());// 2.1 如果不够,直接报错余额不足if (!isEnough) return Result.error("你的余额不足,无法完成支付");// 2.2 如果够,扣减余额payMapper.decreaseBalance(orderInfo.getAccount(), good.getSalePrice());// 2 需要进行三个方面的处理// 2.1 商品给增加销量等等goodMapper.increaseSales(goodId);// 2.2 设置订单状态,截至时间等orderMapper.finishOrder(orderId, now, ORDER_STATUS_SUCCESS);// 2.3 记录支付日志payMapper.logPay(good.getSalePrice(), good.getPayType(), orderInfo.getAccount(), now, goodId);
//        return null;return Result.ok("支付成功");}

支付逻辑比较简单,就是校验参数,但需要注意需要检验一下订单状态,因为可能因为网络问题等等,导致请求到后端的时候,出现时间延迟问题,出现状态已经不是待支付状态已经被修改的问题(处理幂等问题),余额不足问题,这时就不能再进行支付,要对订单进行一下处理。如果满足条件就进行sql操作。

然后在前端为了订单的丢失,又写了一个我的订单页面,如下所示:

可以根据不同的状态去筛选不同的订单列表,然后并可以在此页面完成支付。

至此本功能结束,使用的是rabbitMQ的延迟队列实现定时操作,也可以使用xxl-job,直接使用策略模式扩展一下即可,在复习专栏里有关于设计模式的文章和例子,后续有时间会讲一下定时操作策略的扩展。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/425293.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VTD激光雷达(3)——04_OptiX_SimulationDataFlow

文章目录 前言一、总结 前言 一、 1 总结

synchronized的详解、锁的升级过程和优缺点比较

本文 详细介绍Java中为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级 锁、重量级锁&#xff0c;以及锁升级过程。 Java中每一个对象都可以作为锁。具体表现形式为以下三种形式&#xff1a; 对于普通的同步方法&#xff0c;锁是当前的实例对象对于静态同步方法&a…

cJSON-轻量级解析模块、字符串的神——编织STM32C8T6与阿里云信息传递的纽带

编写方向&#xff1a;本人就不泛泛的编写一篇什么一文学会cJSON了&#xff0c;没什么突出点&#xff0c;也就我水水字数&#xff0c;你们看来看去也不懂&#xff0c;本人是从上阿里云传信息接触的cJSON的&#xff0c;我就此写一篇针对性的文章&#xff0c;希望对大家有用&#…

研1日记12

1. 改19->10 2. 学习数据不平衡问题 1. 欠采样 合并两个样本数据 两种方式 1. 按原分布比例划分。sklearn中train_test_split里&#xff0c;参数stratify含义解析_traintestsplit参数stratify-CSDN博客 3.刘二大人 卷积操作 待看论文&#xff1a; 刘老师指导&#xff1a…

用于稀疏自适应深度细化的掩码空间传播网络 CVPR2024

目录 Masked Spatial Propagation Network for Sparsity-Adaptive Depth Refinement &#xff08;CVPR 2024&#xff09;用于稀疏自适应深度细化的掩码空间传播网络1 介绍2 算法流程2.1 问题建模2.2 Guidance Network2.3 MSPN 模块 3 实验结果3.1 稀疏度自适应深度细化对比试验…

图论篇--代码随想录算法训练营第六十一天打卡| Floyd 算法,A*算法

Floyd 算法&#xff08;求多源汇最短路&#xff09; 题目链接&#xff1a;97. 小明逛公园 题目描述&#xff1a; 小明喜欢去公园散步&#xff0c;公园内布置了许多的景点&#xff0c;相互之间通过小路连接&#xff0c;小明希望在观看景点的同时&#xff0c;能够节省体力&…

计算机二级office操作技巧——Excel篇

文章目录 函数公式总结写在前面五大基本函数sum求和函数average求平均函数max求最大值函数min求最小值函数count求个数函数 rank排名函数if逻辑判断函数条件求个数函数countif单条件求个数函数countifs多条件求个数函数 条件求和函数sumifs多条件求和函数sumproduct乘积求和函数…

算法刷题[比较两个字符串的最大公字符串(滑动窗口实现)]

题目&#xff1a;编程实现&#xff1a;找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"cad" 代码如下所示&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #inclu…

C语言实现贪吃蛇小游戏

✅博客主页:爆打维c-CSDN博客​​​​​​ &#x1f43e; &#x1f539;分享c语言知识及代码 &#x1f43e; 目录 游戏展示视频 一、项目准备工作 二、功能实现分析 1.游戏开始 a.设置本地化、创建窗口、标题 b.隐藏光标,封装定位光标的函数 c.打印欢迎界面及提示信息 …

网盘隐私照片泄露?教你如何保护自己的隐私照片!

网盘内的隐私照片 好兄弟最近遇到了一个困难&#xff1a;“我之前一直都是把照片存在网盘里面的&#xff0c;但是最近听说了某网盘的照片泄露了&#xff0c;自己的生活照啊&#xff0c;私密照啊都被人看光了&#xff0c;这太可怕了&#xff01;我现在也很担心自己的网盘上照片…

2021高教社杯全国大学生数学建模竞赛C题 Python代码演示

目录 问题一1.1 根据附件 1&#xff0c;对 402 家供应商的供货特征进行量化分析计算供货特征数据标准化对正向指标归一化对负向指标归一化 1.2 建立反映保障企业生产重要性的数学模型熵权法熵权法-TOPSISAHP 1.3 在此基础上确定 50 家最重要的供应商&#xff0c;并在论文中列表…

钢轨缺陷检测-目标检测数据集(包括VOC格式、YOLO格式)

钢轨缺陷检测-目标检测数据集&#xff08;包括VOC格式、YOLO格式&#xff09; 数据集&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1h7Dc0MiiRgtd7524cBUOFQ?pwdfr9y 提取码&#xff1a;fr9y 数据集信息介绍&#xff1a; 共有 1493 张图像和一一对应的标注文件 标…

Neo4j入门案例:三星堆

创建一个关于三星堆的知识图谱可以是一个非常有趣的项目&#xff0c;它可以帮助理解如何使用Neo4j来存储和查询复杂的关系数据。三星堆文化以其独特的青铜器、金器和其他文物而闻名&#xff0c;这为我们提供了一个丰富的历史背景来构建知识图谱。 数据模型定义 实体类型&#…

RTMP直播播放器的几种选择

如何选择RTMP播放器&#xff1f; 在选择RTMP播放器时&#xff0c;需要综合考虑多个因素&#xff0c;以确保选择的播放器能够满足实际需求并提供良好的用户体验。以下是一些选择RTMP播放器的建议&#xff1a; 1. 功能需求 低延迟&#xff1a;对于直播场景&#xff0c;低延迟是…

解读 Java 经典巨著《Effective Java》90条编程法则,第5条:优先考虑依赖注入来引用资源

【前言】欢迎订阅【解读《Effective Java》】系列专栏 《Effective Java》是 Java 开发领域的经典著作&#xff0c;作者 Joshua Bloch 以丰富的经验和深入的知识&#xff0c;全面探讨了 Java 编程中的最佳实践。这本书被公认为 Java 开发者的必读经典&#xff0c;对提升编码技…

STM32巡回研讨会总结(2024)

前言 本次ST公司可以说是推出了7大方面&#xff0c;几乎可以说是覆盖到了目前生活中的方方面面&#xff0c;下面总结下我的感受。无线类 支持多种调制模式&#xff08;LoRa、(G)FSK、(G)MSK 和 BPSK&#xff09;满足工业和消费物联网 (IoT) 中各种低功耗广域网 (LPWAN) 无线应…

MelosBoom:解锁数据价值的新纪元

在当今的数字时代&#xff0c;数据被誉为“新的石油”&#xff0c;但用户在传统的Web2环境中&#xff0c;往往无法真正享受到自己贡献数据的价值。大型互联网公司通过集中化的系统和算法&#xff0c;垄断了数据的使用权&#xff0c;并从中获取巨大的商业利益&#xff0c;而数据…

计算机三级网络技术总结(一)

RPR环中每一个节点都执行SRP公平算法IEEE 802.11a和g将传输速率提高到54Mbps一个BGP发言人与其他自治系统中的BGP发言人要交换路由信息就要先建立TCP连接在一个区域内的路由器数一般不超过200个进入接口配置模式&#xff1a;Router(config)#interface <接口名> 封装ppp协…

Qt 实现自定义截图工具

目录 Qt 实现自定义截图工具实现效果图PrintScreen 类介绍PrintScreen 类的主要特性 逐步实现第一步&#xff1a;类定义第二步&#xff1a;初始化截图窗口第三步&#xff1a;处理鼠标事件第四步&#xff1a;计算截图区域第五步&#xff1a;捕获和保存图像 完整代码PrintScreen.…

WLAN实验简述

一&#xff1a;配置生产AP1上级接入层交换机LSW3 sys [Huawei]sysname LSW3 [LSW3]undo info-center enable [LSW3]vlan batch 10 100 [LSW3]int g0/0/2 [LSW3-GigabitEthernet0/0/2]port link-type trunk [LSW3-GigabitEthernet0/0/2]port trunk allow-pass vlan 10 100 [LSW…