Browse Source

fix: 处理库存操作时涉及虚拟库存的问题

luofeiyun 1 week atrás
parent
commit
c4ca69553f

+ 34 - 28
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/api/VoyageApiImpl.java

@@ -29,6 +29,7 @@ import com.yc.ship.module.product.service.voyagestockdistribute.VoyageStockDistr
 import com.yc.ship.module.product.utils.ProductRedisUtils;
 import com.yc.ship.module.trade.enums.TradeOrderStatusEnum;
 import lombok.extern.slf4j.Slf4j;
+import me.zhyd.oauth.utils.UuidUtils;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.stereotype.Service;
@@ -93,8 +94,10 @@ public class VoyageApiImpl implements VoyageApi {
         //现在给整个航次的库存加锁
         String lockKey = String.format(ProductRedisKeyConstants.STOCK_REDIS_KEY_PREFIX, voyageId);
         RLock lock = redissonClient.getLock(lockKey);
+        //用来控制redis缓存
         try {
             lock.lock(60, TimeUnit.SECONDS);
+            String uuid = UuidUtils.getUUID();
             //判断是分销商还是门店下单 1:分销商,2:门店
             Integer type = reqDTO.getType();
             //分销商下单,当前阶段不考虑门店下单
@@ -102,14 +105,14 @@ public class VoyageApiImpl implements VoyageApi {
                 //分销商下单只扣分销商库存,默认是OTA,默认OTC只能门店下单
                 //初定扣分销商库存
                 //先返还初定扣的库存,使用修改前一步订单的 ID
-                preCancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                preCancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                 log.info("先还该订单的库存-orderId: {}", reqDTO.getOrderId());
                 if (reqDTO.getOldOrderId() != null && !reqDTO.getOldOrderId().equals(reqDTO.getOrderId())) {
                     log.info("如果是修改就还修改前的订单的库存-oldOrderId: {}", reqDTO.getOldOrderId());
-                    preCancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                    preCancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                 }
                 //再去扣初定的库存
-                preReduceStockDistributor(reqDTO);
+                preReduceStockDistributor(reqDTO, uuid);
             }
         } finally {
             if (lock.isHeldByCurrentThread() && lock.isLocked()) {
@@ -129,15 +132,16 @@ public class VoyageApiImpl implements VoyageApi {
         RLock lock = redissonClient.getLock(lockKey);
         try {
             lock.lock(60, TimeUnit.SECONDS);
+            String uuid = UuidUtils.getUUID();
             //判断是分销商还是门店下单 1:分销商,2:门店
             Integer type = reqDTO.getType();
             //分销商下单,当前阶段不考虑门店下单
             if (Objects.equals(type, DistributorOrStoreEnum.DISTRIBUTOR.getValue())) {
                 //分销商下单只扣分销商库存,默认是OTA,默认OTC只能门店下单
                 //初定扣分销商库存
-                preCancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                preCancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                 if (reqDTO.getOldOrderId() != null && !reqDTO.getOldOrderId().equals(reqDTO.getOrderId())) {
-                    preCancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                    preCancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                 }
             }
         } finally {
@@ -158,6 +162,7 @@ public class VoyageApiImpl implements VoyageApi {
         RLock lock = redissonClient.getLock(lockKey);
         try {
             lock.lock(60, TimeUnit.SECONDS);
+            String uuid = UuidUtils.getUUID();
             //判断是分销商还是门店下单 1:分销商,2:门店
             Integer type = reqDTO.getType();
             //分销商下单,当前阶段不考虑门店下单
@@ -165,16 +170,16 @@ public class VoyageApiImpl implements VoyageApi {
                 //分销商下单只扣分销商库存,默认是OTA,默认OTC只能门店下单
                 //初定扣分销商库存
                 //先返还初定扣的库存
-                preCancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                preCancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                 if(reqDTO.getOldOrderId() != null && !reqDTO.getOldOrderId().equals(reqDTO.getOrderId())) {
                     if(reqDTO.getOldOrderStatus() != null && reqDTO.getOldOrderStatus().equals(TradeOrderStatusEnum.YD.getStatus())) {
-                        preCancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                        preCancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                     }else {
-                        cancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                        cancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                     }
                 }
                 //再去扣确定的库存
-                reduceStockDistributor(reqDTO);
+                reduceStockDistributor(reqDTO, uuid);
             }
         } catch (Exception e) {
             TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@@ -197,15 +202,16 @@ public class VoyageApiImpl implements VoyageApi {
         RLock lock = redissonClient.getLock(lockKey);
         try {
             lock.lock(60, TimeUnit.SECONDS);
+            String uuid = UuidUtils.getUUID();
             //判断是分销商还是门店下单 1:分销商,2:门店
             Integer type = reqDTO.getType();
             //分销商下单,当前阶段不考虑门店下单
             if (Objects.equals(type, DistributorOrStoreEnum.DISTRIBUTOR.getValue())) {
                 //分销商下单只扣分销商库存,默认是OTA,默认OTC只能门店下单
                 //初定扣分销商库存
-                cancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                cancelReduceStockDistributor(reqDTO.getOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                 if (reqDTO.getOldOrderId() != null && !reqDTO.getOldOrderId().equals(reqDTO.getOrderId())) {
-                    cancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList());
+                    cancelReduceStockDistributor(reqDTO.getOldOrderId(), reqDTO.getType(),reqDTO.getOrderRoomList(), uuid);
                 }
             }
         } finally {
@@ -219,7 +225,7 @@ public class VoyageApiImpl implements VoyageApi {
      * 确定状态时取消订单还库存
      * roomUseDTOList 需要退的房间
      */
-    private void cancelReduceStockDistributor(Long orderId, Integer type,List<OrderRoomUseDTO> roomUseDTOList) {
+    private void cancelReduceStockDistributor(Long orderId, Integer type,List<OrderRoomUseDTO> roomUseDTOList, String uuid) {
         if (orderId == null) {
             return;
         }
@@ -249,7 +255,7 @@ public class VoyageApiImpl implements VoyageApi {
             stockDO.setBookNum(stockDO.getBookNum().subtract(totalNum));
             //更新航次总库存
             voyageStockMapper.updateById(stockDO);
-            productRedisUtils.set(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId, stockDO);
+            productRedisUtils.set(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, stockDO);
             //删除航次库存操作记录
             voyageStockLogMapper.deleteById(voyageStockLogDO);
         } else {
@@ -295,7 +301,7 @@ public class VoyageApiImpl implements VoyageApi {
                 }
             });
             voyageStockDetailMapper.updateBatch(stockDetailList);
-            productRedisUtils.set(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId, stockDetailList);
+            productRedisUtils.set(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, stockDetailList);
 
 
             //2:还分销商库存
@@ -314,7 +320,7 @@ public class VoyageApiImpl implements VoyageApi {
                         item.setBookNum(item.getBookNum() == null ? BigDecimal.ZERO : item.getBookNum().subtract(totalNumMap.get(key)));
                     });
                     voyageStockDistributeNewMapper.updateBatch(list);
-                    productRedisUtils.set(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId, list);
+                    productRedisUtils.set(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId + "_" + uuid, list);
                 }
             }
             // 删除库存详情初定记录
@@ -326,7 +332,7 @@ public class VoyageApiImpl implements VoyageApi {
     /**
      * 确定时扣库存,有限扣实际库存,不足再扣虚拟库存
      */
-    private void reduceStockDistributor(ReduceStockReqDTO reqDTO) {
+    private void reduceStockDistributor(ReduceStockReqDTO reqDTO, String uuid) {
         //航次库存操作日志
         VoyageStockLogDO voyageStockLogDO = new VoyageStockLogDO();
         //航次库存详情操作日志
@@ -353,7 +359,7 @@ public class VoyageApiImpl implements VoyageApi {
         voyageStockLogDO.setDistributorId(distributorId);
         voyageStockLogDO.setStoreId(storeId);
         // 获取航次总库存
-        VoyageStockDO stockDO = productRedisUtils.get(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId, VoyageStockDO.class, 1);
+        VoyageStockDO stockDO = productRedisUtils.get(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, VoyageStockDO.class, 1);
         if (stockDO == null) {
             stockDO = voyageStockMapper.selectById(voyageId);
         }
@@ -366,7 +372,7 @@ public class VoyageApiImpl implements VoyageApi {
 
         //航次库存详情
         //航次库存详情
-        List<VoyageStockDetailDO> stockDetailList = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId, VoyageStockDetailDO.class, 1);
+        List<VoyageStockDetailDO> stockDetailList = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, VoyageStockDetailDO.class, 1);
         if (CollectionUtils.isAnyEmpty(stockDetailList)) {
             stockDetailList = voyageStockDetailMapper.selectListByVoyageId(voyageId);
         }
@@ -377,7 +383,7 @@ public class VoyageApiImpl implements VoyageApi {
         detailReqVO.setDistributorId(distributorId);
         //先获取非共享库存(分销商库存)
         detailReqVO.setEnableShare(YesOrNoEnum.NO.getType());
-        List<VoyageStockDistributeNewRespVO> distributeNewResps = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId, VoyageStockDistributeNewRespVO.class, 1);
+        List<VoyageStockDistributeNewRespVO> distributeNewResps = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId + "_" + uuid, VoyageStockDistributeNewRespVO.class, 1);
         if (CollectionUtils.isAnyEmpty(distributeNewResps)) {
             distributeNewResps = voyageStockDistributeNewService.getDetail(detailReqVO);
         }
@@ -624,7 +630,7 @@ public class VoyageApiImpl implements VoyageApi {
     /**
      * 初定取消还分销商库存
      */
-    private void preCancelReduceStockDistributor(Long orderId, Integer type,List<OrderRoomUseDTO> orderRoomUseDTOList) {
+    private void preCancelReduceStockDistributor(Long orderId, Integer type,List<OrderRoomUseDTO> orderRoomUseDTOList, String uuid) {
         if (orderId == null) {
             return;
         }
@@ -655,7 +661,7 @@ public class VoyageApiImpl implements VoyageApi {
             stockDO.setBookNum(stockDO.getBookNum().subtract(totalNum));
             //更新航次总库存
             voyageStockMapper.updateById(stockDO);
-            productRedisUtils.set(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId, stockDO);
+            productRedisUtils.set(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, stockDO);
             //删除航次库存操作记录
             voyageStockLogMapper.deleteById(voyageStockLogDO);
         } else {
@@ -694,7 +700,7 @@ public class VoyageApiImpl implements VoyageApi {
             }
         });
         voyageStockDetailMapper.updateBatch(stockDetailList);
-        productRedisUtils.set(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId, stockDetailList);
+        productRedisUtils.set(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, stockDetailList);
 
 
         //2:还分销商库存
@@ -725,7 +731,7 @@ public class VoyageApiImpl implements VoyageApi {
                 });
                 log.info("进入初定还分销商库存详情操作,分销商库存还之后详情-distributeNewRespList:{}", JSONArray.toJSONString(distributeNewRespList));
                 voyageStockDistributeNewMapper.updateBatch(list);
-                productRedisUtils.set(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId, list);
+                productRedisUtils.set(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId + "_" + uuid, list);
             }
         }
         // 删除库存详情初定记录
@@ -737,7 +743,7 @@ public class VoyageApiImpl implements VoyageApi {
     /**
      * 初定扣分销商库存
      */
-    private void preReduceStockDistributor(ReduceStockReqDTO reqDTO) {
+    private void preReduceStockDistributor(ReduceStockReqDTO reqDTO, String uuid) {
         log.info("进入初定扣库存操作-orderId:{}", reqDTO.getOrderId());
         //航次库存操作日志
         VoyageStockLogDO voyageStockLogDO = new VoyageStockLogDO();
@@ -765,7 +771,7 @@ public class VoyageApiImpl implements VoyageApi {
         voyageStockLogDO.setDistributorId(distributorId);
         voyageStockLogDO.setStoreId(storeId);
         // 获取航次总库存
-        VoyageStockDO stockDO = productRedisUtils.get(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId, VoyageStockDO.class, 1);
+        VoyageStockDO stockDO = productRedisUtils.get(ProductRedisKeyConstants.STOCK_TOTAL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, VoyageStockDO.class, 1);
         if (stockDO == null) {
             stockDO = voyageStockMapper.selectById(voyageId);
         }
@@ -776,7 +782,7 @@ public class VoyageApiImpl implements VoyageApi {
         BigDecimal shareNum = stockDO.getShareNum();
 
         //航次库存详情
-        List<VoyageStockDetailDO> stockDetailList = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId, VoyageStockDetailDO.class, 1);
+        List<VoyageStockDetailDO> stockDetailList = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId + "_" + uuid, VoyageStockDetailDO.class, 1);
         if (CollectionUtils.isAnyEmpty(stockDetailList)) {
             stockDetailList = voyageStockDetailMapper.selectListByVoyageId(voyageId);
         }
@@ -787,7 +793,7 @@ public class VoyageApiImpl implements VoyageApi {
         detailReqVO.setDistributorId(distributorId);
         //先获取非共享库存(分销商库存)
         detailReqVO.setEnableShare(YesOrNoEnum.NO.getType());
-        List<VoyageStockDistributeNewRespVO> distributeNewRespList = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId, VoyageStockDistributeNewRespVO.class, 1);
+        List<VoyageStockDistributeNewRespVO> distributeNewRespList = productRedisUtils.getList(ProductRedisKeyConstants.STOCK_DISTRIBUTOR_REDIS_KEY_PREFIX + voyageId + "_" + distributorId + "_" + uuid, VoyageStockDistributeNewRespVO.class, 1);
         if (CollectionUtils.isAnyEmpty(distributeNewRespList)) {
             distributeNewRespList = voyageStockDistributeNewService.getDetail(detailReqVO);
         }
@@ -857,9 +863,9 @@ public class VoyageApiImpl implements VoyageApi {
                 } else {
                     voyageStockDetailLogDO.setVirtualNum(item.getVirtualNum());
                     voyageStockDetailLogDO.setRealNum(useNum.subtract(item.getVirtualNum()));
-                    item.setVirtualNum(BigDecimal.ZERO);
                     // 扣实际房间数
                     item.setRealTotalNum(item.getRealTotalNum().subtract(useNum.subtract(item.getVirtualNum())));
+                    item.setVirtualNum(BigDecimal.ZERO);
                 }
                 // 加预定房间数
                 if (item.getBookNum() != null) {

+ 7 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/voyage/VoyageServiceImpl.java

@@ -368,10 +368,17 @@ public class VoyageServiceImpl implements VoyageService {
                 priceRoomModelList.forEach(priceRoomModelDO -> {
                     priceRoomModelDO.setObjectId(priceVoyageId);
                     List<PriceRoomModelTypeDO> roomModelTypeList = priceRoomModelDO.getRoomModelTypeList();
+                    if(CollectionUtils.isAnyEmpty(roomModelTypeList)) {
+                        return;
+                    }
                     roomModelTypeList.forEach(roomModelType -> {
                         roomModelType.setObjectId(priceVoyageId);
                         PriceSingleSettingDO singleSetting = roomModelType.getSingleSetting();
+                        if(singleSetting == null) {
+                            return;
+                        }
                         singleSetting.setObjectId(priceVoyageId);
+
                     });
                 });
                 priceVoyageSaveReqVO.setRoomModelList(priceRoomModelList);