소스 검색

添加商品库存同步

yuanliang 1 년 전
부모
커밋
a752c90c37

+ 8 - 0
mec-application/src/main/java/com/ym/mec/web/controller/APIController.java

@@ -12,6 +12,7 @@ import com.ym.mec.biz.service.*;
 import com.ym.mec.biz.service.impl.GoodsServiceImpl;
 import com.ym.mec.common.controller.BaseController;
 import com.ym.mec.common.entity.GoodsSubModel;
+import com.ym.mec.common.entity.GoodsSubStockModel;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.entity.MallCreateOrderModel;
 import com.ym.mec.common.entity.OrderCancelModel;
@@ -241,8 +242,15 @@ public class APIController extends BaseController {
 		return succeed(balance);
 	}
 
+	// 组合商品状态同步
 	@PostMapping("/api/goodsStatusSynchronize")
 	public HttpResponseResult<Boolean> goodsStatusSynchronize(List<GoodsSubModel> goodsSubModelList) {
 		return succeed(goodsService.goodsStatusSynchronize(goodsSubModelList));
 	}
+
+	// 组合商品库存同步
+	@PostMapping("/api/goodsStockCountSynchronize")
+	public HttpResponseResult<Boolean> goodsStockCountSynchronize(List<GoodsSubStockModel> goodsSubStockModels) {
+		return succeed(goodsService.goodsStockCountSynchronize(goodsSubStockModels));
+	}
 }

+ 1 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dao/GoodsDao.java

@@ -205,4 +205,5 @@ public interface GoodsDao extends BaseDAO<Integer, Goods> {
 
     void updateStatus(@Param("goodIdList") List<Integer> goodIdList, @Param("status") Boolean status);
 
+    void updateStock(@Param("goodsList") List<Goods> goodsList);
 }

+ 6 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/wrapper/GoodsWrapper.java

@@ -185,9 +185,15 @@ public class GoodsWrapper {
         @ApiModelProperty("商城商品编号")
         private Integer mallGoodsId;
 
+        @ApiModelProperty("商城商品名称")
+        private String mallGoodsName;
+
         @ApiModelProperty("sku编号")
         private Integer sku;
 
+        @ApiModelProperty("销售价格")
+        private BigDecimal price;
+
         @ApiModelProperty("商品状态,1:上架、0:下架")
         private Boolean goodsStatus;
 

+ 3 - 0
mec-biz/src/main/java/com/ym/mec/biz/service/GoodsService.java

@@ -6,6 +6,7 @@ import com.ym.mec.biz.dal.page.GoodsQueryInfo;
 import com.ym.mec.biz.dal.wrapper.GoodsWrapper;
 import com.ym.mec.common.dto.PmsProductDto;
 import com.ym.mec.common.entity.GoodsSubModel;
+import com.ym.mec.common.entity.GoodsSubStockModel;
 import com.ym.mec.common.page.PageInfo;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -140,4 +141,6 @@ public interface GoodsService extends BaseService<Integer, Goods> {
     PageInfo<PmsProductDto> queryGoodsSubByPage(GoodsWrapper.GoodsSubQuery query);
 
     Boolean goodsStatusSynchronize(List<GoodsSubModel> goodsSubModelList);
+
+    Boolean goodsStockCountSynchronize(List<GoodsSubStockModel> goodsSubStockModels);
 }

+ 84 - 19
mec-biz/src/main/java/com/ym/mec/biz/service/impl/GoodsServiceImpl.java

@@ -23,6 +23,7 @@ import com.ym.mec.common.dal.BaseDAO;
 import com.ym.mec.common.dto.PmsProductDto;
 import com.ym.mec.common.dto.PmsProductQueryParamDto;
 import com.ym.mec.common.entity.GoodsSubModel;
+import com.ym.mec.common.entity.GoodsSubStockModel;
 import com.ym.mec.common.entity.UploadReturnBean;
 import com.ym.mec.common.exception.BizException;
 import com.ym.mec.common.page.PageInfo;
@@ -56,6 +57,7 @@ import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -262,9 +264,9 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 					throw new BizException("{}等商品还在销售中", goodsNames);
 				}
 			}
