Browse Source

优惠券:新增/修改时,校验对应的商品、分类是否存在

owen 1 year ago
parent
commit
d0d21b2787
11 changed files with 164 additions and 20 deletions
  1. 20 0
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApi.java
  2. 16 0
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java
  3. 1 1
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
  4. 27 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApiImpl.java
  5. 10 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
  6. 9 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java
  7. 24 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java
  8. 10 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
  9. 23 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
  10. 21 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java
  11. 3 14
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java

+ 20 - 0
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApi.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.product.api.category;
+
+import java.util.Collection;
+
+/**
+ * 商品分类 API 接口
+ *
+ * @author owen
+ */
+public interface ProductCategoryApi {
+
+    /**
+     * 校验商品分类是否有效。如下情况,视为无效:
+     * 1. 商品分类编号不存在
+     * 2. 商品分类被禁用
+     *
+     * @param ids 商品分类编号数组
+     */
+    void validateCategoryList(Collection<Long> ids);
+}

+ 16 - 0
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java

@@ -21,6 +21,14 @@ public interface ProductSpuApi {
      */
     List<ProductSpuRespDTO> getSpuList(Collection<Long> ids);
 
+    /**
+     * 批量查询 SPU 数组,并且校验是否 SPU 是否有效
+     *
+     * @param ids SPU 编号列表
+     * @return SPU 数组
+     */
+    List<ProductSpuRespDTO> getSpuListAndValidate(Collection<Long> ids);
+
     /**
      * 获得 SPU
      *
@@ -28,4 +36,12 @@ public interface ProductSpuApi {
      */
     ProductSpuRespDTO getSpu(Long id);
 
+    /**
+     * 校验商品是否有效。如下情况,视为无效:
+     * 1. 商品编号不存在
+     * 2. 商品被禁用
+     *
+     * @param ids 商品编号数组
+     */
+    void validateSpuList(Collection<Long> ids);
 }

+ 1 - 1
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java

@@ -34,7 +34,7 @@ public interface ErrorCodeConstants {
     // ========== 商品 SPU 1-008-005-000 ==========
     ErrorCode SPU_NOT_EXISTS = new ErrorCode(1_008_005_000, "商品 SPU 不存在");
     ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1_008_005_001, "商品分类不正确,原因:必须使用第二级的商品分类及以下");
-    ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU 不处于上架状态");
+    ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU【[]】不处于上架状态");
     ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_003, "商品 SPU 不处于回收站状态");
 
     // ========== 商品 SKU 1-008-006-000 ==========

+ 27 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/category/ProductCategoryApiImpl.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.product.api.category;
+
+import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.Collection;
+
+/**
+ * 商品分类 API 接口实现类
+ *
+ * @author owen
+ */
+@Service
+@Validated
+public class ProductCategoryApiImpl implements ProductCategoryApi {
+
+    @Resource
+    private ProductCategoryService productCategoryService;
+
+    @Override
+    public void validateCategoryList(Collection<Long> ids) {
+        productCategoryService.validateCategoryList(ids);
+    }
+
+}

+ 10 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java

@@ -3,9 +3,6 @@ package cn.iocoder.yudao.module.product.api.spu;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
-import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
-import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
-import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -36,9 +33,19 @@ public class ProductSpuApiImpl implements ProductSpuApi {
         return ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids));
     }
 
+    @Override
+    public List<ProductSpuRespDTO> getSpuListAndValidate(Collection<Long> ids) {
+        return ProductSpuConvert.INSTANCE.convertList2(spuService.validateSpuList(ids));
+    }
+
     @Override
     public ProductSpuRespDTO getSpu(Long id) {
         return ProductSpuConvert.INSTANCE.convert02(spuService.getSpu(id));
     }
 
+    @Override
+    public void validateSpuList(Collection<Long> ids) {
+        spuService.validateSpuList(ids);
+    }
+
 }

+ 9 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCateg
 import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
 
 import javax.validation.Valid;
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -75,4 +76,12 @@ public interface ProductCategoryService {
      */
     List<ProductCategoryDO> getEnableCategoryList();
 
+    /**
+     * 校验商品分类是否有效。如下情况,视为无效:
+     * 1. 商品分类编号不存在
+     * 2. 商品分类被禁用
+     *
+     * @param ids 商品分类编号数组
+     */
+    void validateCategoryList(Collection<Long> ids);
 }

+ 24 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.product.service.category;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
@@ -13,7 +15,9 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -99,6 +103,26 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
         }
     }
 
