From e4b968e0af58bffa87bbc68bf482be1ba6dfd46f Mon Sep 17 00:00:00 2001 From: Chopper Date: Thu, 17 Jun 2021 10:37:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BA=93=E5=AD=98=E6=89=A3=E5=87=8F=EF=BC=8C?= =?UTF-8?q?=E5=BA=93=E5=AD=98=E5=9B=9E=E6=BB=9A=E9=97=AE=E9=A2=98=E5=A4=84?= =?UTF-8?q?=E7=90=86=E3=80=82=20=E4=B9=8B=E5=89=8D=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E5=95=86=E5=93=81=E5=8F=96=E6=B6=88=E5=90=8E=EF=BC=8C=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=9B=9E=E6=BB=9A=E5=BA=93=E5=AD=98=EF=BC=8C=E5=8F=AF?= =?UTF-8?q?=E6=98=AF=E5=BF=BD=E7=95=A5=E4=BA=86=E5=95=86=E5=93=81=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E5=8F=AF=E8=83=BD=E6=98=AF=E5=9B=A0=E4=B8=BA=E5=BA=93?= =?UTF-8?q?=E5=AD=98=E4=B8=8D=E8=B6=B3=E5=AF=BC=E8=87=B4=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lili/event/impl/StockUpdateExecute.java | 80 +++++++++++++++---- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/consumer/src/main/java/cn/lili/event/impl/StockUpdateExecute.java b/consumer/src/main/java/cn/lili/event/impl/StockUpdateExecute.java index aa226c27..c8449df3 100644 --- a/consumer/src/main/java/cn/lili/event/impl/StockUpdateExecute.java +++ b/consumer/src/main/java/cn/lili/event/impl/StockUpdateExecute.java @@ -12,6 +12,7 @@ import cn.lili.modules.order.order.service.OrderService; import cn.lili.modules.promotion.entity.dos.PromotionGoods; import cn.lili.modules.promotion.entity.enums.PromotionTypeEnum; import cn.lili.modules.promotion.service.PromotionGoodsService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; @@ -26,9 +27,12 @@ import java.util.List; * @author Chopper * @date 2020-07-03 11:20 */ +@Slf4j @Service public class StockUpdateExecute implements OrderStatusChangeEvent { + //出库失败消息 + static String outOfStockMessage = "库存不足,出库失败"; //Redis @Autowired private StringRedisTemplate stringRedisTemplate; @@ -52,7 +56,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent { switch (orderMessage.getNewStatus()) { case PAID: { - + //获取订单详情 OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn()); //库存key 和 扣减数量 List keys = new ArrayList<>(); @@ -67,33 +71,41 @@ public class StockUpdateExecute implements OrderStatusChangeEvent { Boolean skuResult = stringRedisTemplate.execute(quantityScript, keys, values.toArray()); //如果库存扣减都成功,则记录成交订单 if (Boolean.TRUE.equals(skuResult)) { + log.info("库存扣减成功,参数为{};{}", keys, values); //库存确认之后对结构处理 orderService.afterOrderConfirm(orderMessage.getOrderSn()); //成功之后,同步库存 synchroDB(order); } else { + log.info("库存扣件失败,变更缓存key{} 变更缓存value{}", keys, values); //失败之后取消订单 this.errorOrder(orderMessage.getOrderSn()); } break; } case CANCELLED: { - + //获取订单详情 OrderDetailVO order = orderService.queryDetail(orderMessage.getOrderSn()); - if (order.getOrder().getPayStatus().equals(PayStatusEnum.PAID.name())) { + //判定是否已支付 并且 非库存不足导致库存回滚 则需要考虑订单库存返还业务 + if (order.getOrder().getPayStatus().equals(PayStatusEnum.PAID.name()) && order.getOrder().getCancelReason().equals(outOfStockMessage)) { + //库存key 和 还原数量 + List keys = new ArrayList<>(); + List values = new ArrayList<>(); + + //返还商品库存,促销库存不与返还,不然前台展示层有展示逻辑错误 for (OrderItem orderItem : order.getOrderItems()) { - if (PromotionTypeEnum.haveStock(orderItem.getPromotionType())) { - PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType()); - Integer goodsPromotionOriginStock = promotionGoodsService.getPromotionGoodsStock(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId()); - int goodsPromotionStock = goodsPromotionOriginStock + orderItem.getNum(); - String promotionGoodsStockCacheKey = PromotionGoodsService.getPromotionGoodsStockCacheKey(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId()); - stringRedisTemplate.opsForValue().set(promotionGoodsStockCacheKey, Integer.toString(goodsPromotionStock)); - } - String stockCacheKey = GoodsSkuService.getStockCacheKey(orderItem.getSkuId()); - Integer goodsOriginStock = goodsSkuService.getStock(orderItem.getSkuId()); - int goodsStock = goodsOriginStock + orderItem.getNum(); - stringRedisTemplate.opsForValue().set(stockCacheKey, Integer.toString(goodsStock)); + keys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId())); + int i = orderItem.getNum(); + values.add(Integer.toString(i)); } + //批量脚本执行库存回退 + Boolean skuResult = stringRedisTemplate.execute(quantityScript, keys, values.toArray()); + + //返还失败,则记录日志 + if (Boolean.FALSE.equals(skuResult)) { + log.error("库存回退异常,keys:{},回复库存值为: {}", keys, values); + } + rollbackOrderStock(order); } break; } @@ -108,7 +120,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent { * @param orderSn 失败入库订单信息 */ private void errorOrder(String orderSn) { - orderService.systemCancel(orderSn, "库存不足,出库失败"); + orderService.systemCancel(orderSn, outOfStockMessage); } @@ -132,8 +144,9 @@ public class StockUpdateExecute implements OrderStatusChangeEvent { } } + /** - * 写入需要更改促销库存的商品 + * 同步库存和促销库存 * * @param order 订单 */ @@ -159,6 +172,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent { if (PromotionTypeEnum.haveStock(orderItem.getPromotionType())) { PromotionTypeEnum promotionTypeEnum = PromotionTypeEnum.valueOf(orderItem.getPromotionType()); PromotionGoods pGoods = promotionGoodsService.getPromotionGoods(promotionTypeEnum, orderItem.getPromotionId(), orderItem.getSkuId()); + //记录需要更新的促销库存信息 promotionKey.add( PromotionGoodsService.getPromotionGoodsStockCacheKey( promotionTypeEnum, @@ -170,6 +184,7 @@ public class StockUpdateExecute implements OrderStatusChangeEvent { goodsSkus.add(goodsSku); } + //批量获取商品库存 List skuStocks = cache.multiGet(skuKeys); //循环写入商品库存 for (int i = 0; i < skuStocks.size(); i++) { @@ -188,8 +203,41 @@ public class StockUpdateExecute implements OrderStatusChangeEvent { } promotionGoodsService.updateBatchById(promotionGoods); } + //商品库存,包含sku库存集合,批量更新商品库存相关 goodsSkuService.updateGoodsStuck(goodsSkus); + log.info("订单确认,库存同步:商品信息--{};促销信息---{}", goodsSkus, promotionGoods); + } + /** + * 恢复商品库存 + * + * @param order 订单 + */ + private void rollbackOrderStock(OrderDetailVO order) { + + //sku商品 + List goodsSkus = new ArrayList<>(); + //sku库存key 集合 + List skuKeys = new ArrayList<>(); + // 循环订单 + for (OrderItem orderItem : order.getOrderItems()) { + skuKeys.add(GoodsSkuService.getStockCacheKey(orderItem.getSkuId())); + GoodsSku goodsSku = new GoodsSku(); + goodsSku.setId(orderItem.getSkuId()); + goodsSkus.add(goodsSku); + } + //批量获取商品库存 + List skuStocks = cache.multiGet(skuKeys); + //循环写入商品SKU库存 + for (int i = 0; i < skuStocks.size(); i++) { + goodsSkus.get(i).setQuantity(Integer.parseInt(skuStocks.get(i).toString())); + } + log.info("订单取消,库存还原:{}", goodsSkus); + //批量修改商品库存 + goodsSkuService.updateBatchById(goodsSkus); + goodsSkuService.updateGoodsStuck(goodsSkus); + + } }