-			List<GoodsSub> goodsSubs = queryGoodsSub(goodsId);
+			List<GoodsWrapper.GoodsSub> goodsSubs = queryGoodsSub(goodsId);
 			if (!CollectionUtils.isEmpty(goodsSubs) && status == 1) {
-				long falseSize = goodsSubs.stream().map(GoodsSub::getGoodsStatus).filter(Boolean.FALSE::equals).count();
+				long falseSize = goodsSubs.stream().map(GoodsWrapper.GoodsSub::getGoodsStatus).filter(Boolean.FALSE::equals).count();
 				if (falseSize > 0) {
 					throw new BizException("存在已下架的子商品");
 				}
@@ -283,12 +285,35 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 		goodsDao.update(goods);
 	}
 
-	private List<GoodsSub> queryGoodsSub(Integer goodsId) {
+	private List<GoodsWrapper.GoodsSub> queryGoodsSub(Integer goodsId) {
 		// 从管乐迷商城组合的商品
 		QueryWrapper<GoodsSub> queryWrapper = new QueryWrapper<>();
 		queryWrapper.eq("goods_id_", goodsId);
 		List<GoodsSub> goodsSubs = goodsSubMapper.selectList(queryWrapper);
-		return goodsSubs;
+		List<GoodsWrapper.GoodsSub> goodsSubList = goodsSubs.stream().map(next -> {
+			GoodsWrapper.GoodsSub goodsSub = new GoodsWrapper.GoodsSub();
+			goodsSub.setGoodsId(goodsId);
+			goodsSub.setMallGoodsId(next.getMallGoodsId());
+			goodsSub.setGoodsStatus(next.getGoodsStatus());
+			goodsSub.setSku(next.getSku());
+			goodsSub.setGoodsPrice(next.getGoodsPrice());
+			return goodsSub;
+		}).collect(Collectors.toList());
+		if (!CollectionUtils.isEmpty(goodsSubList)) {
+			List<String> goodIdList = goodsSubList.stream().map(next -> next.getMallGoodsId().toString()).distinct().collect(Collectors.toList());
+			PmsProductQueryParamDto build = PmsProductQueryParamDto.builder()
+					.productIds(String.join(",", goodIdList))
+					.pageSize(9999)
+					.pageNum(1).build();
+			Map<String, PmsProductDto> map = mallFeignService.getProductList(build)
+					.getRows().stream().collect(Collectors.toMap(next -> next.getGoodsId() + "_" + next.getSkuStockId(), Function.identity()));
+			goodsSubList.forEach(next -> {
+				PmsProductDto orDefault = map.getOrDefault(next.getMallGoodsId() + "_" + next.getSku(), new PmsProductDto());
+				next.setPrice(orDefault.getPrice());
+				next.setMallGoodsName(orDefault.getName());
+			});
+		}
+		return goodsSubList;
 	}
 
 	@Override
@@ -781,10 +806,9 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 		if(StringUtils.isNotEmpty(goods.getFreeFeeShowOrganId())){
 			goods.setFreeFeeShowOrganName(StringUtils.join(organizationDao.findByOrganIds(goods.getFreeFeeShowOrganId()),","));
 		}
-		List<GoodsSub> goodsSubs = queryGoodsSub(goodsId);
 		GoodsWrapper.Goods detail = new GoodsWrapper.Goods();
 		BeanUtils.copyProperties(goods, detail);
-		detail.setGoodsSubList(JSON.parseArray(JSON.toJSONString(goodsSubs), GoodsWrapper.GoodsSub.class));
+		detail.setGoodsSubList(queryGoodsSub(goodsId));
 		return detail;
 	}
 
@@ -849,32 +873,73 @@ public class GoodsServiceImpl extends BaseServiceImpl<Integer, Goods>  implement
 		if (CollectionUtils.isEmpty(goodsSubModelList)) {
 			return false;
 		}
-		log.info("开始同步商品状态:" + JSON.toJSONString(goodsSubModelList));
+		log.info(Thread.currentThread().getName() + "开始同步商品状态:" + JSON.toJSONString(goodsSubModelList));
 		List<Integer> goodIds = goodsSubModelList.stream().map(GoodsSubModel::getMallGoodsId).distinct().collect(Collectors.toList());