+    @Override
+    public void validateCategoryList(Collection<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return;
+        }
+        // 获得商品分类信息
+        List<ProductCategoryDO> categoryList = productCategoryMapper.selectBatchIds(ids);
+        Map<Long, ProductCategoryDO> categoryMap = CollectionUtils.convertMap(categoryList, ProductCategoryDO::getId);
+        // 校验
+        ids.forEach(id -> {
+            ProductCategoryDO category = categoryMap.get(id);
+            if (category == null) {
+                throw exception(CATEGORY_NOT_EXISTS);
+            }
+            if (!CommonStatusEnum.ENABLE.getStatus().equals(category.getStatus())) {
+                throw exception(CATEGORY_DISABLED, category.getName());
+            }
+        });
+    }
+
     @Override
     public ProductCategoryDO getCategory(Long id) {
         return productCategoryMapper.selectById(id);

+ 10 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java

@@ -136,4 +136,14 @@ public interface ProductSpuService {
      */
     Long getSpuCountByCategoryId(Long categoryId);
 
+
+    /**
+     * 校验商品是否有效。如下情况,视为无效:
+     * 1. 商品编号不存在
+     * 2. 商品被禁用
+     *
+     * @param ids 商品编号数组
+     * @return 商品 SPU 列表
+     */
+    List<ProductSpuDO> validateSpuList(Collection<Long> ids);
 }

+ 23 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.product.service.spu;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -139,6 +140,28 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         }
     }
 
+    @Override
+    public List<ProductSpuDO> validateSpuList(Collection<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyList();
+        }
+        // 获得商品信息
+        List<ProductSpuDO> spuList = productSpuMapper.selectBatchIds(ids);
+        Map<Long, ProductSpuDO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuDO::getId);
+        // 校验
+        ids.forEach(id -> {
+            ProductSpuDO spu = spuMap.get(id);
+            if (spu == null) {
+                throw exception(SPU_NOT_EXISTS);
+            }
+            if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
+                throw exception(SPU_NOT_ENABLE, spu.getName());
+            }
+        });
+
+        return spuList;
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void deleteSpu(Long id) {

+ 21 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java

@@ -2,19 +2,22 @@ package cn.iocoder.yudao.module.promotion.service.coupon;
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.product.api.category.ProductCategoryApi;
+import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateCreateReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplatePageReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template.CouponTemplateUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.convert.coupon.CouponTemplateConvert;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
 import cn.iocoder.yudao.module.promotion.dal.mysql.coupon.CouponTemplateMapper;
+import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
 import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-
 import java.util.List;
+import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS;
@@ -32,9 +35,15 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
     @Resource
     private CouponTemplateMapper couponTemplateMapper;
 
-    // TODO @疯狂:新增/修改时,需要校验对应的商品、分类是否存在
+    @Resource
+    private ProductCategoryApi productCategoryApi;
+    @Resource
+    private ProductSpuApi productSpuApi;
+
     @Override
     public Long createCouponTemplate(CouponTemplateCreateReqVO createReqVO) {
+        // 校验商品范围
+        validateProductScope(createReqVO.getProductScope(), createReqVO.getProductScopeValues());
         // 插入
         CouponTemplateDO couponTemplate = CouponTemplateConvert.INSTANCE.convert(createReqVO)
                 .setStatus(CommonStatusEnum.ENABLE.getStatus());
@@ -51,6 +60,8 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
         if (updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) {
             throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount());
         }
+        // 校验商品范围
+        validateProductScope(updateReqVO.getProductScope(), updateReqVO.getProductScopeValues());
 
         // 更新
         CouponTemplateDO updateObj = CouponTemplateConvert.INSTANCE.convert(updateReqVO);
@@ -81,6 +92,14 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
         return couponTemplate;
     }
 
+    private void validateProductScope(Integer productScope, List<Long> productScopeValues) {
+        if (Objects.equals(PromotionProductScopeEnum.SPU.getScope(), productScope)) {
+            productSpuApi.validateSpuList(productScopeValues);
+        } else if (Objects.equals(PromotionProductScopeEnum.CATEGORY.getScope(), productScope)) {
+            productCategoryApi.validateCategoryList(productScopeValues);
+        }
+    }
+
     @Override
     public CouponTemplateDO getCouponTemplate(Long id) {
         return couponTemplateMapper.selectById(id);

+ 3 - 14
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java

@@ -4,7 +4,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
-import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
 import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator;
@@ -20,7 +19,8 @@ import java.util.Map;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
+import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL;
 
 /**
@@ -82,18 +82,7 @@ public class TradePriceServiceImpl implements TradePriceService {
 
     private List<ProductSpuRespDTO> checkSpuList(List<ProductSkuRespDTO> skuList) {
         // 获得商品 SPU 数组
-        List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(convertSet(skuList, ProductSkuRespDTO::getSpuId));
-
-        // 校验商品 SPU
-        spus.forEach(spu -> {
-            if (spu == null) {
-                throw exception(SPU_NOT_EXISTS);
-            }
-            if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
-                throw exception(SPU_NOT_ENABLE);
-            }
-        });
-        return spus;
+        return productSpuApi.getSpuListAndValidate(convertSet(skuList, ProductSkuRespDTO::getSpuId));
     }
 
 }