浏览代码

修改库存时,判断库存库存是否发生变动

caotao 1 周之前
父节点
当前提交
ea9886438b

+ 2 - 1
ship-module-product/ship-module-product-api/src/main/java/com/yc/ship/module/product/enums/ErrorCodeConstants.java

@@ -43,6 +43,7 @@ public interface ErrorCodeConstants {
 
     ErrorCode VOYAGE_NO_STOCK = new ErrorCode(10_028, "该航次未设置库存");
 
+
     ErrorCode VOYAGE_SHARE_STOCK_NOT_ENOUGH = new ErrorCode(10_029, "该航次共享库存不足,库存为:%s,需要库存:%s");
 
     ErrorCode VOYAGE_SHARE_ROOM_NOT_ENOUGH = new ErrorCode(10_030, "共享库存-%s-%sF可售房间不足, 库存为:%s, 需要库存:%s");
@@ -50,7 +51,7 @@ public interface ErrorCodeConstants {
     ErrorCode VOYAGE_DISTRIBUTOR_ROOM_NOT_ENOUGH = new ErrorCode(10_031, "分销商库存-%s-%sF可售房间不足, 库存为:%s, 需要库存: %s");
 
     ErrorCode VOYAGE_ROOM_NOT_EXIST = new ErrorCode(10_032, "订单所选房间%s不存在");
-
+    ErrorCode VOYAGE_STOCK_CHANGED = new ErrorCode(10_033, "该航次库存数有变动,请刷新页面后重新设置");
     ErrorCode VOYAGE_DATA_NOT_EXISTS = new ErrorCode(10_200, "航行数据不存在");
     ErrorCode REDD_DATA_NOT_EXISTS = new ErrorCode(10_201, "碳排放指标管理不存在");
 

+ 1 - 0
ship-module-product/ship-module-product-api/src/main/java/com/yc/ship/module/product/enums/ProductStockStaticsName.java

@@ -9,5 +9,6 @@ public interface ProductStockStaticsName {
     public static final String CAN_SELL_NUM = "可售房间数";
     public static final String OVERSOLD_NUM = "超卖房间数";
     public static final String SURPLUS_NUM = "剩余房间数";
+    public static final String IN_ROOM = "内舱房";
     public static final String TOTAL = "合计";
 }

+ 44 - 5
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/service/voyagestockdetail/VoyageStockDetailServiceImpl.java

@@ -38,6 +38,9 @@ import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static com.yc.ship.module.product.enums.ErrorCodeConstants.VOYAGE_STOCK_CHANGED;
+
 /**
  * 航次库存 Service 实现类
  *
@@ -79,8 +82,32 @@ public class VoyageStockDetailServiceImpl implements VoyageStockDetailService {
         RLock lock = redissonClient.getLock(lockKey);
         try {
             lock.lock(60, TimeUnit.SECONDS);
-            voyageStockDetailMapper.deleteByVoyageId(voyageId);
+            // 获取数据库中现在的库存详情数
+            List<VoyageStockDetailDO> detailDos = voyageStockDetailMapper.selectListByVoyageId(voyageId);
             List<VoyageStockDetailDO> list = BeanUtils.toBean(createReqVO, VoyageStockDetailDO.class);
+            // 现有库存数中的预约数、实际房间数和修改的预约数、实际房间数比较,如果不一致,则返回库存数有变动,请刷新页面后重新设置
+            Map<String, VoyageStockDetailDO> existMap = detailDos.stream()
+                    .collect(Collectors.toMap(
+                            item -> item.getRoomModelId() + "_" + item.getFloor(),
+                            item -> item,
+                            (a, b) -> a));
+            for (VoyageStockDetailDO reqItem : list) {
+                // 排除合计和内舱房
+                if(ProductStockStaticsName.TOTAL.equals(reqItem.getRoomModelName()) || ProductStockStaticsName.IN_ROOM.equals(reqItem.getRoomModelName())) {
+                    continue;
+                }
+                String key = reqItem.getRoomModelId() + "_" + reqItem.getFloor();
+                VoyageStockDetailDO exist = existMap.get(key);
+                if (exist == null) {
+                    // 现有库存里没有该房型楼层,视为已被变动(如被删除/新增)
+                    throw exception(VOYAGE_STOCK_CHANGED);
+                }
+                if (!equalsBigDecimal(exist.getBookNum(), reqItem.getBookNum())
+                        || !equalsBigDecimal(exist.getRealTotalNum(), reqItem.getRealTotalNum())) {
+                    throw exception(VOYAGE_STOCK_CHANGED);
+                }
+            }
+            voyageStockDetailMapper.deleteByVoyageId(voyageId);
             List<VoyageStockDetailDO> insertList = new ArrayList<>();
             list.stream().forEach(item -> {
                 if(ProductStockStaticsName.TOTAL.equals(item.getRoomModelName())) {
@@ -93,10 +120,6 @@ public class VoyageStockDetailServiceImpl implements VoyageStockDetailService {
                 }
             });
             Boolean aBoolean = voyageStockDetailMapper.insertBatch(insertList);
-            // 设置缓存
-            if(aBoolean) {
-                productRedisUtils.set(ProductRedisKeyConstants.STOCK_DETAIL_REDIS_KEY_PREFIX + voyageId, insertList);
-            }
             return aBoolean;
         }finally {
             if(lock.isHeldByCurrentThread() && lock.isLocked()){
@@ -105,6 +128,22 @@ public class VoyageStockDetailServiceImpl implements VoyageStockDetailService {
         }
     }
 
+    /**
+     * 比较两个 BigDecimal 是否相等
+     * @param a
+     * @param b
+     * @return
+     */
+    private boolean equalsBigDecimal(BigDecimal a, BigDecimal b) {
+        if (a == null && b == null) {
+            return true;
+        }
+        if (a == null || b == null) {
+            return false;
+        }
+        return a.compareTo(b) == 0;   // 用 compareTo 避免 1.0 与 1.00 被判不等
+    }
+
     /**
      * 处理共享库存
      * @param voyageId