-		List<Integer> skus = goodsSubModelList.stream().map(GoodsSubModel::getSku).distinct().collect(Collectors.toList());
 		QueryWrapper<GoodsSub> queryWrapper = new QueryWrapper<>();
-		queryWrapper.in("goods_id_", goodIds)
-				.in("sku_", skus);
+		queryWrapper.in("mall_goods_id_", goodIds);
 		List<GoodsSub> goodsSubs = goodsSubMapper.selectList(queryWrapper);
 		if (CollectionUtils.isEmpty(goodsSubs)) {
 			return true;
 		}
-		Map<String, Boolean> keyStatusMap = goodsSubModelList.stream().collect(Collectors.toMap(next -> next.getMallGoodsId() + "_" + next.getSku(), GoodsSubModel::getGoodsStatus));
-		Set<String> keys = keyStatusMap.keySet();
-		goodsSubs.removeIf(next -> !keys.contains(next.getMallGoodsId() + "_" + next.getSku()));
-		if (CollectionUtils.isEmpty(goodsSubs)) {
-			return true;
-		}
-		log.info("开始同步商品状态:0/" + goodsSubs.size());
-		List<GoodsSub> goodsSubList = goodsSubs.stream().peek(next -> next.setGoodsStatus(keyStatusMap.get(next.getMallGoodsId() + "_" + next.getSku()))).collect(Collectors.toList());
+		Map<Integer, Boolean> keyStatusMap = goodsSubModelList.stream().collect(Collectors.toMap(GoodsSubModel::getMallGoodsId, GoodsSubModel::getGoodsStatus));
+		log.info(Thread.currentThread().getName() + "开始同步商品状态:0/" + goodsSubs.size());
+		List<GoodsSub> goodsSubList = goodsSubs.stream().peek(next -> next.setGoodsStatus(keyStatusMap.get(next.getMallGoodsId()))).collect(Collectors.toList());
 		// 下架的商品
 		List<GoodsSub> downGoods = goodsSubList.stream().filter(next -> Boolean.FALSE.equals(next.getGoodsStatus())).collect(Collectors.toList());
 		if(!CollectionUtils.isEmpty(downGoods)){
 			List<Integer> goodIdList = downGoods.stream().map(GoodsSub::getGoodsId).distinct().collect(Collectors.toList());
 			goodsDao.updateStatus(goodIdList, false);
 		}
-		Map<Boolean, List<Integer>> listMap = goodsSubList.stream().collect(Collectors.groupingBy(GoodsSub::getGoodsStatus, Collectors.mapping(next -> next.getId(), Collectors.toList())));
+		Map<Boolean, List<Integer>> listMap = goodsSubList.stream().collect(Collectors.groupingBy(GoodsSub::getGoodsStatus, Collectors.mapping(GoodsSub::getId, Collectors.toList())));
 		listMap.forEach((key, values) -> goodsSubMapper.updateStatus(values, key));
