尚品汇-秒杀成功下单接口、秒杀结束定时任务-清空缓存数据(五十四)

目录:

(1)下单页面

(2)service-activity-client添加接口

(3)web-all 编写去下单控制器

(4)service-order模块提供秒杀下单接口

 (5)service-order-client模块暴露接口

(6)service-activity模块秒杀下单

(7)秒杀结束清空redis缓存

(1)下单页面

我们已经把下单信息记录到redis缓存中,所以接下来我们要组装下单页数据

 下单页数据数据接口SeckillGoodsApiController

@Autowired
private RedisTemplate redisTemplate;
/*** 秒杀确认订单* @param request* @return*/
@GetMapping("auth/trade")
public Result trade(HttpServletRequest request) {// 获取到用户IdString userId = AuthContextHolder.getUserId(request);// 先得到用户想要购买的商品!OrderRecode orderRecode = (OrderRecode) redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).get(userId);if (null == orderRecode) {return Result.fail().message("非法操作");}//获取商品SeckillGoods seckillGoods = orderRecode.getSeckillGoods();//获取用户地址List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(userId);// 声明一个集合来存储订单明细ArrayList<OrderDetail> detailArrayList = new ArrayList<>();OrderDetail orderDetail = new OrderDetail();orderDetail.setSkuId(seckillGoods.getSkuId());orderDetail.setSkuName(seckillGoods.getSkuName());orderDetail.setImgUrl(seckillGoods.getSkuDefaultImg());orderDetail.setSkuNum(orderRecode.getNum());orderDetail.setOrderPrice(seckillGoods.getCostPrice());// 添加到集合detailArrayList.add(orderDetail);// 计算总金额  创建订单对象,计算订单价格OrderInfo orderInfo = new OrderInfo();orderInfo.setOrderDetailList(detailArrayList);orderInfo.sumTotalAmount();Map<String, Object> result = new HashMap<>();result.put("userAddressList", userAddressList);result.put("detailArrayList", detailArrayList);result.put("totalNum", 1);// 保存总金额result.put("totalAmount", orderInfo.getTotalAmount());return Result.ok(result);
}

(2)service-activity-client添加接口

ActivityFeignClient
/*** 秒杀确认订单* @return*/
@GetMapping("/api/activity/seckill/auth/trade")
Result<Map<String, Object>> trade();

ActivityDegradeFeignClient 


@Override
public Result<Map<String, Object>> trade() {return Result.fail();
}

(3)web-all 编写去下单控制器

SeckillController

/*** 确认订单* @param model* @return*/
@GetMapping("seckill/trade.html")
public String trade(Model model) {Result<Map<String, Object>> result = activityFeignClient.trade();if(result.isOk()) {model.addAllAttributes(result.getData());return "seckill/trade";} else {model.addAttribute("message",result.getMessage());return "seckill/fail";}
}

Result

package com.atguigu.gmall.common.result;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;/*** 全局统一返回结果类**/
@Data
@ApiModel(value = "全局统一返回结果")
public class Result<T> {@ApiModelProperty(value = "返回码")private Integer code;@ApiModelProperty(value = "返回消息")private String message;@ApiModelProperty(value = "返回数据")private T data;public Result(){}// 返回数据protected static <T> Result<T> build(T data) {Result<T> result = new Result<T>();if (data != null)result.setData(data);return result;}public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {Result<T> result = build(body);result.setCode(resultCodeEnum.getCode());result.setMessage(resultCodeEnum.getMessage());return result;}public static<T> Result<T> ok(){return Result.ok(null);}/*** 操作成功* @param data* @param <T>* @return*/public static<T> Result<T> ok(T data){Result<T> result = build(data);return build(data, ResultCodeEnum.SUCCESS);}public static<T> Result<T> fail(){return Result.fail(null);}/*** 操作失败* @param data* @param <T>* @return*/public static<T> Result<T> fail(T data){Result<T> result = build(data);return build(data, ResultCodeEnum.FAIL);}public Result<T> message(String msg){this.setMessage(msg);return this;}public Result<T> code(Integer code){this.setCode(code);return this;}public boolean isOk() {if(this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {return true;}return false;}
}

 

下单确认页面

该页面与正常下单页面类似,只是下单提交接口不一样,因为秒杀下单不需要正常下单的各种判断,因此我们要在订单服务提供一个秒杀下单接口,直接下单

