刘俊驰 1 tahun lalu
induk
melakukan
665c810300
18 mengubah file dengan 375 tambahan dan 162 penghapusan
  1. 2 2
      mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/ResourceServerConfig.java
  2. 11 6
      mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/ExportController.java
  3. 0 1
      mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/dao/PmsSkuStockDao.java
  4. 110 3
      mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/impl/OmsOrderServiceImpl.java
  5. 4 3
      mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/impl/PmsSkuStockServiceImpl.java
  6. 0 22
      mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/wrapper/PmsSkuStockWrapper.java
  7. 0 13
      mec-mall/mall-admin/src/main/resources/config/mybatis/PmsSkuStockDao.xml
  8. 32 0
      mec-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/dto/PmsSkuStockDto.java
  9. 2 0
      mec-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/PmsProductSkuStockRecordMapper.java
  10. 2 0
      mec-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/PmsSkuStockMapper.java
  11. 10 0
      mec-mall/mall-mbg/src/main/resources/config/mybatis/PmsProductSkuStockRecordMapper.xml
  12. 15 1
      mec-mall/mall-mbg/src/main/resources/config/mybatis/PmsSkuStockMapper.xml
  13. 2 0
      mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/PmsPortalProductService.java
  14. 17 4
      mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/HomeServiceImpl.java
  15. 2 2
      mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/OmsPortalOrderServiceImpl.java
  16. 122 55
      mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/PmsPortalProductServiceImpl.java
  17. 12 20
      mec-mall/mall-portal/src/main/resources/config/mybatis/PortalOrderDao.xml
  18. 32 30
      mec-mall/mall-portal/src/main/resources/config/mybatis/PortalProductDao.xml

+ 2 - 2
mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/ResourceServerConfig.java

@@ -30,8 +30,8 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
                 .permitAll()
             .and()
                 .authorizeRequests()
-            .antMatchers("/wechat/*","/feign-client/**","/v2/api-docs", "/code/*","/payment/callback","/admin/login","/doc.html",
-                "/open/**","/swagger-resources/**", "/webjars/**", "/swagger-ui.html")
+                .antMatchers("/wechat/*","/feign-client/**","/v2/api-docs", "/code/*","/payment/callback","/admin/login","/doc.html",
+                    "/open/**","/swagger-resources/**", "/webjars/**", "/swagger-ui.html")
             .permitAll().anyRequest().authenticated().and().httpBasic();
     }
 

+ 11 - 6
mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/ExportController.java

@@ -16,6 +16,8 @@ import com.yonge.cooleshow.admin.wrapper.PmsProductWrapper;
 import com.yonge.cooleshow.admin.wrapper.PmsSkuStockWrapper;
 import com.yonge.cooleshow.mall.common.api.CommonPage;
 import com.yonge.cooleshow.mall.common.api.CommonResult;
