Browse Source

product:完善 App 商品详情接口

YunaiV 2 years ago
parent
commit
652428a723
18 changed files with 300 additions and 70 deletions
  1. 1 0
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
  2. 10 0
      yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java
  3. 2 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
  4. 4 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java
  5. 4 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java
  6. 23 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java
  7. 8 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http
  8. 44 10
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
  9. 92 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuDetailRespVO.java
  10. 0 21
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java
  11. 13 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
  12. 41 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
  13. 12 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
  14. 21 11
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
  15. 13 8
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
  16. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
  17. 8 8
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
  18. 3 3
      yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java

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

@@ -33,6 +33,7 @@ public interface ErrorCodeConstants {
     // ========== 商品 SPU 1008005000 ==========
     ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
     ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下");
+    ErrorCode SPU_NOT_ENABLE = new ErrorCode(1008005002, "商品 SPU 不处于上架状态");
 
     // ========== 商品 SKU 1008006000 ==========
     ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");

+ 10 - 0
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java

@@ -35,4 +35,14 @@ public enum ProductSpuStatusEnum implements IntArrayValuable {
         return ARRAYS;
     }
 
+    /**
+     * 判断是否处于【上架】状态
+     *
+     * @param status 状态
+     * @return 是否处于【上架】状态
+     */
+    public static boolean isEnable(Integer status) {
+        return ENABLE.getStatus().equals(status);
+    }
+
 }

+ 2 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java

@@ -66,7 +66,7 @@ public class ProductSpuController {
     @ApiOperation("获得商品 SPU")
     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
     @PreAuthorize("@ss.hasPermission('product:spu:query')")
-    public CommonResult<ProductSpuRespVO> getSpu(@RequestParam("id") Long id) {
+    public CommonResult<ProductSpuDO> getSpu(@RequestParam("id") Long id) {
         return success(spuService.getSpu(id));
     }
 
@@ -75,7 +75,7 @@ public class ProductSpuController {
     @ApiOperation("获得商品 SPU 列表")
     @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
     @PreAuthorize("@ss.hasPermission('product:spu:query')")
-    public CommonResult<List<ProductSpuRespVO>> getSpuList(@RequestParam("ids") Collection<Long> ids) {
+    public CommonResult<List<ProductSpuDO>> getSpuList(@RequestParam("ids") Collection<Long> ids) {
         List<ProductSpuDO> list = spuService.getSpuList(ids);
         return success(ProductSpuConvert.INSTANCE.convertList(list));
     }

+ 4 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * 占位符,无时间作用,避免 package 缩进
+ */
+package cn.iocoder.yudao.module.product.controller.app.property;

+ 4 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java

@@ -0,0 +1,4 @@
+/**
+ * 占位符,无时间作用,避免 package 缩进
+ */
+package cn.iocoder.yudao.module.product.controller.app.property.vo.property;

+ 23 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.product.controller.app.property.vo.value;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel("用户 App - 商品属性值的明细 Response VO")
+@Data
+public class AppProductPropertyValueDetailRespVO {
+
+    @ApiModelProperty(value = "属性的编号", required = true, example = "1")
+    private Long propertyId;
+
+    @ApiModelProperty(value = "属性的名称", required = true, example = "颜色")
+    private String propertyName;
+
+    @ApiModelProperty(value = "属性值的编号", required = true, example = "1024")
+    private Long valueId;
+
+    @ApiModelProperty(value = "属性值的名称", required = true, example = "红色")
+    private String valueName;
+
+}

+ 8 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http

@@ -0,0 +1,8 @@
+### 获得订单交易的分页 TODO
+GET {{appApi}}/trade/order/page?pageNo=1&pageSize=10
+Authorization: Bearer {{appToken}}
+tenant-id: {{appTenentId}}
+
+### 获得商品 SPU 明细
+GET {{appApi}}/product/spu/get-detail?id=4
+tenant-id: {{appTenentId}}

+ 44 - 10
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java

@@ -1,13 +1,22 @@
 package cn.iocoder.yudao.module.product.controller.app.spu;
 
-import cn.hutool.core.bean.BeanUtil;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuDetailRespVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
-import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuRespVO;
+import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
+import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
+import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
+import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
+import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
+import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
+import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
+import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -17,28 +26,53 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.List;
 
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE;
+import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
 
-@Api(tags = "用户 APP -  商品spu")
+@Api(tags = "用户 APP - 商品 SPU")
 @RestController
 @RequestMapping("/product/spu")
 @Validated
 public class AppProductSpuController {
 
     @Resource
-    private ProductSpuService spuService;
+    private ProductSpuService productSpuService;
+    @Resource
+    private ProductSkuService productSkuService;
+    @Resource
+    private ProductPropertyValueService productPropertyValueService;
 
     @GetMapping("/page")
     @ApiOperation("获得商品spu分页")
     public CommonResult<PageResult<AppSpuPageRespVO>> getSpuPage(@Valid AppSpuPageReqVO pageVO) {
-        return success(spuService.getSpuPage(pageVO));
+        return success(productSpuService.getSpuPage(pageVO));
     }
 
-    @GetMapping("/")
-    @ApiOperation("获取商品 - 通过商品id")
-    public CommonResult<AppSpuRespVO> getSpu(@RequestParam("spuId") Long spuId) {
-        AppSpuRespVO appSpuRespVO = BeanUtil.toBean(spuService.getSpu(spuId), AppSpuRespVO.class);
-        return success(appSpuRespVO);
+    @GetMapping("/get-detail")
+    @ApiOperation("获得商品 SPU 明细")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
+    public CommonResult<AppSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
+        // 获得商品 SPU
+        ProductSpuDO spu = productSpuService.getSpu(id);
+        if (spu == null) {
+            throw exception(SPU_NOT_EXISTS);
+        }
+        if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
+            throw exception(SPU_NOT_ENABLE);
+        }
+
+        // 查询商品 SKU
+        List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(),
+                CommonStatusEnum.ENABLE.getStatus());
+        // 查询商品属性
+        List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
+                .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
+        // 拼接
+        return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues));
     }
+
 }