(4)service-order模块提供秒杀下单接口

 

OrderApiController :提供一个重载的下单方法       
/*** 秒杀提交订单,秒杀订单不需要做前置判断,直接下单* @param orderInfo* @return*/
@PostMapping("inner/seckill/submitOrder")
public Long submitOrder(@RequestBody OrderInfo orderInfo) {Long orderId = orderService.saveOrderInfo(orderInfo);return orderId;
}

  (5)service-order-client模块暴露接口

OrderFeignClient
/*** 提交秒杀订单* @param orderInfo* @return*/
@PostMapping("/api/order/inner/seckill/submitOrder")
Long submitOrder(@RequestBody OrderInfo orderInfo);

OrderDegradeFeignClient 


@Override
public Long submitOrder(OrderInfo orderInfo) {return null;
}

(6)service-activity模块秒杀下单

SeckillGoodsApiController
@Autowired
private OrderFeignClient orderFeignClient;@PostMapping("auth/submitOrder")
public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {String userId = AuthContextHolder.getUserId(request);orderInfo.setUserId(Long.parseLong(userId));Long orderId = orderFeignClient.submitOrder(orderInfo);if (null == orderId) {return Result.fail().message("下单失败,请重新操作");}//删除下单信息 临时订单
redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS).delete(userId);//添加一个用户订单记录  下单记录  总订单
redisTemplate.boundHashOps(RedisConst.SECKILL_ORDERS_USERS).put(userId, orderId.toString());return Result.ok(orderId);
}

页面提交订单代码片段

submitOrder() {seckill.submitOrder(this.order).then(response => {if (response.data.code == 200) {window.location.href = 'http://payment.gmall.com/pay.html?orderId=' + response.data.data} else {alert(response.data.message)}})
},

 

 

 

说明:下单成功后,后续流程与正常订单一致

(7)秒杀结束清空redis缓存

秒杀过程中我们写入了大量redis缓存,我们可以在秒杀结束或每天固定时间清楚缓存

,释放缓存空间;

实现思路:假如根据业务,我们确定每天18点所有秒杀业务结束,那么我们编写定时任务,每天18点发送mq消息,service-activity模块监听消息清理缓存

Service-task发送消息

添加常量MqConst

/*** 定时任务*/
public static final String ROUTING_TASK_18 = "seckill.task.18";
//队列
public static final String QUEUE_TASK_18  = "queue.task.18";

 

编写定时任务发送消息

/*** 每天下午18点执行*/
//@Scheduled(cron = "0/35 * * * * ?")
@Scheduled(cron = "0 0 18 * * ?")
public void task18() {rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_TASK, MqConst.ROUTING_TASK_18, "");
}

接收消息并处理

Service-activity接收消息

SeckillReceiver