+		log.info(Thread.currentThread().getName() + "同步商品状态完成");
+		return true;
+	}
+
+	/**
+	 * 同步组合商品库存
+	 * @param goodsSubStockModels 商品库存信息
+	 * @return true/false
+	 */
+	@Transactional(rollbackFor = Exception.class)
+	@Override
+	public Boolean goodsStockCountSynchronize(List<GoodsSubStockModel> goodsSubStockModels) {
+		if(goodsSubStockModels.isEmpty()){
+			return false;
+		}
+		List<Integer> mallGoodIds = goodsSubStockModels.stream().map(GoodsSubStockModel::getMallGoodsId).distinct().collect(Collectors.toList());
+		List<Integer> skus = goodsSubStockModels.stream().map(GoodsSubStockModel::getSku).distinct().collect(Collectors.toList());
+
+		QueryWrapper<GoodsSub> queryWrapper = new QueryWrapper<>();
+		queryWrapper.in("mall_goods_id_", mallGoodIds).in("sku_", skus);
+		List<GoodsSub> goodsSubs = goodsSubMapper.selectList(queryWrapper);
+		if (CollectionUtils.isEmpty(goodsSubs)) {
+			return true;
+		}
+		Map<String, Integer> stockMap = goodsSubStockModels.stream().collect(Collectors.toMap(next -> next.getMallGoodsId() + "_" + next.getSku(), next -> next.getStock()));
+		Set<String> keys = stockMap.keySet();
+		goodsSubs.removeIf(next -> !keys.contains(next.getMallGoodsId() + "_" + next.getSku()));
+		if (CollectionUtils.isEmpty(goodsSubs)) {
+			return true;
+		}
+		List<Integer> goodIds = goodsSubs.stream().map(GoodsSub::getGoodsId).distinct().collect(Collectors.toList());
+		goodsDao.lockGoods(goodIds);
+		List<Goods> goodsList = goodsDao.findGoodsByIds(goodIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
+		Map<Integer, Integer> goodStockMap = goodsList.stream().collect(Collectors.toMap(Goods::getId, Goods::getStockCount));
+
+		List<Goods> updateGoods = new ArrayList<>();
+		for (GoodsSub goodsSub : goodsSubs) {
+			Integer goodsId = goodsSub.getGoodsId();
+			String key = goodsSub.getMallGoodsId() + "_" + goodsSub.getSku();
+			Integer stock = stockMap.get(key);
+			int updateStock = Math.min(goodStockMap.get(goodsId), stock);
+
+			Goods goods = new Goods();
+			goods.setId(goodsId);
+			goods.setStockCount(updateStock);
+			updateGoods.add(goods);
+		}
+		goodsDao.updateStock(updateGoods);
 		return true;
 	}
 }

+ 7 - 0
mec-biz/src/main/resources/config/mybatis/GoodsMapper.xml

@@ -593,4 +593,11 @@
             #{item}
         </foreach>
     </update>
+
+    <update id="updateStock">
+        <foreach collection="goodsList" item="goods" separator=";">
+        UPDATE goods set stock_count_ = #{goods.stockCount}
+            where id_ = #{goods.id}
+        </foreach>
+    </update>
 </mapper>

+ 5 - 0
mec-client-api/src/main/java/com/ym/mec/web/WebFeignService.java

@@ -2,6 +2,7 @@ package com.ym.mec.web;
 
 import com.ym.mec.common.config.FeignConfiguration;
 import com.ym.mec.common.entity.GoodsSubModel;
+import com.ym.mec.common.entity.GoodsSubStockModel;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.entity.MallCreateOrderModel;
 import com.ym.mec.common.entity.OrderCancelModel;
@@ -91,4 +92,8 @@ public interface WebFeignService {
 	// 商城商品状态更新,同步商品状态
 	@PostMapping("/api/goodsStatusSynchronize")
 	HttpResponseResult<Boolean> goodsStatusSynchronize(@RequestBody List<GoodsSubModel> goodsSubModelList);
+
+	// 商城商品库存更新,同步商品库存
+	@PostMapping("/api/goodsStockCountSynchronize")
+	HttpResponseResult<Boolean> goodsStockCountSynchronize(List<GoodsSubStockModel> goodsSubStockModels);
 }

+ 6 - 0
mec-client-api/src/main/java/com/ym/mec/web/fallback/WebFeignServiceFallback.java

@@ -1,6 +1,7 @@
 package com.ym.mec.web.fallback;
 
 import com.ym.mec.common.entity.GoodsSubModel;
+import com.ym.mec.common.entity.GoodsSubStockModel;
 import com.ym.mec.common.entity.HttpResponseResult;
 import com.ym.mec.common.entity.MallCreateOrderModel;
 import com.ym.mec.common.entity.OrderCancelModel;
@@ -120,4 +121,9 @@ public class WebFeignServiceFallback implements WebFeignService {
 	public HttpResponseResult<Boolean> goodsStatusSynchronize(List<GoodsSubModel> goodsSubModelList) {
 		return null;
 	}
+
+	@Override
+	public HttpResponseResult<Boolean> goodsStockCountSynchronize(List<GoodsSubStockModel> goodsSubStockModels) {
+		return null;
+	}
 }

