浏览代码

feat: 添加扣库存接口

luofeiyun 1 月之前
父节点
当前提交
2344c035ad

+ 15 - 0
ship-module-product/ship-module-product-api/src/main/java/com/yc/ship/module/product/api/VoyageApi.java

@@ -0,0 +1,15 @@
+package com.yc.ship.module.product.api;
+
+import com.yc.ship.module.product.api.dto.ReduceStockReqDTO;
+
+/**
+ * 航次相关对外接口
+ */
+public interface VoyageApi {
+
+    /**
+     * 预减库存
+     * @param reqDTO 请求参数
+     */
+    void preReduceStock(ReduceStockReqDTO reqDTO);
+}

+ 46 - 0
ship-module-product/ship-module-product-api/src/main/java/com/yc/ship/module/product/api/dto/ReduceStockReqDTO.java

@@ -0,0 +1,46 @@
+package com.yc.ship.module.product.api.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "减库存请求参数")
+@Data
+public class ReduceStockReqDTO {
+
+    @Schema(description = "订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long OrderId;
+
+    @Schema(description = "航次ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long voyageId;
+
+    @Schema(description = "分销商类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer distributorType;
+
+    @Schema(description = "分销商ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long distributorId;
+
+    @Schema(description = "门店ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long storeId;
+
+    @Schema(description = "订单使用房间详情列表")
+    List<OrderDetailReqDTO> orderDetailList;
+
+
+    @Data
+    @Schema(description = "订单使用房间详情")
+    public static class OrderDetailReqDTO {
+
+
+        @Schema(description = "房型ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+        private Long roomModelId;
+
+        @Schema(description = "楼层号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+        private Integer floor;
+
+        @Schema(description = "房间数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+        private Integer num;
+    }
+
+}

+ 126 - 0
ship-module-product/ship-module-product-biz/src/main/java/com/yc/ship/module/product/api/VoyageApiImpl.java

@@ -0,0 +1,126 @@
+package com.yc.ship.module.product.api;
+
+import com.yc.ship.framework.common.util.collection.CollectionUtils;
+import com.yc.ship.module.product.api.dto.ReduceStockReqDTO;
+import com.yc.ship.module.product.dal.dataobject.voyagestock.VoyageStockDO;
+import com.yc.ship.module.product.dal.dataobject.voyagestockdetail.VoyageStockDetailDO;
+import com.yc.ship.module.product.dal.dataobject.voyagestockdistribute.VoyageStockDistributeDO;
+import com.yc.ship.module.product.dal.mysql.voyagestock.VoyageStockMapper;
+import com.yc.ship.module.product.dal.mysql.voyagestockdetail.VoyageStockDetailMapper;
+import com.yc.ship.module.product.dal.mysql.voyagestockdistribute.VoyageStockDistributeMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception0;
+
+@Service
+public class VoyageApiImpl implements VoyageApi{
+
+    @Resource
+    private VoyageStockDistributeMapper voyageStockDistributeMapper;
+
+    @Resource
+    private VoyageStockMapper voyageStockMapper;
+
+    @Resource
+    private VoyageStockDetailMapper voyageStockDetailMapper;
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    //TODO: 待完善 加锁
+    public void preReduceStock(ReduceStockReqDTO reqDTO) {
+        // 1.扣门店库存
+        // 2.扣分销商库存
+        // 3.扣分销商类型库存
+        // 4.扣航次库存,优先扣虚拟库存
+
+        Integer distributorType = reqDTO.getDistributorType();
+        Long voyageId = reqDTO.getVoyageId();
+        Long distributorId = reqDTO.getDistributorId();
+        Long storeId = reqDTO.getStoreId();
+
+
+        // 1.扣门店库存
+        // 2.扣分销商库存
+        // 3.扣分销商类型库存
+        List<VoyageStockDistributeDO> distributeDOList = voyageStockDistributeMapper.selectListByVoyageId(voyageId);
+        List<ReduceStockReqDTO.OrderDetailReqDTO> orderDetailList = reqDTO.getOrderDetailList();
+        Map<String, ReduceStockReqDTO.OrderDetailReqDTO> map = CollectionUtils.convertMap(orderDetailList, item -> {
+            String key = distributorType + "_" + distributorId + "_" + storeId + "_" + item.getRoomModelId() + "_" + item.getFloor();
+            return key;
+        });
+        AtomicReference<Integer> totalNum = new AtomicReference<>(0);
+        List<VoyageStockDistributeDO> updateList = new ArrayList<>();
+        distributeDOList.stream().forEach(item -> {
+            String key = item.getDistributorType() + "_" + item.getDistributorId() + "_" + item.getStoreId() + "_" + item.getRoomModelId() + "_" + item.getFloor();
+            ReduceStockReqDTO.OrderDetailReqDTO orderDetailReqDTO = map.get(key);
+            if (orderDetailReqDTO != null) {
+                item.setSurplusNum(item.getSurplusNum() - orderDetailReqDTO.getNum());
+                item.setBookNum(item.getBookNum() + orderDetailReqDTO.getNum());
+                updateList.add(item);
+            }
+            totalNum.updateAndGet(v -> v + item.getNum());
+        });
+        Integer total = totalNum.get();
+        voyageStockDistributeMapper.updateBatch(updateList);
+
+        // 4.扣航次库存,优先扣虚拟库存
+        VoyageStockDO stockDO = voyageStockMapper.selectById(voyageId);
+        //判断可售房间数是否大于等于订单的房间数
+        if(stockDO.getCanSellNum() < total) {
+            throw exception0(500,"可售房间数不足");
+        }
+        //减虚拟房间数
+        if(stockDO.getVirtualNum() >= total) {
+            stockDO.setVirtualNum(stockDO.getVirtualNum() - totalNum.get());
+        }else {
+            stockDO.setVirtualNum(0);
+            // 加超卖房间数
+            stockDO.setOversoldNum(stockDO.getOversoldNum() + (total - stockDO.getVirtualNum()));
+        }
+        //减可售房间数
+        stockDO.setCanSellNum(stockDO.getCanSellNum() - total);
+        //加预定房间数
+        stockDO.setBookNum(stockDO.getBookNum() + total);
+        voyageStockMapper.updateById(stockDO);
+
+        // 5.扣库存详情
+        Map<String, ReduceStockReqDTO.OrderDetailReqDTO> detailMap = CollectionUtils.convertMap(orderDetailList, item -> {
+            String key = item.getRoomModelId() + "_" + item.getFloor();
+            return key;
+        });
+        List<VoyageStockDetailDO> stockDetailList = voyageStockDetailMapper.selectListByVoyageId(voyageId);
+        List<VoyageStockDetailDO> updateDetailList = new ArrayList<>();
+        stockDetailList.stream().forEach(item -> {
+            String key = item.getRoomModelId() + "_" + item.getFloor();
+            ReduceStockReqDTO.OrderDetailReqDTO orderDetailReqDTO = detailMap.get(key);
+            Integer num = orderDetailReqDTO.getNum();
+            if (orderDetailReqDTO != null) {
+                //判断可售房间数是否大于等于订单的房间数
+                if(item.getCanSellNum() < num) {
+                    throw exception0(500,"房型楼层可售房间数不足");
+                }
+                //减虚拟房间数
+                if(item.getVirtualNum() >= num) {
+                    item.setVirtualNum(item.getVirtualNum() - num);
+                }else {
+                    item.setVirtualNum(0);
+                    // 加超卖房间数
+                    item.setOversoldNum(item.getOversoldNum() + (num - item.getVirtualNum()));
+                }
+                //减可售房间数
+                item.setCanSellNum(item.getCanSellNum() - num);
+                //加预定房间数
+                item.setBookNum(item.getBookNum() + num);
+                updateDetailList.add(item);
+            }
+        });
+        voyageStockDetailMapper.updateBatch(updateDetailList);
+    }
+}