//  监听删除消息!每天18点清空数据
@SneakyThrows
@RabbitListener(bindings = @QueueBinding(value = @Queue(value = MqConst.QUEUE_TASK_18,durable = "true",autoDelete = "false"),exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),key = {MqConst.ROUTING_TASK_18}
))
public void deleteRedisData(Message message, Channel channel){try {//  查询哪些商品是秒杀结束的!end_time , status = 1//  select * from seckill_goods where status = 1 and end_time < new Date();QueryWrapper<SeckillGoods> seckillGoodsQueryWrapper = new QueryWrapper<>();seckillGoodsQueryWrapper.eq("status",1);seckillGoodsQueryWrapper.le("end_time",new Date());List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(seckillGoodsQueryWrapper);//  对应将秒杀结束缓存中的数据删除!for (SeckillGoods seckillGoods : seckillGoodsList) {//  seckill:stock:46 删除库存对应key  删除List集合redisTemplate.delete(RedisConst.SECKILL_STOCK_PREFIX+seckillGoods.getSkuId());//   删除预热// redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS).delete(seckillGoods.getSkuId());}//  删除预热等数据! 主要针对于预热数据删除! 我们项目只针对一个商品的秒杀! 如果是多个秒杀商品,则不能这样直接删除预热秒杀商品的key!//  46 : 10:00 -- 10:30 | 47 : 18:10 -- 18:30redisTemplate.delete(RedisConst.SECKILL_GOODS);//  预下单  临时订单redisTemplate.delete(RedisConst.SECKILL_ORDERS);//  删除真正下单数据 总订单记录redisTemplate.delete(RedisConst.SECKILL_ORDERS_USERS);//  修改数据库秒杀对象的状态!SeckillGoods seckillGoods = new SeckillGoods();//  1:表示审核通过 ,2:表示秒杀结束seckillGoods.setStatus("2");seckillGoodsMapper.update(seckillGoods,seckillGoodsQueryWrapper);} catch (Exception e) {e.printStackTrace();}//  手动确认消息
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
}

用户是否抢单信息我们这里在前面存储的时候可以设置超时时间就行了,这里就不用清楚了,因为这里不好获取用户id

说明:情况redis缓存,同时更改秒杀商品活动结束

行秒杀下单,提交成功,页面通过轮询后台方法查询秒杀状态

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024年最新 Python 大数据网络爬虫技术基础案例详细教程(更新中)

网络爬虫概述 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;又称为网页蜘蛛&#xff08;Web Spider&#xff09;或网络机器人&#xff08;Web Robot&#xff09;&#xff0c;是一种自动化程序或脚本&#xff0c;用于浏览万维网&#xff08;World Wide Web&#xf…

通过UV快速计算品牌独立站网络流量

背景&#xff1a; 品牌独立站项目交付过程中&#xff0c;我们需要为客户提供“云资源” 成本报价&#xff0c;其中“计算资源” 及CPU、内存、存储 参数相对固定&#xff0c;而互联网网络成本需要进行评估报价&#xff0c;以海外TOP云平台 AWS、AZURE、GCP 为例都是以“不限带…

【学术会议:中国厦门,为全球的计算机科学与管理科技研究者提供一个国际交流平台】第五届计算机科学与管理科技国际学术会议(ICCSMT 2024)

您的学术研究值得被更多人看到&#xff01; 在这里&#xff0c;我为您提供精准的会议推荐&#xff0c;包括计算机科学、管理科技、信息系统、人工智能、供应链管理等领域的国际会议。高效的稿件录用流程和优质的检索服务将确保您的研究成果迅速传播。关注我&#xff0c;寻找与…

java(2)方法的使用

目录 1.前言 2.正文 2.1方法的定义 2.2方法的调用过程 2.3方法的实参与形参 2.3.1形参 2.3.2实参 2.3.3参数传递 2.4方法的重载 3.小结 1.前言 哈喽大家好啊&#xff0c;今天博主继续带领大家学习java的基本语法&#xff0c;java的基础语法部分打算用六到七篇博文完…

828华为云征文——使用Flexus云服务器X实例CentOS镜像下创建MySQL服务器教程

一、概述 1.1 前言 当前正值华为云盛大的828 B2B企业庆典&#xff0c;其中Flexus X实例的特惠活动尤为吸引人眼球。对于追求极致算力表现&#xff0c;并期望在自建MySQL数据库、Redis缓存系统及Nginx服务器部署上获得卓越性能的企业用户而言&#xff0c;这无疑是一个不可多得的…

[Linux] Linux进程PCB内部信息的深入理解

标题&#xff1a;[Linux] Linux进程PCB内部信息的深入理解 个人主页&#xff1a;水墨不写bug &#xff08;图片来自网络&#xff09; 目录 一.查看进程 二.认识并了解进程的关键信息 I&#xff0c;PID/PPID II&#xff0c;exe III&#xff0c;cwd 三、fork&#xff08;&…

设置文件夹用VSCODE右键打开,自己修改注册表不管用,该怎么办

设置文件夹用VSCODE右键打开&#xff0c;自己修改注册表不管用&#xff1b;试了好几次&#xff0c;自己修改注册表的方法不管用。所幸直接下个新版本&#xff0c;覆盖安装&#xff0c;把这两个选项勾上就可以了。

linux-基础知识4

网络连接性测试 ping ping可以用来测试本机与目标主机的连通速度网络稳定性 ping -c 5 -s 1024 目标主机ip地址 -c 表示ping包的个数,linux如果缺省-c会一直ping下去&#xff0c;windows平台的选项是-n -s指定ping发送数据的字节数默认是84字节。windows的是-l 没有问题时会之…

2023国赛C题 蔬菜类商品的自动定价与补货决策(上)

2023国赛C题 蔬菜类商品的自动定价与补货决策&#xff08;上&#xff09; 符号说明&#xff1a; 问题1 问题1主要的代码和思路在上一篇文章“数学建模实战块速入门”中已经进行了较为详细的展示&#xff0c;在问题一种要求我们从蔬菜单品和品类两个维度去分析各自之间的关系。…

2024年中国研究生数学建模竞赛C题——解题思路

2024年中国研究生数学建模竞赛C题——解题思路 数据驱动下磁性元件的磁芯损耗建模——解决思路 二、问题描述 为解决磁性元件磁芯材料损耗精确计算问题&#xff0c;通过实测磁性元件在给定工况&#xff08;不同温度、频率、磁通密度&#xff09;下磁芯材料损耗的数据&#xf…

学习笔记——MMSR 自适应多模态融合的序列推荐

Adaptive Multi-Modalities Fusion in Sequential Recommendation Systems 前几天当我在阅读这篇论文的时候&#xff0c;在网上找到的相关资料很少&#xff0c;所以当时我读这篇论文的时候特别痛苦&#xff0c;精读了两天半.....所以现在我将自己学习笔记分享出来&#xff0c;…

服务器安全,你必须知道的六个知识点

服务器安全 如今没有什么是安全的。各种系统安全漏洞的数量呈爆炸式增长。令人担忧的主要原因之一是服务器安全性。 接下来&#xff0c;就如何提升服务器安全&#xff0c;写几点见解。 虽然很多企业在服务器的安全性方面做了足够多&#xff0c;但是&#xff0c;黑客仍然能够…

Python数据分析与可视化(Python绘图详解)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

Qt圆角窗口

Qt圆角窗口 问题&#xff1a;自己重写了一个窗口&#xff0c;发现用qss设置圆角了&#xff0c;但是都不生效&#xff0c;不过子窗口圆角都生效了。 无边框移动窗口 bool eventFilter(QObject *watched, QEvent *evt) {static QPoint mousePoint;static bool mousePressed f…

群晖Docker如何修改配置文件(ContainerManager)

群晖Docker与其他linux操作系统的docker启动方式存在差异,默认的Docker配置文件位置也不一样。所以本章教程,主要介绍如何找到群晖Docker下的默认配置文件。 一、登录SSH 为了方便操作,需要开启SSH,并通过SSH链接到群晖NAS主机。登录之后,切换到root用户 sudo -i二、编辑配…

车载测试项目实操学习:CAN通信测试、UDS诊断测试、自动化测试、功能安全测试、CAN一致性测试、HIL测试:9-20

FOTA模块中OTA的知识点&#xff1a;1.测试过程中发现哪几类问题&#xff1f; 可能就是一个单键的ecu&#xff0c;比如升了一个门的ecu&#xff0c;他的升了之后就关不上&#xff0c;还有就是升级组合ecu的时候&#xff0c;c屏上不显示进度条。 2.在做ota测试的过程中&#xff…

企业文档管理系统哪个好?2024年热门的10款文档管理系统软件推荐

在信息化时代&#xff0c;企业每天都会生成海量的文档、数据和资料。 如何有效管理这些文档&#xff0c;确保信息安全、版本控制和协同办公顺畅&#xff0c;是每个企业都必须面对的挑战。 2024年&#xff0c;随着技术的不断进步&#xff0c;市场上涌现出了众多优秀的文档管理…

Selenium自动化测试环境搭建详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 本主要介绍以Java为基础&#xff0c;搭建Selenium自动化测试环境&#xff0c;并且实现代码编写的过程。 1、Selenium介绍 Selenium 1.0 包含 core、IDE、RC、gri…

C++进阶 set和map讲解

set 和 map set 和 multiset set set 类的介绍 set 是基于红黑树实现的有序容器。它的插入、删除、查找操作的时间复杂度均为 O(log n)。遍历时&#xff0c;set 的迭代器按照中序遍历&#xff0c;因此它总是以升序排列元素。 set 的声明如下&#xff0c;T 表示 set 的关键字类…

Kubernetes集群部署(kubernetes)

三台主机恢复到docker快照状态&#xff1b; 检查驱动器类型为sytemd&#xff1b; 设置各个节点的主机名&#xff1b; 然后同步会话&#xff0c;修改hosts文件&#xff1b; 在k8s运行过程中不建议使用交换分区&#xff1b; 关闭交换分区&#xff1b; 但是这种方法是临时性的&am…