+ 0 - 2
mec-common/common-core/src/main/java/com/ym/mec/common/entity/GoodsSubModel.java

@@ -7,7 +7,5 @@ public class GoodsSubModel {
 
     private Integer mallGoodsId;
 
-    private Integer sku;
-
     private Boolean goodsStatus;
 }

+ 13 - 0
mec-common/common-core/src/main/java/com/ym/mec/common/entity/GoodsSubStockModel.java

@@ -0,0 +1,13 @@
+package com.ym.mec.common.entity;
+
+import lombok.Data;
+
+@Data
+public class GoodsSubStockModel {
+
+    private Integer mallGoodsId;
+
+    private Integer sku;
+
+    private Integer stock;
+}

+ 39 - 0
mec-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/service/impl/PmsProductServiceImpl.java

@@ -2,7 +2,10 @@ package com.yonge.cooleshow.admin.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import com.github.pagehelper.PageHelper;
+import com.ym.mec.common.entity.GoodsSubModel;
+import com.ym.mec.common.entity.GoodsSubStockModel;
 import com.ym.mec.common.exception.BizException;
+import com.ym.mec.web.WebFeignService;
 import com.yonge.cooleshow.admin.dao.*;
 import com.yonge.cooleshow.admin.dao.*;
 import com.yonge.cooleshow.admin.dto.HomeStatistical;
@@ -16,9 +19,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 
+import javax.annotation.Resource;
 import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
@@ -66,6 +71,8 @@ public class PmsProductServiceImpl implements PmsProductService {
     private PmsProductDao productDao;
     @Autowired
     private PmsProductVertifyRecordDao productVertifyRecordDao;
+    @Resource
+    private WebFeignService webFeignService;
 
     @Override
     public int create(PmsProductParam productParam) {
@@ -254,6 +261,15 @@ public class PmsProductServiceImpl implements PmsProductService {
 
     @Override
     public int updatePublishStatus(List<Long> ids, Integer publishStatus) {
+        // 商品状态同步
+        List<GoodsSubModel> collect = ids.stream().map(next -> {
+            GoodsSubModel goodsSubModel = new GoodsSubModel();
+            goodsSubModel.setMallGoodsId(next.intValue());
+            goodsSubModel.setGoodsStatus(1 == publishStatus);
+            return goodsSubModel;
+        }).collect(Collectors.toList());
+        webFeignService.goodsStatusSynchronize(collect);
+
         PmsProduct record = new PmsProduct();
         record.setPublishStatus(publishStatus);
         PmsProductExample example = new PmsProductExample();
@@ -281,6 +297,29 @@ public class PmsProductServiceImpl implements PmsProductService {
 
     @Override
     public int updateDeleteStatus(List<Long> ids, Integer deleteStatus) {
+        if (1 == deleteStatus) {
+            List<GoodsSubModel> collect = ids.stream().map(next -> {
+                GoodsSubModel goodsSubModel = new GoodsSubModel();
+                goodsSubModel.setMallGoodsId(next.intValue());
+                goodsSubModel.setGoodsStatus(false);
+                return goodsSubModel;
+            }).collect(Collectors.toList());
+            webFeignService.goodsStatusSynchronize(collect);
+            // 更新库存
+            PmsSkuStockExample example = new PmsSkuStockExample();
+            example.createCriteria().andProductIdIn(ids);
+            List<PmsSkuStock> pmsSkuStocks = skuStockMapper.selectByExample(example);
+            if (!CollectionUtils.isEmpty(pmsSkuStocks)) {
+                List<GoodsSubStockModel> stockModels = pmsSkuStocks.stream().map(next -> {
+                    GoodsSubStockModel stockModel = new GoodsSubStockModel();
+                    stockModel.setMallGoodsId(next.getProductId().intValue());
+                    stockModel.setSku(next.getId().intValue());
+                    stockModel.setStock(0);
+                    return stockModel;
+                }).collect(Collectors.toList());
+                webFeignService.goodsStockCountSynchronize(stockModels);
+            }
+        }
         PmsProduct record = new PmsProduct();
         record.setDeleteStatus(deleteStatus);
         PmsProductExample example = new PmsProductExample();