在前面我们已经把商品展示相关的逻辑已经写好了,接着我们就来编写秒杀的核心代码。这里的核心代码其实就是以下几个步骤:
1、判断当前商品的秒杀状态,例如:是否是秒杀商品,是否是秒杀时间段等,是否库存充足等。 2、减商品库存 3、为用户创建未支付订单。
所以这里我们基于上面的步骤来编写秒杀接口。
一、创建秒杀相关的表
这里我们创建一张秒杀相关的表,用户生成秒杀的订单,详细的sql如下:
CREATE TABLE `seckill_order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_no` bigint(20) DEFAULT NULL COMMENT '用户id', `order_id` bigint(20) DEFAULT NULL COMMENT '订单id', `goods_id` bigint(20) DEFAULT NULL COMMENT '商品id', `pay_status` tinyint(1) DEFAULT '1' COMMENT '支付状态,1:未支付,2:已支付', `cts` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `uts` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `u_userid_goodsid` (`user_no`,`goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
二、创建一个秒杀接口
这里我们在order-service里面新增一个秒杀的接口,示例代码如下:
/** * 秒杀商品的接口 * @param userNo * @return */ @PostMapping("/doSeckill") public BaseResponse doSeckill(@RequestHeader("userNo") String userNo,@RequestBody @Validated GoodRequest request) { return seckillService.doSeckill(userNo,request.getGoodId()); }
三、编写秒杀接口的逻辑
这里的秒杀逻辑其实就是实现上面的3个步骤,在service里面进行编写即可,示例代码如下:
public BaseResponse doSeckill(String userNo, Long goodId) { // 首先我们判断下商品状态 这里略过,因为我们这里没有涉及到商品是否销售贺不销售等情况。 // 接着我们判断下当前商品是否是秒杀商品 GoodsSeckillDto seckillInfo = goodsManager.getGoodsSeckillInfo(goodId); if (null == seckillInfo) { return BaseResponse.fail(HttpStatusCode.GOODNOTSECKILL); } // 判断当前商品当前用户是否已经秒杀成功过了,如果有秒杀过,则返回不能再抢。这里由于我们一会要做并发测试,因此这里我们暂时不做此判断。 // 判断当前时间段是不是秒杀时间段 Long currentTime = new Date().getTime(); if (!(currentTime < seckillInfo.getEndDate().getTime() && currentTime > seckillInfo.getStartDate().getTime())) { return BaseResponse.fail(HttpStatusCode.GOODNOTSECKILLTIME); } // 判断库存 if (seckillInfo.getStockCount() < 1) { return BaseResponse.fail(HttpStatusCode.GOODSTOCKNOTENOUGH); } // 接着就可以下单了。 减库存->为用户增加未订单 Boolean success = goodsClient.reduceGoodStock(GoodRequest.builder().goodId(goodId).build()); if (!success) { return BaseResponse.fail(HttpStatusCode.GOODSTOCKNOTENOUGH); } // 获取用户信息 BaseResponse response = userClient.getUserInfoByNos(UserRequest.builder().userNos(userNo).build()); if (!response.isOk()) { return BaseResponse.fail(HttpStatusCode.ORDERFAILS); } // 创建订单 SeckillOrderDto newOrder = SeckillOrderDto.builder().userNo(userNo).orderId(IdWorker.getId()).goodsId(goodId) .build(); Boolean suc = odersManager.createNewSeckillOrder(newOrder); return suc ? BaseResponse.ok() : BaseResponse.fail(HttpStatusCode.ORDERFAILS); }
这里我们的秒杀接口就编写完了,然后我们测试一下,这里我们使用商品id为1的商品进行秒杀,所以这里我们把秒杀时间段修改下,然后把库存置为1,示例图如下:
然后我们启动所有的服务:
然后我们进行请求这个秒杀接口:
可以看到秒杀成功了,然后我们看看商品库存是否减了:
库存已经变成了0,然后再看看是否生成了用户未支付的订单:
可以看到未支付的订单已经生成,没有任何问题。然后再请求一次秒杀,可以看到已经提示库存不足了:
以上我们就实现了秒杀的核心代码逻辑。
备注:
1、这里我们只是实现秒杀的核心逻辑,具体的其他细节等方面在后面的文章介绍。
最后按照惯例,附上本案例的源码,登陆后即可下载。
还没有评论,来说两句吧...