+ 92 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuDetailRespVO.java

@@ -0,0 +1,92 @@
+package cn.iocoder.yudao.module.product.controller.app.spu.vo;
+
+import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@ApiModel("用户 App - 商品 SPU 明细 Response VO")
+@Data
+public class AppSpuDetailRespVO {
+
+    @ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
+    private Long id;
+
+    // ========== 基本信息 =========
+
+    @ApiModelProperty(value = "商品名称", required = true, example = "芋道")
+    private String name;
+
+    @ApiModelProperty(value = "促销语", example = "好吃!")
+    private String sellPoint;
+
+    @ApiModelProperty(value = "商品详情", required = true, example = "我是商品描述")
+    private String description;
+
+    @ApiModelProperty(value = "商品分类编号", required = true, example = "1")
+    private Long categoryId;
+
+    @ApiModelProperty(value = "商品图片的数组", required = true)
+    private List<String> picUrls;
+
+    @ApiModelProperty(value = "商品视频", required = true)
+    private String videoUrl;
+
+    // ========== SKU 相关字段 =========
+
+    @ApiModelProperty(value = "规格类型", required = true, example = "1", notes = "参见 ProductSpuSpecTypeEnum 枚举类")
+    private Integer specType;
+
+    @ApiModelProperty(value = "是否展示库存", required = true, example = "true")
+    private Boolean showStock;
+
+    @ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
+    private Integer minPrice;
+
+    @ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024")
+    private Integer maxPrice;
+
+    /**
+     * SKU 数组
+     */
+    private List<Sku> skus;
+
+    // ========== 统计相关字段 =========
+
+    @ApiModelProperty(value = "商品销量", required = true, example = "1024")
+    private Integer salesCount;
+
+    @ApiModel("用户 App - 商品 SPU 明细的 SKU 信息")
+    @Data
+    public static class Sku {
+
+        @ApiModelProperty(value = "商品 SKU 编号", example = "1")
+        private Long id;
+
+        /**
+         * 商品属性数组
+         */
+        private List<AppProductPropertyValueDetailRespVO> properties;
+
+        @ApiModelProperty(value = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分")
+        private Integer price;
+
+        @ApiModelProperty(value = "市场价", example = "1024", notes = "单位:分")
+        private Integer marketPrice;
+
+        @ApiModelProperty(value = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
+        private String picUrl;
+
+        @ApiModelProperty(value = "库存", required = true, example = "1")
+        private Integer stock;
+
+        @ApiModelProperty(value = "商品重量", example = "1", notes = "单位:kg 千克")
+        private Double weight;
+
+        @ApiModelProperty(value = "商品体积", example = "1024", notes = "单位:m^3 平米")
+        private Double volume;
+    }
+
+}

+ 0 - 21
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppSpuRespVO.java

@@ -1,21 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.app.spu.vo;
-
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;
-import io.swagger.annotations.ApiModel;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * <p>
- *
- * </p>
- *
- * @author LuoWenFeng
- */
-@ApiModel("App - 商品spu Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class AppSpuRespVO extends ProductSpuRespVO {
-
-
-}

+ 13 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.product.convert.sku;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
@@ -10,9 +11,8 @@ import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
@@ -72,4 +72,14 @@ public interface ProductSkuConvert {
         return spuIdAndStockMap;
     }
 
+    default Collection<Long> convertPropertyValueIds(List<ProductSkuDO> list) {
+        if (CollUtil.isEmpty(list)) {
+            return new HashSet<>();
+        }
+        return list.stream().filter(item -> item.getProperties() != null)
+                .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
+                .map(ProductSkuDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合
+                .collect(Collectors.toSet());
+    }
+
 }

+ 41 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java

@@ -1,15 +1,25 @@
 package cn.iocoder.yudao.module.product.convert.spu;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
+import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
+import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuDetailRespVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageRespVO;
+import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
+import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+
+import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
 /**
  * 商品spu Convert
@@ -25,18 +35,46 @@ public interface ProductSpuConvert {
 
     ProductSpuDO convert(ProductSpuUpdateReqVO bean);
 
-    ProductSpuRespVO convert(ProductSpuDO bean);
-
-    List<ProductSpuRespVO> convertList(List<ProductSpuDO> list);
+    List<ProductSpuDO> convertList(List<ProductSpuDO> list);
 
     PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page);
 
     ProductSpuPageReqVO convert(AppSpuPageReqVO bean);
 
+    // TODO 芋艿:修改下
     AppSpuPageRespVO convertAppResp(ProductSpuDO list);
 
     List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list);
 
     List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
 
+    default AppSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus,
+                                       List<ProductPropertyValueDetailRespBO> propertyValues) {
+        AppSpuDetailRespVO spuVO = convert02(spu)
+                .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0));
+        spuVO.setSkus(convertList03(skus));
+        // 处理商品属性
+        Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId);
+        for (int i = 0; i < skus.size(); i++) {
+            List<ProductSkuDO.Property> properties = skus.get(i).getProperties();
+            if (CollUtil.isEmpty(properties)) {
+                continue;
+            }
+            AppSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
+            sku.setProperties(new ArrayList<>(properties.size()));
+            // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
+            properties.forEach(property -> {
+                ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId());
+                if (propertyValue == null) {
+                    return;
+                }
+                sku.getProperties().add(convert03(propertyValue));
+            });
+        }
+        return spuVO;
+    }
+    AppSpuDetailRespVO convert02(ProductSpuDO spu);
+    List<AppSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus);
+    AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue);
+
 }

+ 12 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -22,6 +23,17 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
         return selectList(ProductSkuDO::getSpuId, spuId);
     }
 
+    default List<ProductSkuDO> selectListBySpuIdAndStatus(Long spuId,
+                                                          Integer status) {
+        return selectList(new LambdaQueryWrapperX<ProductSkuDO>()
+                .eq(ProductSkuDO::getSpuId, spuId)
+                .eqIfPresent(ProductSkuDO::getStatus, status));
+    }
+
+    default List<ProductSkuDO> selectListBySpuId(Collection<Long> spuIds) {
+        return selectList(ProductSkuDO::getSpuId, spuIds);
+    }
+
     default void deleteBySpuId(Long spuId) {
         delete(new LambdaQueryWrapperX<ProductSkuDO>().eq(ProductSkuDO::getSpuId, spuId));
     }

+ 21 - 11
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.service.sku;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
 import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
+import org.springframework.lang.Nullable;
 
 import java.util.Collection;
 import java.util.List;
@@ -49,25 +50,25 @@ public interface ProductSkuService {
      *
      * @param list sku组合的集合
      */
-    void validateSkus(List<ProductSkuCreateOrUpdateReqVO> list, Integer specType);
+    void validateSkuList(List<ProductSkuCreateOrUpdateReqVO> list, Integer specType);
 
     /**
      * 批量创建 SKU
      *
      * @param spuId 商品 SPU 编号
-     * @para spuName 商品 SPU 名称
+     * @param spuName 商品 SPU 名称
      * @param list SKU 对象集合
      */
-    void createSkus(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> list);
+    void createSkuList(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> list);
 
     /**
      * 根据 SPU 编号,批量更新它的 SKU 信息
      *
      * @param spuId SPU 编码
-     * @para spuName 商品 SPU 名称
+     * @param spuName 商品 SPU 名称
      * @param skus SKU 的集合
      */
-    void updateSkus(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> skus);
+    void updateSkuList(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> skus);
 
     /**
      * 更新 SKU 库存(增量)
@@ -79,20 +80,30 @@ public interface ProductSkuService {
     void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO);
 
     /**
-     * 获得商品 sku 集合
+     * 获得商品 SKU 集合
      *
      * @param spuId spu 编号
      * @return 商品sku 集合
      */
-    List<ProductSkuDO> getSkusBySpuId(Long spuId);
+    List<ProductSkuDO> getSkuListBySpuId(Long spuId);
 
     /**
-     * 获得 spu 对应的 sku 集合
+     * 基于 SPU 编号和状态,获得商品 SKU 集合
+     *
+     * @param spuId SPU 编号
+     * @param status 状态
+     * @return 商品 SKU 集合
+     */
+    List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId,
+                                                  @Nullable Integer status);
+
+    /**
+     * 获得 spu 对应的 SKU 集合
      *
      * @param spuIds spu 编码集合
      * @return  商品 sku 集合
      */
-    List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds);
+    List<ProductSkuDO> getSkuListBySpuId(List<Long> spuIds);
 
     /**
      * 通过 spuId 删除 sku 信息
@@ -106,7 +117,6 @@ public interface ProductSkuService {
      *
      * @return SKU 数组
      */