+import com.yonge.cooleshow.mbg.dto.PmsSkuStockDto;
+import com.yonge.cooleshow.mbg.mapper.PmsSkuStockMapper;
 import com.yonge.cooleshow.mbg.model.PmsProduct;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -44,7 +46,7 @@ public class ExportController {
     private PmsProductService productService;
 
     @Autowired
-    private PmsSkuStockDao skuStockDao;
+    private PmsSkuStockMapper skuStockMapper;
 
     @ApiOperation("订单详情")
     @RequestMapping(value = "/orderDetail", method = RequestMethod.POST)
@@ -88,17 +90,20 @@ public class ExportController {
             List<Long> productIds = list.stream().map(PmsProductWrapper.PmsProductExport::getId).collect(Collectors.toList());
 
             // 计算库存数据
-            List<PmsSkuStockWrapper.PmsSkuStockStock> skuStockStocks = skuStockDao.getSkuStockByProductIds(productIds);
+            List<PmsSkuStockDto.PmsSkuStockStock> skuStockStocks = skuStockMapper.getSkuStockByProductIds(productIds);
 
             // Convert to map
-            Map<Long, List<PmsSkuStockWrapper.PmsSkuStockStock>> skuStockStockMap = skuStockStocks.stream().collect(Collectors.groupingBy(PmsSkuStockWrapper.PmsSkuStockStock::getProductId));
+            Map<Long, List<PmsSkuStockDto.PmsSkuStockStock>> skuStockStockMap = skuStockStocks.stream().collect(Collectors.groupingBy(PmsSkuStockDto.PmsSkuStockStock::getProductId));
 
             // Merge
             for (PmsProductWrapper.PmsProductExport pmsProductExport : list) {
-                List<PmsSkuStockWrapper.PmsSkuStockStock> skuStockStock = skuStockStockMap.get(pmsProductExport.getId());
+                List<PmsSkuStockDto.PmsSkuStockStock> skuStockStock = skuStockStockMap.get(pmsProductExport.getId());
                 if (!CollectionUtils.isEmpty(skuStockStock)) {
-                    pmsProductExport.setInternalStock(skuStockStock.stream().mapToInt(PmsSkuStockWrapper.PmsSkuStockStock::getInternalStock).sum());
-                    pmsProductExport.setTaxStock(skuStockStock.stream().mapToInt(PmsSkuStockWrapper.PmsSkuStockStock::getTaxStock).sum());
+                    pmsProductExport.setInternalStock(skuStockStock.stream().mapToInt(PmsSkuStockDto.PmsSkuStockStock::getInternalStock).sum());
+                    pmsProductExport.setTaxStock(skuStockStock.stream().mapToInt(PmsSkuStockDto.PmsSkuStockStock::getTaxStock).sum());
+                } else {
+                    pmsProductExport.setInternalStock(0);
+                    pmsProductExport.setTaxStock(0);
                 }
             }
         }

+ 0 - 1
mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/dao/PmsSkuStockDao.java

@@ -22,5 +22,4 @@ public interface PmsSkuStockDao {
      */
     int replaceList(@Param("list")List<PmsSkuStock> skuStockList);
 
-    List<PmsSkuStockWrapper.PmsSkuStockStock> getSkuStockByProductIds(@Param("productIds") List<Long> productIds);
 }

+ 110 - 3
mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/impl/OmsOrderServiceImpl.java

@@ -5,20 +5,22 @@ import com.ym.mec.common.exception.BizException;
 import com.ym.mec.util.date.DateUtil;
 import com.yonge.cooleshow.admin.dao.OmsOrderDao;
 import com.yonge.cooleshow.admin.dao.OmsOrderOperateHistoryDao;
+import com.yonge.cooleshow.admin.dao.PmsProductSkuStockRecordDao;
 import com.yonge.cooleshow.admin.dto.*;
 import com.yonge.cooleshow.admin.dto.search.OrderStatisticalSearch;
 import com.yonge.cooleshow.admin.dto.search.UserStatisticalSearch;
 import com.yonge.cooleshow.admin.service.OmsOrderReturnApplyService;
 import com.yonge.cooleshow.admin.service.PmsProductService;
+import com.yonge.cooleshow.mbg.mapper.OmsOrderItemMapper;
 import com.yonge.cooleshow.mbg.mapper.OmsOrderMapper;
 import com.yonge.cooleshow.mbg.mapper.OmsOrderOperateHistoryMapper;
-import com.yonge.cooleshow.mbg.model.OmsOrder;
-import com.yonge.cooleshow.mbg.model.OmsOrderExample;
-import com.yonge.cooleshow.mbg.model.OmsOrderOperateHistory;
+import com.yonge.cooleshow.mbg.mapper.PmsProductSkuStockRecordMapper;
+import com.yonge.cooleshow.mbg.model.*;
 import com.yonge.cooleshow.admin.service.OmsOrderService;
 import com.yonge.cooleshow.admin.enums.OrderStatisticalEnum;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
@@ -54,6 +56,12 @@ public class OmsOrderServiceImpl implements OmsOrderService {
     @Autowired
     private PmsProductService productService;
 
+    @Autowired
+    private OmsOrderItemMapper omsOrderItemMapper;
+
+    @Autowired
+    private PmsProductSkuStockRecordMapper pmsProductSkuStockRecordMapper;
+
     @Override
     public List<OrderVo> list(OmsOrderQueryParam queryParam, Integer pageSize, Integer pageNum) {
         PageHelper.startPage(pageNum, pageSize);
@@ -61,9 +69,108 @@ public class OmsOrderServiceImpl implements OmsOrderService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public int delivery(List<OmsOrderDeliveryParam> deliveryParamList) {
         //批量发货
         int count = orderDao.delivery(deliveryParamList);
+
+        // 扣减库存
+        //库存扣减规则更新
+        //扣减顺序:内部库存>税务库存>进货批次
+        //先把所有批次的内部库存扣完,再扣税务库存,例如:
+        //第一批   内部0     税务10
+        //第二批   内部10   税务10
+        //这个时候发货10个商品,扣减的是第二批的内部10,再发货10个商品扣减的是第一批的税务10
+
+        // 查询出所有订单关联的skuId
+        // 订单ID集合
+        List<Long> orderIds = deliveryParamList.stream().map(OmsOrderDeliveryParam::getOrderId).collect(Collectors.toList());
+        // 查询订单详情
+        OmsOrderItemExample example = new OmsOrderItemExample();
+        example.createCriteria().andOrderIdIn(orderIds);
+        List<OmsOrderItem> omsOrderItems = omsOrderItemMapper.selectByExample(example);
+        // skuId 数量 map
+        Map<Long, Integer> skuIdMap = omsOrderItems.stream().collect(Collectors.groupingBy(OmsOrderItem::getProductSkuId,Collectors.summingInt(OmsOrderItem::getProductQuantity)));
+
+        // skuid 集合
+        List<Long> skuIds = new ArrayList<>(skuIdMap.keySet());
+        // 查询库存
+        PmsProductSkuStockRecordExample stockRecordExample = new PmsProductSkuStockRecordExample();
+        stockRecordExample.createCriteria().andProductSkuIdIn(skuIds);
+        List<PmsProductSkuStockRecord> productSkuStockRecords = pmsProductSkuStockRecordMapper.selectByExample(stockRecordExample);
+        if (CollectionUtils.isEmpty(productSkuStockRecords)) {
+            throw new BizException("库存不足");
+        }
+        //id 集合
+        List<Long> stockRecordIds = productSkuStockRecords.stream().map(PmsProductSkuStockRecord::getId).collect(Collectors.toList());
+
+        // 根据ID锁定库存
+        pmsProductSkuStockRecordMapper.lockStock(stockRecordIds);
+
+        // 根据 skuID 分组
+        Map<Long, List<PmsProductSkuStockRecord>> skuStockRecordMap = productSkuStockRecords.stream().collect(Collectors.groupingBy(PmsProductSkuStockRecord::getProductSkuId));
+        // 扣减库存
+
+        List<PmsProductSkuStockRecord> updateList = new ArrayList<>();
+        skuIdMap.forEach((skuId, num) -> {
+            List<PmsProductSkuStockRecord> skuStockRecords = skuStockRecordMap.get(skuId);
+            if (CollectionUtils.isEmpty(skuStockRecords)) {
+                throw new BizException("库存不足");
+            }
+            int count1 = num;
+            // 扣减内部库存
+            for (PmsProductSkuStockRecord skuStockRecord : skuStockRecords) {
+                if (count1 <= 0) {
+                    break;
+                }
+                if (skuStockRecord.getInternalStock() > 0) {
+
+                    int stock = skuStockRecord.getInternalStock() - skuStockRecord.getInternalSaleStock();
+                    if (stock > 0) {
+                        PmsProductSkuStockRecord record = new PmsProductSkuStockRecord();
+                        record.setId(skuStockRecord.getId());
+
+                        if (stock >= count1) {
+                            record.setInternalSaleStock(skuStockRecord.getInternalSaleStock() + count1);
+                            count1 = 0;
+                        } else {
+                            count1 = count1 - stock;
+                            record.setInternalSaleStock(record.getInternalStock());
+                        }
+                        updateList.add(record);
+                    }
+                }
+            }
+            // 扣减税务库存
+            for (PmsProductSkuStockRecord skuStockRecord : skuStockRecords) {
+                if (count1 <= 0) {
+                    break;
+                }
+                if (skuStockRecord.getTaxStock() > 0) {
+                    int stock = skuStockRecord.getTaxStock() - skuStockRecord.getTaxSaleStock();
+                    if (stock > 0) {
+                        PmsProductSkuStockRecord record = new PmsProductSkuStockRecord();
+                        record.setId(skuStockRecord.getId());
+                        if (stock >= count1) {
+                            record.setTaxSaleStock(skuStockRecord.getTaxSaleStock() + count1);
+                            count1 = 0;
+                        } else {
+                            count1 = count1 - stock;
+                            record.setTaxSaleStock(record.getTaxStock());
+                        }
+                        updateList.add(record);
+                    }
+                }
+            }
+            if (count1 > 0) {
+                throw new BizException("库存不足");
+            }
+        });
+        for (PmsProductSkuStockRecord pmsProductSkuStockRecord : updateList) {
+            pmsProductSkuStockRecordMapper.updateByPrimaryKeySelective(pmsProductSkuStockRecord);
+        }
+
+
         //添加操作记录
         List<OmsOrderOperateHistory> operateHistoryList = deliveryParamList.stream()
                 .map(omsOrderDeliveryParam -> {

+ 4 - 3
mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/impl/PmsSkuStockServiceImpl.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.google.common.collect.Lists;
 import com.yonge.cooleshow.admin.dao.PmsSkuStockDao;
 import com.yonge.cooleshow.admin.wrapper.PmsSkuStockWrapper;
+import com.yonge.cooleshow.mbg.dto.PmsSkuStockDto;
 import com.yonge.cooleshow.mbg.mapper.PmsSkuStockMapper;
 import com.yonge.cooleshow.mbg.model.PmsSkuStock;
 import com.yonge.cooleshow.mbg.model.PmsSkuStockExample;
@@ -46,14 +47,14 @@ public class PmsSkuStockServiceImpl implements PmsSkuStockService {
         List<PmsSkuStockWrapper.PmsSkuStock> stockList = JSON.parseArray(JSON.toJSONString(pmsSkuStocks), PmsSkuStockWrapper.PmsSkuStock.class);
 
         // 计算库存数据
-        List<PmsSkuStockWrapper.PmsSkuStockStock> skuStockStocks =  skuStockDao.getSkuStockByProductIds(Lists.newArrayList(pid));
+        List<PmsSkuStockDto.PmsSkuStockStock> skuStockStocks =  skuStockMapper.getSkuStockByProductIds(Lists.newArrayList(pid));
 
         // Convert to map
-        Map<Long, PmsSkuStockWrapper.PmsSkuStockStock> skuStockStockMap = skuStockStocks.stream().collect(Collectors.toMap(PmsSkuStockWrapper.PmsSkuStockStock::getId, skuStock -> skuStock));
+        Map<Long, PmsSkuStockDto.PmsSkuStockStock> skuStockStockMap = skuStockStocks.stream().collect(Collectors.toMap(PmsSkuStockDto.PmsSkuStockStock::getId, skuStock -> skuStock));
 
         // Merge
         for (PmsSkuStockWrapper.PmsSkuStock stock : stockList) {
-            PmsSkuStockWrapper.PmsSkuStockStock skuStockStock = skuStockStockMap.get(stock.getId());
+            PmsSkuStockDto.PmsSkuStockStock skuStockStock = skuStockStockMap.get(stock.getId());
             if (skuStockStock != null) {
                 stock.setInternalStock(skuStockStock.getInternalStock());
                 stock.setTaxStock(skuStockStock.getTaxStock());

+ 0 - 22
mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/wrapper/PmsSkuStockWrapper.java

@@ -54,26 +54,4 @@ public class PmsSkuStockWrapper {
     }
 
 
-    @Data
-    @ApiModel("PmsSkuStock-sku管理")
-    public static class PmsSkuStockStock {
-        @ApiModelProperty(value = "sku库存表id")
-        private Long id;
-
-        @ApiModelProperty(value = "商品id")
-        private Long productId;
-
-        /**
-         * 内部库存
-         */
-        @ApiModelProperty("内部库存")
-        private Integer internalStock;
-
-        /**
-         * 税务库存
-         */
-        @ApiModelProperty("税务库存")
-        private Integer taxStock;
-
-    }
 }

+ 0 - 13
mec-mall/mall-admin/src/main/resources/config/mybatis/PmsSkuStockDao.xml

@@ -29,17 +29,4 @@
         </foreach>
     </insert>
 
-    <select id="getSkuStockByProductIds"
-            resultType="com.yonge.cooleshow.admin.wrapper.PmsSkuStockWrapper$PmsSkuStockStock">
-        select t.product_sku_id                              as id,
-               t.product_id                                  as productId,
-               sum(t.internal_stock - t.internal_sale_stock) as internalStock,
-               sum(t.tax_stock - t.tax_sale_stock) as taxStock
-        from pms_product_sku_stock_record t
-        where t.product_id in
-        <foreach collection="productIds" item="productId" open="(" separator="," close=")">
-            #{productId}
-        </foreach>
-        group by t.product_sku_id, t.product_id
-    </select>
 </mapper>

+ 32 - 0
mec-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/dto/PmsSkuStockDto.java

@@ -0,0 +1,32 @@
+package com.yonge.cooleshow.mbg.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+public class PmsSkuStockDto {
+
+
+    @Data
+    @ApiModel("PmsSkuStock-sku管理")
+    public static class PmsSkuStockStock {
+        @ApiModelProperty(value = "sku库存表id")
+        private Long id;
+
+        @ApiModelProperty(value = "商品id")
+        private Long productId;
+
+        /**
+         * 内部库存
+         */
+        @ApiModelProperty("内部库存")
+        private Integer internalStock;
+
+        /**
+         * 税务库存
+         */
+        @ApiModelProperty("税务库存")
+        private Integer taxStock;
+
+    }
+}

+ 2 - 0
mec-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/PmsProductSkuStockRecordMapper.java

@@ -28,4 +28,6 @@ public interface PmsProductSkuStockRecordMapper {
     int updateByPrimaryKeySelective(PmsProductSkuStockRecord record);
 
     int updateByPrimaryKey(PmsProductSkuStockRecord record);
+
+    void lockStock(@Param("stockRecordIds") List<Long> stockRecordIds);
 }

+ 2 - 0
mec-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/PmsSkuStockMapper.java

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.mbg.mapper;
 
+import com.yonge.cooleshow.mbg.dto.PmsSkuStockDto;
 import com.yonge.cooleshow.mbg.model.PmsSkuStock;
 import com.yonge.cooleshow.mbg.model.PmsSkuStockExample;
 
@@ -39,4 +40,5 @@ public interface PmsSkuStockMapper {
      */
     int lockStock(@Param("productSkuId") Long productSkuId, @Param("quantity") Integer quantity);
 
+    List<PmsSkuStockDto.PmsSkuStockStock> getSkuStockByProductIds(@Param("productIds") List<Long> productIds);
 }

+ 10 - 0
mec-mall/mall-mbg/src/main/resources/config/mybatis/PmsProductSkuStockRecordMapper.xml

@@ -313,4 +313,14 @@
       create_by = #{createBy,jdbcType=BIGINT}
     where id = #{id,jdbcType=BIGINT}
   </update>
+
+  <select id="lockStock" >
+    <!--@mbg.generated-->
+      select * from pms_product_sku_stock_record where
+      id in
+      <foreach collection="stockRecordIds" item="item" separator="," open="(" close=")">
+        #{item}
+      </foreach>
+      for update
+    </select>
 </mapper>

+ 15 - 1
mec-mall/mall-mbg/src/main/resources/config/mybatis/PmsSkuStockMapper.xml

@@ -305,7 +305,21 @@
   </update>
 
   <update id="lockStock">
-    update pms_sku_stock set lock_stock = lock_stock + #{quantity} where  id = #{productSkuId} and stock &gt;= ( lock_stock + #{quantity})
+<!--    update pms_sku_stock set lock_stock = lock_stock + #{quantity} where  id = #{productSkuId} and stock &gt;= ( lock_stock + #{quantity})-->
+    update pms_sku_stock set lock_stock = lock_stock  where  id = #{productSkuId}
     </update>
 
+
+    <select id="getSkuStockByProductIds" resultType="com.yonge.cooleshow.mbg.dto.PmsSkuStockDto$PmsSkuStockStock">
+        select t.product_sku_id                              as id,
+        t.product_id                                  as productId,
+        sum(t.internal_stock - t.internal_sale_stock) as internalStock,
+        sum(t.tax_stock - t.tax_sale_stock) as taxStock
+        from pms_product_sku_stock_record t
+        where t.product_id in
+        <foreach collection="productIds" item="productId" open="(" separator="," close=")">
+            #{productId}
+        </foreach>
+        group by t.product_sku_id, t.product_id
+    </select>
 </mapper>

+ 2 - 0
mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/PmsPortalProductService.java

@@ -20,6 +20,8 @@ public interface PmsPortalProductService {
      */
     List<PmsProduct> search(String keyword, Long brandId, Long productCategoryId, Long productAttributeCategoryId, Integer pageNum, Integer pageSize, Integer sort);
 
+    List<PmsProduct> updateProductStock(List<PmsProduct> pmsProducts);
+
     /**
      * 以树形结构获取所有商品分类
      */

+ 17 - 4
mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/HomeServiceImpl.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.portal.service.impl;
 
 import com.github.pagehelper.PageHelper;
 import com.ym.mec.common.exception.BizException;
+import com.yonge.cooleshow.mbg.dto.PmsSkuStockDto;
 import com.yonge.cooleshow.mbg.mapper.*;
 import com.yonge.cooleshow.mbg.model.*;
 import com.yonge.cooleshow.portal.dao.HomeDao;
@@ -10,6 +11,7 @@ import com.yonge.cooleshow.portal.domain.HomeContentResult;
 import com.yonge.cooleshow.portal.domain.HomeFlashPromotion;
 import com.yonge.cooleshow.portal.dto.ProductCategorySmallVo;
 import com.yonge.cooleshow.portal.service.HomeService;
+import com.yonge.cooleshow.portal.service.PmsPortalProductService;
 import com.yonge.cooleshow.portal.service.UmsMemberService;
 import com.yonge.cooleshow.portal.util.DateUtil;
 import org.springframework.beans.BeanUtils;
@@ -20,6 +22,7 @@ import org.springframework.util.CollectionUtils;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -50,6 +53,9 @@ public class HomeServiceImpl implements HomeService {
     @Autowired
     private PmsProductAttributeCategoryMapper productAttributeCategoryMapper;
 
+    @Autowired
+    private PmsPortalProductService portalProductService;
+
     @Override
     public HomeContentResult content() {
         HomeContentResult result = new HomeContentResult();
@@ -87,9 +93,11 @@ public class HomeServiceImpl implements HomeService {
                 .andPublishStatusEqualTo(1)
                 .andRecommandStatusEqualTo(1)
                 .andVerifyStatusEqualTo(1);
-        return productMapper.selectByExample(example);
+        List<PmsProduct> pmsProducts = productMapper.selectByExample(example);
+        return portalProductService.updateProductStock(pmsProducts);
     }
 
+
     private long getHomeCartItemCount() {
         OmsCartItemExample example = new OmsCartItemExample();
         UmsMember currentMember = memberService.getCurrentMember();
@@ -140,7 +148,9 @@ public class HomeServiceImpl implements HomeService {
         example.createCriteria()
                 .andDeleteStatusEqualTo(0)
                 .andPublishStatusEqualTo(1);
-        return productMapper.selectByExample(example);
+
+        List<PmsProduct> pmsProducts = productMapper.selectByExample(example);
+        return portalProductService.updateProductStock(pmsProducts);
     }
 
     @Override
@@ -168,13 +178,16 @@ public class HomeServiceImpl implements HomeService {
     @Override
     public List<PmsProduct> hotProductList(Integer pageNum, Integer pageSize) {
         int offset = pageSize * (pageNum - 1);
-        return homeDao.getHotProductList(offset, pageSize);
+        List<PmsProduct> hotProductList = homeDao.getHotProductList(offset, pageSize);
+
+        return portalProductService.updateProductStock(hotProductList);
     }
 
     @Override
     public List<PmsProduct> newProductList(Integer pageNum, Integer pageSize) {
         int offset = pageSize * (pageNum - 1);
-        return homeDao.getNewProductList(offset, pageSize);
+        List<PmsProduct> newProductList = homeDao.getNewProductList(offset, pageSize);
+        return portalProductService.updateProductStock(newProductList);
     }
 
     private HomeFlashPromotion getHomeFlashPromotion() {

+ 2 - 2
mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/OmsPortalOrderServiceImpl.java

@@ -284,10 +284,10 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
         //计算order_item的实付金额
         handleRealAmount(orderItemList);
         //进行sku库存锁定
-        lockSkuStock(cartPromotionItemList);
+//        lockSkuStock(cartPromotionItemList);
 
         // 进行商品库存锁定
-        lockProductStock(cartPromotionItemList);
+//        lockProductStock(cartPromotionItemList);
 
         //根据商品合计、运费、活动优惠、优惠券、积分计算应付金额
         String cartIds = orderParam.getCartIds().stream().map(String::valueOf).collect(Collectors.joining(","));

+ 122 - 55
mec-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/PmsPortalProductServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
 import com.github.pagehelper.PageHelper;
 import com.ym.mec.auth.api.entity.SysUser;
 import com.yonge.cooleshow.mall.common.exception.Asserts;
+import com.yonge.cooleshow.mbg.dto.PmsSkuStockDto;
 import com.yonge.cooleshow.mbg.mapper.*;
 import com.yonge.cooleshow.mbg.model.*;
 import com.yonge.cooleshow.portal.dao.PortalProductDao;
@@ -23,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -99,13 +99,75 @@ public class PmsPortalProductServiceImpl implements PmsPortalProductService {
         PmsSkuStockExample skuExample = new PmsSkuStockExample();
         skuExample.createCriteria().andProductIdIn(productIdList);
         List<PmsSkuStock> skuStockList = skuStockMapper.selectByExample(skuExample);
+        skuStockList = updateProductSkuStock(skuStockList);
         Map<Long, List<PmsSkuStock>> collect = skuStockList.stream()
                                                            .collect(Collectors.groupingBy(PmsSkuStock::getProductId));
         for (PmsProduct pmsProduct : pmsProducts) {
             pmsProduct.setSkuStockList(collect.get(pmsProduct.getId()));
         }
-        return pmsProducts;
 
+        return updateProductStock(pmsProducts);
+
+    }
+
+    public List<PmsSkuStock> updateProductSkuStock(List<PmsSkuStock> skuStocks) {
+        if (CollectionUtils.isEmpty(skuStocks)) {
+            return new ArrayList<>();
+        }
+        // 从进货清单中 获取剩余库存数量
+        List<Long> productIds = skuStocks.stream().map(PmsSkuStock::getProductId).distinct().collect(Collectors.toList());
+
+        // 计算库存数据
+        List<PmsSkuStockDto.PmsSkuStockStock> skuStockStocks = skuStockMapper.getSkuStockByProductIds(productIds);
+
+        // Convert to map
+        Map<Long, Map<Long, List<PmsSkuStockDto.PmsSkuStockStock>>> map = skuStockStocks.stream()
+            .collect(Collectors.groupingBy(PmsSkuStockDto.PmsSkuStockStock::getProductId, Collectors.groupingBy(PmsSkuStockDto.PmsSkuStockStock::getId)));
+
+        // Merge
+        for (PmsSkuStock skuStock : skuStocks) {
+            Map<Long, List<PmsSkuStockDto.PmsSkuStockStock>> skuStockStock = map.get(skuStock.getProductId());
+            if (!CollectionUtils.isEmpty(skuStockStock)) {
+                List<PmsSkuStockDto.PmsSkuStockStock> pmsSkuStockStocks = skuStockStock.get(skuStock.getId());
+                if (CollectionUtils.isEmpty(pmsSkuStockStocks)) {
+                    skuStock.setLockStock(0);
+                    skuStock.setStock(0);
+                    continue;
+                }
+                skuStock.setStock(pmsSkuStockStocks.stream().mapToInt(item -> item.getInternalStock() + item.getTaxStock()).sum());
+                skuStock.setLockStock(0);
+            }
+
+        }
+        return skuStocks;
+    }
+
+    @Override
+    public List<PmsProduct> updateProductStock(List<PmsProduct> pmsProducts) {
+        if (CollectionUtils.isEmpty(pmsProducts)) {
+            return new ArrayList<>();
+        }
+        // 从进货清单中 获取剩余库存数量
+        List<Long> productIds = pmsProducts.stream().map(PmsProduct::getId).collect(Collectors.toList());
+
+        // 计算库存数据
+        List<PmsSkuStockDto.PmsSkuStockStock> skuStockStocks = skuStockMapper.getSkuStockByProductIds(productIds);
+
+        // Convert to map
+        Map<Long, List<PmsSkuStockDto.PmsSkuStockStock>> skuStockStockMap = skuStockStocks.stream().collect(Collectors.groupingBy(PmsSkuStockDto.PmsSkuStockStock::getProductId));
+
+        // Merge
+        for (PmsProduct pmsProduct : pmsProducts) {
+            List<PmsSkuStockDto.PmsSkuStockStock> skuStockStock = skuStockStockMap.get(pmsProduct.getId());
+            if (!CollectionUtils.isEmpty(skuStockStock)) {
+                pmsProduct.setStock(skuStockStock.stream().mapToInt(PmsSkuStockDto.PmsSkuStockStock::getInternalStock).sum() + skuStockStock.stream().mapToInt(PmsSkuStockDto.PmsSkuStockStock::getTaxStock).sum());
+                pmsProduct.setLockStock(0);
+            } else {
+                pmsProduct.setStock(0);
+                pmsProduct.setLockStock(0);
+            }
+        }
+        return pmsProducts;
     }
 
     /**
@@ -145,7 +207,11 @@ public class PmsPortalProductServiceImpl implements PmsPortalProductService {
         PmsPortalProductDetail result = new PmsPortalProductDetail();
         //获取商品信息
         PmsProduct product = productMapper.selectByPrimaryKey(id);
-        result.setProduct(product);
+        if (product == null) {
+            Asserts.fail("商品不存在");
+        }
+        List<PmsProduct> pmsProducts = updateProductStock(CollUtil.newArrayList(product));
+        result.setProduct(pmsProducts.get(0));
         //获取品牌信息
         PmsBrand brand = brandMapper.selectByPrimaryKey(product.getBrandId());
         result.setBrand(brand);
@@ -167,6 +233,7 @@ public class PmsPortalProductServiceImpl implements PmsPortalProductService {
         PmsSkuStockExample skuExample = new PmsSkuStockExample();
         skuExample.createCriteria().andProductIdEqualTo(product.getId());
         List<PmsSkuStock> skuStockList = skuStockMapper.selectByExample(skuExample);
+        skuStockList = updateProductSkuStock(skuStockList);
         result.setSkuStockList(skuStockList);
         //商品阶梯价格设置
         if(product.getPromotionType()==3){
@@ -219,58 +286,58 @@ public class PmsPortalProductServiceImpl implements PmsPortalProductService {
     @Override
     @Transactional
     public void reduceStock(List<StockOperateModel> model, String stockType) {
-
-        // 商品库存变动
-        List<ProductStock> productList = new ArrayList<>();
-        Map<Long, List<StockOperateModel>> collect = model.stream().collect(Collectors.groupingBy(
-                StockOperateModel::getProductId));
-        for (Map.Entry<Long, List<StockOperateModel>> entry : collect.entrySet()) {
-            ProductStock productStock = new ProductStock();
-            List<StockOperateModel> value = entry.getValue();
-            if (CollectionUtils.isEmpty(value)) {
-                continue;
-            }
-            int sum = value.stream().mapToInt(StockOperateModel::getCount).sum();
-            productStock.setProductId(entry.getKey());
-            productStock.setStock(sum);
-            productList.add(productStock);
-        }
-        switch (stockType) {
-            case "lock" :
-                // sku库存锁定
-                for (StockOperateModel stockOperateModel : model) {
-                    int i = skuStockMapper.lockStock(stockOperateModel.getProductSkuId(), stockOperateModel.getCount());
-                    if (i ==0) {
-                        Asserts.fail("库存不足");
-                    }
-                }
-                // 商品扣减锁定
-                for (ProductStock product : productList) {
-                    if (product.getStock() > 0) {
-                        int i = pmsProductMapper.lockStock(product.getProductId(), product.getStock());
-                        if (i == 0) {
-                            Asserts.fail("库存不足");
-                        }
-                    }
-                }
-                break;
-            case "unlock" :
-                // 解锁sku库存
-                portalProductDao.unlockSku(model);
-
-                // 解锁商品库存
-                portalProductDao.unlockProduct(productList);
-                break;
-            case "reduce" :
-                // 扣减sku库存
-                portalProductDao.reduceSku(model);
-
-                // 扣减商品库存
-                portalProductDao.updateProductStock(productList);
-                break;
-            default: break;
-
-        }
+//
+//        // 商品库存变动
+//        List<ProductStock> productList = new ArrayList<>();
+//        Map<Long, List<StockOperateModel>> collect = model.stream().collect(Collectors.groupingBy(
+//                StockOperateModel::getProductId));
+//        for (Map.Entry<Long, List<StockOperateModel>> entry : collect.entrySet()) {
+//            ProductStock productStock = new ProductStock();
+//            List<StockOperateModel> value = entry.getValue();
+//            if (CollectionUtils.isEmpty(value)) {
+//                continue;
+//            }
+//            int sum = value.stream().mapToInt(StockOperateModel::getCount).sum();
+//            productStock.setProductId(entry.getKey());
+//            productStock.setStock(sum);
+//            productList.add(productStock);
+//        }
+//        switch (stockType) {
+//            case "lock" :
+//                // sku库存锁定
+//                for (StockOperateModel stockOperateModel : model) {
+//                    int i = skuStockMapper.lockStock(stockOperateModel.getProductSkuId(), stockOperateModel.getCount());
+//                    if (i ==0) {
+//                        Asserts.fail("库存不足");
+//                    }
+//                }
+//                // 商品扣减锁定
+//                for (ProductStock product : productList) {
+//                    if (product.getStock() > 0) {
+//                        int i = pmsProductMapper.lockStock(product.getProductId(), product.getStock());
+//                        if (i == 0) {
+//                            Asserts.fail("库存不足");
+//                        }
+//                    }
+//                }
+//                break;
+//            case "unlock" :
+//                // 解锁sku库存
+//                portalProductDao.unlockSku(model);
+//
+//                // 解锁商品库存
+//                portalProductDao.unlockProduct(productList);
+//                break;
+//            case "reduce" :
+//                // 扣减sku库存
+//                portalProductDao.reduceSku(model);
+//
+//                // 扣减商品库存
+//                portalProductDao.updateProductStock(productList);
+//                break;
+//            default: break;
+//
+//        }
 
 
     }

+ 12 - 20
mec-mall/mall-portal/src/main/resources/config/mybatis/PortalOrderDao.xml

@@ -48,20 +48,10 @@
     <update id="updateSkuStock">
         UPDATE pms_sku_stock
         SET
-            stock = CASE id
-            <foreach collection="itemList" item="item">
-              WHEN #{item.productSkuId} THEN stock - #{item.productQuantity}
-            </foreach>
-            END,
             sale = CASE id
             <foreach collection="itemList" item="item">
                 WHEN #{item.productSkuId} THEN pms_sku_stock.sale + #{item.productQuantity}
             </foreach>
-            END,
-            lock_stock = CASE id
-            <foreach collection="itemList" item="item">
-              WHEN #{item.productSkuId} THEN lock_stock - #{item.productQuantity}
-            </foreach>
             END
         WHERE
             id IN
@@ -80,11 +70,12 @@
     <update id="releaseSkuStockLock">
         UPDATE pms_sku_stock
         SET
-        lock_stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productSkuId} THEN lock_stock - #{item.productQuantity}
-        </foreach>
-        END
+        lock_stock = lock_stock
+<!--        lock_stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productSkuId} THEN lock_stock - #{item.productQuantity}-->
+<!--        </foreach>-->
+<!--        END-->
         WHERE
         id IN
         <foreach collection="itemList" item="item" separator="," open="(" close=")">
@@ -95,11 +86,12 @@
     <update id="releaseProductStockLock">
         UPDATE pms_product
         SET
-        lock_stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productId} THEN lock_stock - #{item.stock}
-        </foreach>
-        END
+        lock_stock = lock_stock
+<!--        lock_stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productId} THEN lock_stock - #{item.stock}-->
+<!--        </foreach>-->
+<!--        END-->
         WHERE
         id IN
         <foreach collection="itemList" item="item" separator="," open="(" close=")">

+ 32 - 30
mec-mall/mall-portal/src/main/resources/config/mybatis/PortalProductDao.xml

@@ -99,20 +99,20 @@
     <update id="updateProductStock">
         UPDATE pms_product
         SET
-        stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productId} THEN stock - #{item.stock}
-        </foreach>
-        END,
+<!--        stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productId} THEN stock - #{item.stock}-->
+<!--        </foreach>-->
+<!--        END,-->
         sale = CASE id
         <foreach collection="itemList" item="item">
             WHEN #{item.productId} THEN sale + #{item.stock}
         </foreach>
-        END,
-        lock_stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productId} THEN lock_stock - #{item.stock}
-        </foreach>
+<!--        END,-->
+<!--        lock_stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productId} THEN lock_stock - #{item.stock}-->
+<!--        </foreach>-->
         END
         WHERE
         id IN
@@ -124,11 +124,12 @@
     <update id="unlockSku">
         UPDATE pms_sku_stock
         SET
-        lock_stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productSkuId} THEN lock_stock - #{item.count}
-        </foreach>
-        END
+        lock_stock = lock_stock
+<!--        lock_stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productSkuId} THEN lock_stock - #{item.count}-->
+<!--        </foreach>-->
+<!--        END-->
         WHERE
         id IN
         <foreach collection="itemList" item="item" separator="," open="(" close=")">
@@ -139,11 +140,12 @@
     <update id="unlockProduct">
         UPDATE pms_product
         SET
-        lock_stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productId} THEN lock_stock - #{item.stock}
-        </foreach>
-        END
+        lock_stock = lock_stock
+<!--        lock_stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productId} THEN lock_stock - #{item.stock}-->
+<!--        </foreach>-->
+<!--        END-->
         WHERE
         id IN
         <foreach collection="itemList" item="item" separator="," open="(" close=")">
@@ -154,20 +156,20 @@
     <update id="reduceSku">
         UPDATE pms_sku_stock
         SET
-        stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productSkuId} THEN stock - #{item.count}
-        </foreach>
-        END,
+<!--        stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productSkuId} THEN stock - #{item.count}-->
+<!--        </foreach>-->
+<!--        END,-->
         sale = CASE id
         <foreach collection="itemList" item="item">
             WHEN #{item.productSkuId} THEN pms_sku_stock.sale + #{item.count}
         </foreach>
-        END,
-        lock_stock = CASE id
-        <foreach collection="itemList" item="item">
-            WHEN #{item.productSkuId} THEN lock_stock - #{item.count}
-        </foreach>
+<!--        END,-->
+<!--        lock_stock = CASE id-->
+<!--        <foreach collection="itemList" item="item">-->
+<!--            WHEN #{item.productSkuId} THEN lock_stock - #{item.count}-->
+<!--        </foreach>-->
         END
         WHERE
         id IN