-    List<ProductSkuDO> getSkusByAlarmStock();
-
+    List<ProductSkuDO> getSkuListByAlarmStock();
 
 }

+ 13 - 8
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java

@@ -78,7 +78,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
     }
 
     @Override
-    public void validateSkus(List<ProductSkuCreateOrUpdateReqVO> skus, Integer specType) {
+    public void validateSkuList(List<ProductSkuCreateOrUpdateReqVO> skus, Integer specType) {
         // 非多规格,不需要校验
         if (ObjectUtil.notEqual(specType, ProductSpuSpecTypeEnum.DISABLE.getType())) {
             return;
@@ -121,7 +121,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
     }
 
     @Override
-    public void createSkus(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList) {
+    public void createSkuList(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList) {
         // 批量插入 SKU
         List<ProductSkuDO> skuDOList = ProductSkuConvert.INSTANCE.convertList06(skuCreateReqList, spuName);
         skuDOList.forEach(v -> v.setSpuId(spuId));
@@ -129,13 +129,18 @@ public class ProductSkuServiceImpl implements ProductSkuService {
     }
 
     @Override
-    public List<ProductSkuDO> getSkusBySpuId(Long spuId) {
-        return productSkuMapper.selectList(ProductSkuDO::getSpuId, spuId);
+    public List<ProductSkuDO> getSkuListBySpuId(Long spuId) {
+        return productSkuMapper.selectListBySpuId(spuId);
     }
 
     @Override
-    public List<ProductSkuDO> getSkusBySpuIds(List<Long> spuIds) {
-        return productSkuMapper.selectList(ProductSkuDO::getSpuId, spuIds);
+    public List<ProductSkuDO> getSkuListBySpuIdAndStatus(Long spuId, Integer status) {
+        return productSkuMapper.selectListBySpuIdAndStatus(spuId, status);
+    }
+
+    @Override
+    public List<ProductSkuDO> getSkuListBySpuId(List<Long> spuIds) {
+        return productSkuMapper.selectListBySpuId(spuIds);
     }
 
     @Override
@@ -144,13 +149,13 @@ public class ProductSkuServiceImpl implements ProductSkuService {
     }
 
     @Override
-    public List<ProductSkuDO> getSkusByAlarmStock() {
+    public List<ProductSkuDO> getSkuListByAlarmStock() {
         return productSkuMapper.selectListByAlarmStock();
     }
 
     @Override
     @Transactional
-    public void updateSkus(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> skus) {
+    public void updateSkuList(Long spuId, String spuName, List<ProductSkuCreateOrUpdateReqVO> skus) {
         // 查询 SPU 下已经存在的 SKU 的集合
         List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuId(spuId);
         // 构建属性与 SKU 的映射关系;

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

@@ -56,7 +56,7 @@ public interface ProductSpuService {
      * @param id 编号
      * @return 商品 SPU
      */
-    ProductSpuRespVO getSpu(Long id);
+    ProductSpuDO getSpu(Long id);
 
     /**
      * 获得商品 SPU 列表

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

@@ -72,7 +72,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         brandService.validateProductBrand(createReqVO.getBrandId());
         // 校验SKU
         List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = createReqVO.getSkus();
-        productSkuService.validateSkus(skuCreateReqList, createReqVO.getSpecType());
+        productSkuService.validateSkuList(skuCreateReqList, createReqVO.getSpecType());
         // 插入 SPU
         ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
         spu.setMarketPrice(CollectionUtils.getMaxValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
@@ -81,7 +81,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         spu.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
         productSpuMapper.insert(spu);
         // 插入 SKU
-        productSkuService.createSkus(spu.getId(), spu.getName(), skuCreateReqList);
+        productSkuService.createSkuList(spu.getId(), spu.getName(), skuCreateReqList);
         // 返回
         return spu.getId();
     }
@@ -97,7 +97,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         brandService.validateProductBrand(updateReqVO.getBrandId());
         // 校验SKU
         List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList = updateReqVO.getSkus();
-        productSkuService.validateSkus(skuCreateReqList, updateReqVO.getSpecType());
+        productSkuService.validateSkuList(skuCreateReqList, updateReqVO.getSpecType());
 
         // 更新 SPU
         ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
@@ -107,7 +107,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         updateObj.setTotalStock(CollectionUtils.getSumValue(skuCreateReqList, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
         productSpuMapper.updateById(updateObj);
         // 批量更新 SKU
-        productSkuService.updateSkus(updateObj.getId(), updateObj.getName(), updateReqVO.getSkus());
+        productSkuService.updateSkuList(updateObj.getId(), updateObj.getName(), updateReqVO.getSkus());
     }
 
     /**
@@ -146,7 +146,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         ProductSpuDO spu = productSpuMapper.selectById(id);
         ProductSpuDetailRespVO respVO = BeanUtil.copyProperties(spu, ProductSpuDetailRespVO.class);
         if (null != spu) {
-            List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkusBySpuId(id));
+            List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkuListBySpuId(id));
             respVO.setSkus(skuReqs);
             // 组合 sku 属性
             if (spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) {
@@ -181,8 +181,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
     }
 
     @Override
-    public ProductSpuRespVO getSpu(Long id) {
-        return ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectById(id));
+    public ProductSpuDO getSpu(Long id) {
+        return productSpuMapper.selectById(id);
     }
 
     @Override
@@ -200,7 +200,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         // 库存告警的 SPU 编号的集合
         Set<Long> alarmStockSpuIds = null;
         if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) {
-            alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkusByAlarmStock(), ProductSkuDO::getSpuId);
+            alarmStockSpuIds = CollectionUtils.convertSet(productSkuService.getSkuListByAlarmStock(), ProductSkuDO::getSpuId);
             if (CollUtil.isEmpty(alarmStockSpuIds)) {
                 return PageResult.empty();
             }

+ 3 - 3
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java

@@ -186,7 +186,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
 
         });
 
-        Mockito.when(productSkuService.getSkusBySpuId(createReqVO.getId())).thenReturn(productSkuDOS);
+        Mockito.when(productSkuService.getSkuListBySpuId(createReqVO.getId())).thenReturn(productSkuDOS);
 //        Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO);
 //        Mockito.when(productPropertyService.getPropertyVOList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS);
 //
@@ -202,7 +202,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
         ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class);
         productSpuMapper.insert(createReqVO);
 
-        ProductSpuRespVO spu = productSpuService.getSpu(createReqVO.getId());
+        ProductSpuDO spu = productSpuService.getSpu(createReqVO.getId());
         assertPojoEquals(createReqVO, spu);
     }
 
@@ -267,7 +267,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
             o.setSpuId(createReqVO.getId());
         }));
 
-        Mockito.when(productSkuService.getSkusByAlarmStock()).thenReturn(productSpuDOS);
+        Mockito.when(productSkuService.getSkuListByAlarmStock()).thenReturn(productSpuDOS);
 
         // 调用
         ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();