Browse Source

✨ MALL:简化 SPU 的 VO 转化

YunaiV 1 year ago
parent
commit
f6c8159dac
32 changed files with 312 additions and 663 deletions
  1. 16 0
      yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java
  2. 5 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java
  3. 9 7
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
  4. 3 3
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java
  5. 0 22
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java
  6. 0 14
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java
  7. 0 16
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java
  8. 0 18
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java
  9. 19 17
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
  10. 51 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java
  11. 5 13
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java
  12. 0 24
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java
  13. 0 22
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java
  14. 0 90
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java
  15. 0 32
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java
  16. 95 12
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java
  17. 22 11
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSaveReqVO.java
  18. 0 41
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java
  19. 17 35
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
  20. 0 9
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java
  21. 1 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuRespVO.java
  22. 0 21
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java
  23. 9 71
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
  24. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
  25. 0 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java
  26. 0 35
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
  27. 4 18
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java
  28. 17 28
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
  29. 5 33
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
  30. 19 33
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
  31. 6 6
      yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java
  32. 9 16
      yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java

+ 16 - 0
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java

@@ -21,6 +21,14 @@ public class BeanUtils {
         return BeanUtil.toBean(source, targetClass);
     }
 
+    public static <T> T toBean(Object source, Class<T> targetClass, Consumer<T> peek) {
+        T target = toBean(source, targetClass);
+        if (target != null) {
+            peek.accept(target);
+        }
+        return target;
+    }
+
     public static <S, T> List<T> toBean(List<S> source, Class<T> targetType) {
         if (source == null) {
             return null;
@@ -28,6 +36,14 @@ public class BeanUtils {
         return CollectionUtils.convertList(source, s -> toBean(s, targetType));
     }
 
+    public static <S, T> List<T> toBean(List<S> source, Class<T> targetType, Consumer<T> peek) {
+        List<T> list = toBean(source, targetType);
+        if (list != null) {
+            list.forEach(peek);
+        }
+        return list;
+    }
+
     public static <S, T> PageResult<T> toBean(PageResult<S> source, Class<T> targetType) {
         return toBean(source, targetType, null);
     }

+ 5 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java

@@ -1,14 +1,14 @@
 package cn.iocoder.yudao.module.product.api.sku;
 
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 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.convert.sku.ProductSkuConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
+import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
-import jakarta.annotation.Resource;
 import java.util.Collection;
 import java.util.List;
 
@@ -28,19 +28,19 @@ public class ProductSkuApiImpl implements ProductSkuApi {
     @Override
     public ProductSkuRespDTO getSku(Long id) {
         ProductSkuDO sku = productSkuService.getSku(id);
-        return ProductSkuConvert.INSTANCE.convert02(sku);
+        return BeanUtils.toBean(sku, ProductSkuRespDTO.class);
     }
 
     @Override
     public List<ProductSkuRespDTO> getSkuList(Collection<Long> ids) {
         List<ProductSkuDO> skus = productSkuService.getSkuList(ids);
-        return ProductSkuConvert.INSTANCE.convertList04(skus);
+        return BeanUtils.toBean(skus, ProductSkuRespDTO.class);
     }
 
     @Override
     public List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds) {
         List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spuIds);
-        return ProductSkuConvert.INSTANCE.convertList04(skus);
+        return BeanUtils.toBean(skus, ProductSkuRespDTO.class);
     }
 
     @Override

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

@@ -1,15 +1,14 @@
 package cn.iocoder.yudao.module.product.api.spu;
 
-import cn.hutool.core.collection.CollectionUtil;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 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.service.spu.ProductSpuService;
+import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
-import jakarta.annotation.Resource;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -27,17 +26,20 @@ public class ProductSpuApiImpl implements ProductSpuApi {
 
     @Override
     public List<ProductSpuRespDTO> getSpuList(Collection<Long> ids) {
-        return ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids));
+        List<ProductSpuDO> spus = spuService.getSpuList(ids);
+        return BeanUtils.toBean(spus, ProductSpuRespDTO.class);
     }
 
     @Override
     public List<ProductSpuRespDTO> validateSpuList(Collection<Long> ids) {
-        return ProductSpuConvert.INSTANCE.convertList2(spuService.validateSpuList(ids));
+        List<ProductSpuDO> spus = spuService.validateSpuList(ids);
+        return BeanUtils.toBean(spus, ProductSpuRespDTO.class);
     }
 
     @Override
     public ProductSpuRespDTO getSpu(Long id) {
-        return ProductSpuConvert.INSTANCE.convert02(spuService.getSpu(id));
+        ProductSpuDO spu = spuService.getSpu(id);
+        return BeanUtils.toBean(spu, ProductSpuRespDTO.class);
     }
 
 }

+ 3 - 3
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java

@@ -1,12 +1,12 @@
 package cn.iocoder.yudao.module.product.controller.admin.comment.vo;
 
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSkuSaveReqVO;
 import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
-import jakarta.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -58,6 +58,6 @@ public class ProductCommentRespVO extends ProductCommentBaseVO {
     private String skuPicUrl;
 
     @Schema(description = "商品 SKU 规格值数组")
-    private List<ProductSkuBaseVO.Property> skuProperties;
+    private List<ProductSkuSaveReqVO.Property> skuProperties;
 
 }

+ 0 - 22
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "管理后台 - 商品属性值的明细 Response VO")
-@Data
-public class ProductPropertyValueDetailRespVO {
-
-    @Schema(description = "属性的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long propertyId;
-
-    @Schema(description = "属性的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "颜色")
-    private String propertyName;
-
-    @Schema(description = "属性值的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    private Long valueId;
-
-    @Schema(description = "属性值的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "红色")
-    private String valueName;
-
-}

+ 0 - 14
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java

@@ -1,14 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.sku;
-
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@Tag(name = "管理后台 - 商品 SKU")
-@RestController
-@RequestMapping("/product/sku")
-@Validated
-public class ProductSkuController {
-
-}

+ 0 - 16
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.util.List;
-
-@Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO {
-
-}

+ 0 - 18
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java

@@ -1,18 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-
-import jakarta.validation.constraints.NotNull;
-import java.util.List;
-
-@Schema(description = "管理后台 - 商品 SKU Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ProductSkuRespVO extends ProductSkuBaseVO {
-
-    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    private Long id;
-
-}

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

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.controller.admin.spu;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
@@ -14,23 +15,22 @@ import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.Valid;
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
-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.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
 
 @Tag(name = "管理后台 - 商品 SPU")
 @RestController
@@ -46,14 +46,14 @@ public class ProductSpuController {
     @PostMapping("/create")
     @Operation(summary = "创建商品 SPU")
     @PreAuthorize("@ss.hasPermission('product:spu:create')")
-    public CommonResult<Long> createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) {
+    public CommonResult<Long> createProductSpu(@Valid @RequestBody ProductSpuSaveReqVO createReqVO) {
         return success(productSpuService.createSpu(createReqVO));
     }
 
     @PutMapping("/update")
     @Operation(summary = "更新商品 SPU")
     @PreAuthorize("@ss.hasPermission('product:spu:update')")
-    public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) {
+    public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuSaveReqVO updateReqVO) {
         productSpuService.updateSpu(updateReqVO);
         return success(true);
     }
@@ -79,15 +79,15 @@ public class ProductSpuController {
     @Operation(summary = "获得商品 SPU 明细")
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
     @PreAuthorize("@ss.hasPermission('product:spu:query')")
-    public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
+    public CommonResult<ProductSpuRespVO> getSpuDetail(@RequestParam("id") Long id) {
         // 获得商品 SPU
         ProductSpuDO spu = productSpuService.getSpu(id);
         if (spu == null) {
-            throw exception(SPU_NOT_EXISTS);
+            return success(null);
         }
         // 查询商品 SKU
         List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
-        return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus));
+        return success(ProductSpuConvert.INSTANCE.convert(spu, skus));
     }
 
     @GetMapping("/list-all-simple")
@@ -97,14 +97,14 @@ public class ProductSpuController {
         List<ProductSpuDO> list = productSpuService.getSpuListByStatus(ProductSpuStatusEnum.ENABLE.getStatus());
         // 降序排序后,返回给前端
         list.sort(Comparator.comparing(ProductSpuDO::getSort).reversed());
-        return success(ProductSpuConvert.INSTANCE.convertList02(list));
+        return success(BeanUtils.toBean(list, ProductSpuSimpleRespVO.class));
     }
 
     @GetMapping("/list")
     @Operation(summary = "获得商品 SPU 详情列表")
     @Parameter(name = "spuIds", description = "spu 编号列表", required = true, example = "[1,2,3]")
     @PreAuthorize("@ss.hasPermission('product:spu:query')")
-    public CommonResult<List<ProductSpuDetailRespVO>> getSpuList(@RequestParam("spuIds") Collection<Long> spuIds) {
+    public CommonResult<List<ProductSpuRespVO>> getSpuList(@RequestParam("spuIds") Collection<Long> spuIds) {
         return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespListVO(
                 productSpuService.getSpuList(spuIds), productSkuService.getSkuListBySpuId(spuIds)));
     }
@@ -113,7 +113,8 @@ public class ProductSpuController {
     @Operation(summary = "获得商品 SPU 分页")
     @PreAuthorize("@ss.hasPermission('product:spu:query')")
     public CommonResult<PageResult<ProductSpuRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) {
-        return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO)));
+        PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO);
+        return success(BeanUtils.toBean(pageResult, ProductSpuRespVO.class));
     }
 
     @GetMapping("/get-count")
@@ -127,12 +128,13 @@ public class ProductSpuController {
     @Operation(summary = "导出商品")
     @PreAuthorize("@ss.hasPermission('product:spu:export')")
     @OperateLog(type = EXPORT)
-    public void exportUserList(@Validated ProductSpuExportReqVO reqVO,
+    public void exportSpuList(@Validated ProductSpuPageReqVO reqVO,
                                HttpServletResponse response) throws IOException {
-        List<ProductSpuDO> spuList = productSpuService.getSpuList(reqVO);
+        reqVO.setPageSize(PAGE_SIZE_NONE);
+        List<ProductSpuDO> list = productSpuService.getSpuPage(reqVO).getList();
         // 导出 Excel
-        List<ProductSpuExcelVO> datas = ProductSpuConvert.INSTANCE.convertList03(spuList);
-        ExcelUtils.write(response, "商品列表.xls", "数据", ProductSpuExcelVO.class, datas);
+        ExcelUtils.write(response, "商品列表.xls", "数据", ProductSpuRespVO.class,
+                BeanUtils.toBean(list, ProductSpuRespVO.class));
     }
 
 }

+ 51 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "管理后台 - 商品 SKU Response VO")
+@Data
+public class ProductSkuRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+    private Long id;
+
+    @Schema(description = "商品 SKU 名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉小短袖")
+    private String name;
+
+    @Schema(description = "销售价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999")
+    private Integer price;
+
+    @Schema(description = "市场价", example = "2999")
+    private Integer marketPrice;
+
+    @Schema(description = "成本价", example = "19")
+    private Integer costPrice;
+
+    @Schema(description = "条形码", example = "15156165456")
+    private String barCode;
+
+    @Schema(description = "图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
+    private String picUrl;
+
+    @Schema(description = "库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "200")
+    private Integer stock;
+
+    @Schema(description = "商品重量,单位:kg 千克", example = "1.2")
+    private Double weight;
+
+    @Schema(description = "商品体积,单位:m^3 平米", example = "2.5")
+    private Double volume;
+
+    @Schema(description = "一级分销的佣金,单位:分", example = "199")
+    private Integer firstBrokeragePrice;
+
+    @Schema(description = "二级分销的佣金,单位:分", example = "19")
+    private Integer secondBrokeragePrice;
+
+    @Schema(description = "属性数组")
+    private List<ProductSkuSaveReqVO.Property> properties;
+
+}

+ 5 - 13
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java → yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java

@@ -1,20 +1,15 @@
-package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
+package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
+import lombok.*;
+
 import java.util.List;
 
-/**
-* 商品 SKU Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
+@Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO")
 @Data
-public class ProductSkuBaseVO {
+public class ProductSkuSaveReqVO {
 
     @Schema(description = "商品 SKU 名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉小短袖")
     @NotEmpty(message = "商品 SKU 名字不能为空")
@@ -41,9 +36,6 @@ public class ProductSkuBaseVO {
     @NotNull(message = "库存不能为空")
     private Integer stock;
 
-    @Schema(description = "预警预存", example = "10")
-    private Integer warnStock;
-
     @Schema(description = "商品重量,单位:kg 千克", example = "1.2")
     private Double weight;
 

+ 0 - 24
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
-
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import jakarta.validation.Valid;
-import java.util.List;
-
-@Schema(description = "管理后台 - 商品 SPU 创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ProductSpuCreateReqVO extends ProductSpuBaseVO {
-
-    // ========== SKU 相关字段 =========
-
-    @Schema(description = "SKU 数组")
-    @Valid
-    private List<ProductSkuCreateOrUpdateReqVO> skus;
-
-}

+ 0 - 22
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
-
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import java.util.List;
-
-@Schema(description = "管理后台 - 商品 SPU 详细 Response VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ProductSpuDetailRespVO extends ProductSpuRespVO {
-
-    // ========== SKU 相关字段 =========
-
-    @Schema(description = "SKU 数组")
-    private List<ProductSkuRespVO> skus;
-
-}

+ 0 - 90
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java

@@ -1,90 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
-
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
-import com.alibaba.excel.annotation.ExcelProperty;
-import lombok.Data;
-
-
-import java.time.LocalDateTime;
-
-/**
- * 商品 Spu Excel 导出 VO TODO 暂定
- *
- * @author HUIHUI
- */
-@Data
-public class ProductSpuExcelVO {
-
-    @ExcelProperty("商品编号")
-    private Long id;
-
-    @ExcelProperty("商品名称")
-    private String name;
-
-    @ExcelProperty("关键字")
-    private String keyword;
-
-    @ExcelProperty("商品简介")
-    private String introduction;
-
-    @ExcelProperty("商品详情")
-    private String description;
-
-    @ExcelProperty("条形码")
-    private String barCode;
-
-    @ExcelProperty("商品分类编号")
-    private Long categoryId;
-
-    @ExcelProperty("商品品牌编号")
-    private Long brandId;
-
-    @ExcelProperty("商品封面图")
-    private String picUrl;
-
-    @ExcelProperty("排序字段")
-    private Integer sort;
-
-    @ExcelProperty(value = "商品状态", converter = DictConvert.class)
-    @DictFormat(DictTypeConstants.PRODUCT_SPU_STATUS)
-    private Integer status;
-
-    @ExcelProperty("规格类型")
-    private Boolean specType;
-
-    @ExcelProperty("商品价格")
-    private Integer price;
-
-    @ExcelProperty("市场价")
-    private Integer marketPrice;
-
-    @ExcelProperty("成本价")
-    private Integer costPrice;
-
-    @ExcelProperty("库存")
-    private Integer stock;
-
-    @ExcelProperty("物流配置模板编号")
-    private Long deliveryTemplateId;
-
-    @ExcelProperty("赠送积分")
-    private Integer giveIntegral;
-
-    @ExcelProperty("分销类型")
-    private Boolean subCommissionType;
-
-    @ExcelProperty("商品销量")
-    private Integer salesCount;
-
-    @ExcelProperty("虚拟销量")
-    private Integer virtualSalesCount;
-
-    @ExcelProperty("商品点击量")
-    private Integer browseCount;
-
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-}

+ 0 - 32
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java

@@ -1,32 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.time.LocalDateTime;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@Schema(description = "管理后台 - 商品 SPU 导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class ProductSpuExportReqVO {
-
-    @Schema(description = "商品名称", example = "清凉小短袖")
-    private String name;
-
-    @Schema(description = "前端请求的tab类型", example = "1")
-    private Integer tabType;
-
-    @Schema(description = "商品分类编号", example = "100")
-    private Long categoryId;
-
-    @Schema(description = "创建时间", example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] createTime;
-
-}

+ 95 - 12
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java

@@ -1,43 +1,126 @@
 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
 
+import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
+import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
+import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert;
+import cn.iocoder.yudao.module.product.enums.DictTypeConstants;
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "管理后台 - 商品 SPU Response VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ProductSpuRespVO extends ProductSpuBaseVO {
+@ExcelIgnoreUnannotated
+public class ProductSpuRespVO {
 
     @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "111")
+    @ExcelProperty("商品编号")
     private Long id;
 
+    @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉小短袖")
+    @ExcelProperty("商品名称")
+    private String name;
+
+    @Schema(description = "关键字", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑不出汗")
+    @ExcelProperty("关键字")
+    private String keyword;
+
+    @Schema(description = "商品简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉小短袖简介")
+    @ExcelProperty("商品简介")
+    private String introduction;
+
+    @Schema(description = "商品详情", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉小短袖详情")
+    @ExcelProperty("商品详情")
+    private String description;
+
+    @Schema(description = "商品分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("商品分类编号")
+    private Long categoryId;
+
+    @Schema(description = "商品品牌编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("商品品牌编号")
+    private Long brandId;
+
+    @Schema(description = "商品封面图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
+    @ExcelProperty("商品封面图")
+    private String picUrl;
+
+    @Schema(description = "商品轮播图", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
+    private List<String> sliderPicUrls;
+
+    @Schema(description = "排序字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("排序字段")
+    private Integer sort;
+
+    @Schema(description = "商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty(value = "商品状态", converter = DictConvert.class)
+    @DictFormat(DictTypeConstants.PRODUCT_SPU_STATUS)
+    private Integer status;
+
+    @Schema(description = "商品创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-05-24 00:00:00")
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    // ========== SKU 相关字段 =========
+
+    @Schema(description = "规格类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @ExcelProperty("规格类型")
+    private Boolean specType;
+
     @Schema(description = "商品价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999")
+    @ExcelProperty(value = "商品价格", converter = MoneyConvert.class)
     private Integer price;
 
-    @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000")
-    private Integer salesCount;
-
     @Schema(description = "市场价,单位使用:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "199")
+    @ExcelProperty(value = "市场价", converter = MoneyConvert.class)
     private Integer marketPrice;
 
     @Schema(description = "成本价,单位使用:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "19")
+    @ExcelProperty(value = "成本价", converter = MoneyConvert.class)
     private Integer costPrice;
 
     @Schema(description = "商品库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000")
+    @ExcelProperty("库存")
     private Integer stock;
 
-    @Schema(description = "商品创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-05-24 00:00:00")
-    private LocalDateTime createTime;
+    @Schema(description = "SKU 数组")
+    private List<ProductSkuRespVO> skus;
 
-    @Schema(description = "商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Integer status;
+    // ========== 物流相关字段 =========
+
+    @Schema(description = "配送方式数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private List<Integer> deliveryTypes;
+
+    @Schema(description = "物流配置模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "111")
+    @ExcelProperty("物流配置模板编号")
+    private Long deliveryTemplateId;
+
+    // ========== 营销相关字段 =========
+
+    @Schema(description = "赠送积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "111")
+    @ExcelProperty("赠送积分")
+    private Integer giveIntegral;
+
+    @Schema(description = "分销类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+    @ExcelProperty("分销类型")
+    private Boolean subCommissionType;
+
+    // ========== 统计相关字段 =========
+
+    @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000")
+    @ExcelProperty("商品销量")
+    private Integer salesCount;
+
+    @Schema(description = "虚拟销量", example = "66")
+    @ExcelProperty("虚拟销量")
+    private Integer virtualSalesCount;
 
     @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
+    @ExcelProperty("商品点击量")
     private Integer browseCount;
 
 }

+ 22 - 11
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java → yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSaveReqVO.java

@@ -1,20 +1,19 @@
 package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
+import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
 import java.util.List;
 
-/**
-* 商品 SPU Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
- *
- * @author HUIHUI
- */
+@Schema(description = "管理后台 - 商品 SPU 新增/更新 Request VO")
 @Data
-public class ProductSpuBaseVO {
+public class ProductSpuSaveReqVO {
+
+    @Schema(description = "商品编号", example = "1")
+    private Long id;
 
     @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉小短袖")
     @NotEmpty(message = "商品名称不能为空")
@@ -44,7 +43,8 @@ public class ProductSpuBaseVO {
     @NotEmpty(message = "商品封面图不能为空")
     private String picUrl;
 
-    @Schema(description = "商品轮播图", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
+    @Schema(description = "商品轮播图", requiredMode = Schema.RequiredMode.REQUIRED,
+            example = "[https://www.iocoder.cn/xx.png, https://www.iocoder.cn/xxx.png]")
     private List<String> sliderPicUrls;
 
     @Schema(description = "排序字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@@ -64,7 +64,6 @@ public class ProductSpuBaseVO {
     private List<Integer> deliveryTypes;
 
     @Schema(description = "物流配置模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "111")
-    @NotNull(message = "物流配置模板编号不能为空")
     private Long deliveryTemplateId;
 
     // ========== 营销相关字段 =========
@@ -82,4 +81,16 @@ public class ProductSpuBaseVO {
     @Schema(description = "虚拟销量", example = "66")
     private Integer virtualSalesCount;
 
+    @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999")
+    private Integer salesCount;
+
+    @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999")
+    private Integer browseCount;
+
+    // ========== SKU 相关字段 =========
+
+    @Schema(description = "SKU 数组")
+    @Valid
+    private List<ProductSkuSaveReqVO> skus;
+
 }

+ 0 - 41
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java

@@ -1,41 +0,0 @@
-package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
-
-import cn.iocoder.yudao.framework.common.validation.InEnum;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
-import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotNull;
-import java.util.List;
-
-@Schema(description = "管理后台 - 商品 SPU 更新 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ProductSpuUpdateReqVO extends ProductSpuBaseVO {
-
-    @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "商品编号不能为空")
-    private Long id;
-
-    @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999")
-    private Integer salesCount;
-
-    @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999")
-    private Integer browseCount;
-
-    @Schema(description = "商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @InEnum(ProductSpuStatusEnum.class)
-    private Integer status;
-
-    // ========== SKU 相关字段 =========
-
-    @Schema(description = "SKU 数组")
-    @Valid
-    private List<ProductSkuCreateOrUpdateReqVO> skus;
-
-}

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

@@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.product.controller.app.spu;
 import cn.hutool.core.collection.CollUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
 import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
-import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO;
-import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
+import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuRespVO;
 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;
@@ -19,16 +19,15 @@ import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.Parameters;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
-import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
@@ -57,39 +56,18 @@ public class AppProductSpuController {
     @Resource
     private MemberUserApi memberUserApi;
 
-    @GetMapping("/list")
-    @Operation(summary = "获得商品 SPU 列表")
-    @Parameters({
-            @Parameter(name = "recommendType", description = "推荐类型", required = true), // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量
-            @Parameter(name = "count", description = "数量", required = true)
-    })
-    public CommonResult<List<AppProductSpuPageRespVO>> getSpuList(
-            @RequestParam("recommendType") String recommendType,
-            @RequestParam(value = "count", defaultValue = "10") Integer count) {
-        List<ProductSpuDO> list = productSpuService.getSpuList(recommendType, count);
-        if (CollUtil.isEmpty(list)) {
-            return success(Collections.emptyList());
-        }
-
-        // 拼接返回
-        List<AppProductSpuPageRespVO> voList = ProductSpuConvert.INSTANCE.convertListForGetSpuList(list);
-        // 处理 vip 价格
-        MemberLevelRespDTO memberLevel = getMemberLevel();
-        voList.forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));
-        return success(voList);
-    }
-
     @GetMapping("/list-by-ids")
     @Operation(summary = "获得商品 SPU 列表")
     @Parameter(name = "ids", description = "编号列表", required = true)
-    public CommonResult<List<AppProductSpuPageRespVO>> getSpuList(@RequestParam("ids") Set<Long> ids) {
+    public CommonResult<List<AppProductSpuRespVO>> getSpuList(@RequestParam("ids") Set<Long> ids) {
         List<ProductSpuDO> list = productSpuService.getSpuList(ids);
         if (CollUtil.isEmpty(list)) {
             return success(Collections.emptyList());
         }
 
         // 拼接返回
-        List<AppProductSpuPageRespVO> voList = ProductSpuConvert.INSTANCE.convertListForGetSpuList(list);
+        list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
+        List<AppProductSpuRespVO> voList = BeanUtils.toBean(list, AppProductSpuRespVO.class);
         // 处理 vip 价格
         MemberLevelRespDTO memberLevel = getMemberLevel();
         voList.forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));
@@ -98,14 +76,15 @@ public class AppProductSpuController {
 
     @GetMapping("/page")
     @Operation(summary = "获得商品 SPU 分页")
-    public CommonResult<PageResult<AppProductSpuPageRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
+    public CommonResult<PageResult<AppProductSpuRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
         PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO);
         if (CollUtil.isEmpty(pageResult.getList())) {
             return success(PageResult.empty(pageResult.getTotal()));
         }
 
         // 拼接返回
-        PageResult<AppProductSpuPageRespVO> voPageResult = ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult);
+        pageResult.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
+        PageResult<AppProductSpuRespVO> voPageResult = BeanUtils.toBean(pageResult, AppProductSpuRespVO.class);
         // 处理 vip 价格
         MemberLevelRespDTO memberLevel = getMemberLevel();
         voPageResult.getList().forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));
@@ -124,6 +103,8 @@ public class AppProductSpuController {
         if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
             throw exception(SPU_NOT_ENABLE);
         }
+        // 获得商品 SKU
+        List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
 
         // 增加浏览量
         productSpuService.updateBrowseCount(id, 1);
@@ -131,12 +112,13 @@ public class AppProductSpuController {
         productBrowseHistoryService.createBrowseHistory(getLoginUserId(), id);
 
         // 拼接返回
-        List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
-        AppProductSpuDetailRespVO detailVO = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus);
+        spu.setBrowseCount(spu.getBrowseCount() + spu.getVirtualSalesCount());
+        AppProductSpuDetailRespVO spuVO = BeanUtils.toBean(spu, AppProductSpuDetailRespVO.class)
+                .setSkus(BeanUtils.toBean(skus, AppProductSpuDetailRespVO.Sku.class));
         // 处理 vip 价格
         MemberLevelRespDTO memberLevel = getMemberLevel();
-        detailVO.setVipPrice(calculateVipPrice(detailVO.getPrice(), memberLevel));
-        return success(detailVO);
+        spuVO.setVipPrice(calculateVipPrice(spuVO.getPrice(), memberLevel));
+        return success(spuVO);
     }
 
     private MemberLevelRespDTO getMemberLevel() {

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

@@ -21,12 +21,6 @@ public class AppProductSpuPageReqVO extends PageParam {
     public static final String SORT_FIELD_SALES_COUNT = "salesCount";
     public static final String SORT_FIELD_CREATE_TIME = "createTime";
 
-    public static final String RECOMMEND_TYPE_HOT = "hot";
-    public static final String RECOMMEND_TYPE_BENEFIT = "benefit";
-    public static final String RECOMMEND_TYPE_BEST = "best";
-    public static final String RECOMMEND_TYPE_NEW = "new";
-    public static final String RECOMMEND_TYPE_GOOD = "good";
-
     @Schema(description = "商品 SPU 编号数组", example = "1,3,5")
     private List<Long> ids;
 
@@ -45,9 +39,6 @@ public class AppProductSpuPageReqVO extends PageParam {
     @Schema(description = "排序方式", example = "true")
     private Boolean sortAsc;
 
-    @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量
-    private String recommendType;
-
     @AssertTrue(message = "排序字段不合法")
     @JsonIgnore
     public boolean isSortFieldValid() {

+ 1 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java → yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuRespVO.java

@@ -7,7 +7,7 @@ import java.util.List;
 
 @Schema(description = "用户 App - 商品 SPU Response VO")
 @Data
-public class AppProductSpuPageRespVO {
+public class AppProductSpuRespVO {
 
     @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     private Long id;

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

@@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.product.convert.sku;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
-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;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
@@ -25,24 +22,6 @@ public interface ProductSkuConvert {
 
     ProductSkuConvert INSTANCE = Mappers.getMapper(ProductSkuConvert.class);
 
-    ProductSkuDO convert(ProductSkuCreateOrUpdateReqVO bean);
-
-    ProductSkuRespVO convert(ProductSkuDO bean);
-
-    List<ProductSkuRespVO> convertList(List<ProductSkuDO> list);
-
-    List<ProductSkuDO> convertList06(List<ProductSkuCreateOrUpdateReqVO> list);
-
-    default List<ProductSkuDO> convertList06(List<ProductSkuCreateOrUpdateReqVO> list, Long spuId) {
-        List<ProductSkuDO> result = convertList06(list);
-        result.forEach(item -> item.setSpuId(spuId));
-        return result;
-    }
-
-    ProductSkuRespDTO convert02(ProductSkuDO bean);
-
-    List<ProductSkuRespDTO> convertList04(List<ProductSkuDO> list);
-
     /**
      * 获得 SPU 的库存变化 Map
      *

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

@@ -1,25 +1,19 @@
 package cn.iocoder.yudao.module.product.convert.spu;
 
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-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.spu.vo.AppProductSpuDetailRespVO;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSkuRespVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
-import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO;
-import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
 import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
-import org.mapstruct.Named;
 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.convertMultiMap;
 
 /**
@@ -32,73 +26,17 @@ public interface ProductSpuConvert {
 
     ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
 
-    ProductSpuDO convert(ProductSpuCreateReqVO bean);
-
-    ProductSpuDO convert(ProductSpuUpdateReqVO bean);
-
-    List<ProductSpuDO> convertList(List<ProductSpuDO> list);
-
-    PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page);
-
     ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean);
 
-    List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list);
-
-    List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
-
-    @Mapping(target = "price", expression = "java(spu.getPrice() / 100)")
-    @Mapping(target = "marketPrice", expression = "java(spu.getMarketPrice() / 100)")
-    @Mapping(target = "costPrice", expression = "java(spu.getCostPrice() / 100)")
-    ProductSpuExcelVO convert(ProductSpuDO spu);
-
-    default List<ProductSpuExcelVO> convertList03(List<ProductSpuDO> list) {
-        List<ProductSpuExcelVO> spuExcelVOs = new ArrayList<>();
-        list.forEach(spu -> {
-            ProductSpuExcelVO spuExcelVO = convert(spu);
-            spuExcelVOs.add(spuExcelVO);
-        });
-        return spuExcelVOs;
-    }
-
-    ProductSpuDetailRespVO convert03(ProductSpuDO spu);
-
-    ProductSpuRespDTO convert02(ProductSpuDO bean);
-
-    // ========== 用户 App 相关 ==========
-
-    PageResult<AppProductSpuPageRespVO> convertPageForGetSpuPage(PageResult<ProductSpuDO> page);
-
-    default List<AppProductSpuPageRespVO> convertListForGetSpuList(List<ProductSpuDO> list) {
-        // 处理虚拟销量
-        list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
-        // 处理 VO 字段
-        return convertListForGetSpuList0(list);
-    }
-
-    @Named("convertListForGetSpuList0")
-    List<AppProductSpuPageRespVO> convertListForGetSpuList0(List<ProductSpuDO> list);
-
-    default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus) {
-        // 处理 SPU
-        AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu)
-                .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0));
-        // 处理 SKU
-        spuVO.setSkus(convertListForGetSpuDetail(skus));
+    default ProductSpuRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus) {
+        ProductSpuRespVO spuVO = BeanUtils.toBean(spu, ProductSpuRespVO.class);
+        spuVO.setSkus(BeanUtils.toBean(skus, ProductSkuRespVO.class));
         return spuVO;
     }
 
-    AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu);
-
-    List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus);
-
-    default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) {
-        return convert03(spu).setSkus(ProductSkuConvert.INSTANCE.convertList(skus));
-    }
-
-    default List<ProductSpuDetailRespVO> convertForSpuDetailRespListVO(List<ProductSpuDO> spus, List<ProductSkuDO> skus) {
+    default List<ProductSpuRespVO> convertForSpuDetailRespListVO(List<ProductSpuDO> spus, List<ProductSkuDO> skus) {
         Map<Long, List<ProductSkuDO>> skuMultiMap = convertMultiMap(skus, ProductSkuDO::getSpuId);
-        return CollectionUtils.convertList(spus, spu -> convert03(spu)
-                .setSkus(ProductSkuConvert.INSTANCE.convertList(skuMultiMap.get(spu.getId()))));
+        return CollectionUtils.convertList(spus, spu -> convert(spu, skuMultiMap.get(spu.getId())));
     }
 
 }

+ 0 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java

@@ -54,11 +54,6 @@ public class ProductSpuDO extends BaseDO {
      * 商品详情
      */
     private String description;
-    // TODO @芋艿:是不是要删除
-    /**
-     * 商品条码(一维码)
-     */
-    private String barCode;
 
     /**
      * 商品分类编号

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

@@ -4,7 +4,6 @@ import cn.hutool.core.lang.Assert;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -56,8 +55,4 @@ public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
         return update(null, updateWrapper);
     }
 
-    default List<ProductSkuDO> selectListByAlarmStock() {
-        return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
-    }
-
 }

+ 0 - 35
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java

@@ -1,12 +1,9 @@
 package cn.iocoder.yudao.module.product.dal.mysql.spu;
 
-import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuExportReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
@@ -15,7 +12,6 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
 
-import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 
@@ -81,21 +77,6 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
         return selectPage(pageReqVO, query);
     }
 
-    default List<ProductSpuDO> selectListByRecommendType(String recommendType, Integer count) {
-        QueryWrapperX<ProductSpuDO> query = new QueryWrapperX<>();
-        // 上架状态 且有库存
-        query.eq("status", ProductSpuStatusEnum.ENABLE.getStatus()).gt("stock", 0);
-        // 推荐类型的过滤条件
-        if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) {
-            query.eq("recommend_hot", true);
-        } else if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) {
-            query.eq("recommend_good", true);
-        }
-        // 设置最大长度
-        query.limitN(count);
-        return selectList(query);
-    }
-
     /**
      * 更新商品 SPU 库存
      *
@@ -110,22 +91,6 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
         update(null, updateWrapper);
     }
 
-    /**
-     * 获得 Spu 列表
-     *
-     * @param reqVO 查询条件
-     * @return Spu 列表
-     */
-    default List<ProductSpuDO> selectList(ProductSpuExportReqVO reqVO) {
-        Integer tabType = reqVO.getTabType();
-        LambdaQueryWrapperX<ProductSpuDO> queryWrapper = new LambdaQueryWrapperX<>();
-        queryWrapper.eqIfPresent(ProductSpuDO::getName, reqVO.getName());
-        queryWrapper.eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId());
-        queryWrapper.betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime());
-        appendTabQuery(tabType, queryWrapper);
-        return selectList(queryWrapper);
-    }
-
     /**
      * 添加后台 Tab 选项的查询条件
      *

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

@@ -1,7 +1,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.controller.admin.spu.vo.ProductSkuSaveReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 
 import java.util.Collection;
@@ -29,13 +29,6 @@ public interface ProductSkuService {
      */
     ProductSkuDO getSku(Long id);
 
-    /**
-     * 获得商品 SKU 列表
-     *
-     * @return 商品sku列表
-     */
-    List<ProductSkuDO> getSkuList();
-
     /**
      * 获得商品 SKU 列表
      *
@@ -49,7 +42,7 @@ public interface ProductSkuService {
      *
      * @param list sku组合的集合
      */
-    void validateSkuList(List<ProductSkuCreateOrUpdateReqVO> list, Boolean specType);
+    void validateSkuList(List<ProductSkuSaveReqVO> list, Boolean specType);
 
     /**
      * 批量创建 SKU
@@ -57,7 +50,7 @@ public interface ProductSkuService {
      * @param spuId 商品 SPU 编号
      * @param list  SKU 对象集合
      */
-    void createSkuList(Long spuId, List<ProductSkuCreateOrUpdateReqVO> list);
+    void createSkuList(Long spuId, List<ProductSkuSaveReqVO> list);
 
     /**
      * 根据 SPU 编号,批量更新它的 SKU 信息
@@ -65,7 +58,7 @@ public interface ProductSkuService {
      * @param spuId SPU 编码
      * @param skus  SKU 的集合
      */
-    void updateSkuList(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus);
+    void updateSkuList(Long spuId, List<ProductSkuSaveReqVO> skus);
 
     /**
      * 更新 SKU 库存(增量)
@@ -99,13 +92,6 @@ public interface ProductSkuService {
      */
     void deleteSkuBySpuId(Long spuId);
 
-    /**
-     * 获得库存预警的 SKU 数组
-     *
-     * @return SKU 数组
-     */
-    List<ProductSkuDO> getSkuListByAlarmStock();
-
     /**
      * 更新 sku 属性
      *

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

@@ -3,9 +3,9 @@ package cn.iocoder.yudao.module.product.service.sku;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSkuSaveReqVO;
 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
@@ -14,12 +14,12 @@ import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper;
 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
 import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
+import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import jakarta.annotation.Resource;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -68,11 +68,6 @@ public class ProductSkuServiceImpl implements ProductSkuService {
         return productSkuMapper.selectById(id);
     }
 
-    @Override
-    public List<ProductSkuDO> getSkuList() {
-        return productSkuMapper.selectList();
-    }
-
     @Override
     public List<ProductSkuDO> getSkuList(Collection<Long> ids) {
         if (CollUtil.isEmpty(ids)) {
@@ -82,20 +77,18 @@ public class ProductSkuServiceImpl implements ProductSkuService {
     }
 
     @Override
-    public void validateSkuList(List<ProductSkuCreateOrUpdateReqVO> skus, Boolean specType) {
+    public void validateSkuList(List<ProductSkuSaveReqVO> skus, Boolean specType) {
         // 0、校验skus是否为空
         if (CollUtil.isEmpty(skus)) {
             throw exception(SKU_NOT_EXISTS);
         }
         // 单规格,赋予单规格默认属性
         if (ObjectUtil.equal(specType, false)) {
-            ProductSkuCreateOrUpdateReqVO skuVO = skus.get(0);
-            List<ProductSkuBaseVO.Property> properties = new ArrayList<>();
-            ProductSkuBaseVO.Property property = new ProductSkuBaseVO.Property();
-            property.setPropertyId(ProductPropertyDO.ID_DEFAULT);
-            property.setPropertyName(ProductPropertyDO.NAME_DEFAULT);
-            property.setValueId(ProductPropertyValueDO.ID_DEFAULT);
-            property.setValueName(ProductPropertyValueDO.NAME_DEFAULT);
+            ProductSkuSaveReqVO skuVO = skus.get(0);
+            List<ProductSkuSaveReqVO.Property> properties = new ArrayList<>();
+            ProductSkuSaveReqVO.Property property = new ProductSkuSaveReqVO.Property()
+                    .setPropertyId(ProductPropertyDO.ID_DEFAULT).setPropertyName(ProductPropertyDO.NAME_DEFAULT)
+                    .setValueId(ProductPropertyValueDO.ID_DEFAULT).setValueName(ProductPropertyValueDO.NAME_DEFAULT);
             properties.add(property);
             skuVO.setProperties(properties);
             return; // 单规格不需要后续的校验
@@ -106,7 +99,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
                 // 遍历多个 Property 属性
                 .flatMap(p -> p.getProperties().stream())
                 // 将每个 Property 转换成对应的 propertyId,最后形成集合
-                .map(ProductSkuCreateOrUpdateReqVO.Property::getPropertyId)
+                .map(ProductSkuSaveReqVO.Property::getPropertyId)
                 .collect(Collectors.toSet());
         List<ProductPropertyDO> propertyList = productPropertyService.getPropertyList(propertyIds);
         if (propertyList.size() != propertyIds.size()) {
@@ -133,17 +126,18 @@ public class ProductSkuServiceImpl implements ProductSkuService {
         // 4. 最后校验,每个 Sku 之间不是重复的
         // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
         Set<Set<Long>> skuAttrValues = new HashSet<>();
-        for (ProductSkuCreateOrUpdateReqVO sku : skus) {
+        for (ProductSkuSaveReqVO sku : skus) {
             // 添加失败,说明重复
-            if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuCreateOrUpdateReqVO.Property::getValueId))) {
+            if (!skuAttrValues.add(convertSet(sku.getProperties(), ProductSkuSaveReqVO.Property::getValueId))) {
                 throw exception(SPU_SKU_NOT_DUPLICATE);
             }
         }
     }
 
     @Override
-    public void createSkuList(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skuCreateReqList) {
-        productSkuMapper.insertBatch(ProductSkuConvert.INSTANCE.convertList06(skuCreateReqList, spuId));
+    public void createSkuList(Long spuId, List<ProductSkuSaveReqVO> skuCreateReqList) {
+        List<ProductSkuDO> skus = BeanUtils.toBean(skuCreateReqList, ProductSkuDO.class, sku -> sku.setSpuId(spuId));
+        productSkuMapper.insertBatch(skus);
     }
 
     @Override
@@ -164,11 +158,6 @@ public class ProductSkuServiceImpl implements ProductSkuService {
         productSkuMapper.deleteBySpuId(spuId);
     }
 
-    @Override
-    public List<ProductSkuDO> getSkuListByAlarmStock() {
-        return productSkuMapper.selectListByAlarmStock();
-    }
-
     @Override
     public int updateSkuProperty(Long propertyId, String propertyName) {
         // 获取所有的 sku
@@ -220,7 +209,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateSkuList(Long spuId, List<ProductSkuCreateOrUpdateReqVO> skus) {
+    public void updateSkuList(Long spuId, List<ProductSkuSaveReqVO> skus) {
         // 构建属性与 SKU 的映射关系;
         Map<String, Long> existsSkuMap = convertMap(productSkuMapper.selectListBySpuId(spuId),
                 ProductSkuConvert.INSTANCE::buildPropertyKey, ProductSkuDO::getId);
@@ -228,7 +217,7 @@ public class ProductSkuServiceImpl implements ProductSkuService {
         // 拆分三个集合,新插入的、需要更新的、需要删除的
         List<ProductSkuDO> insertSkus = new ArrayList<>();
         List<ProductSkuDO> updateSkus = new ArrayList<>();
-        List<ProductSkuDO> allUpdateSkus = ProductSkuConvert.INSTANCE.convertList06(skus, spuId);
+        List<ProductSkuDO> allUpdateSkus = BeanUtils.toBean(skus, ProductSkuDO.class, sku -> sku.setSpuId(spuId));
         allUpdateSkus.forEach(sku -> {
             String propertiesKey = ProductSkuConvert.INSTANCE.buildPropertyKey(sku);
             // 1、找得到的,进行更新

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

@@ -1,10 +1,11 @@
 package cn.iocoder.yudao.module.product.service.spu;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuSaveReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateStatusReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
-
 import jakarta.validation.Valid;
 import org.springframework.scheduling.annotation.Async;
 
@@ -12,8 +13,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
-
 /**
  * 商品 SPU Service 接口
  *
@@ -27,14 +26,14 @@ public interface ProductSpuService {
      * @param createReqVO 创建信息
      * @return 编号
      */
-    Long createSpu(@Valid ProductSpuCreateReqVO createReqVO);
+    Long createSpu(@Valid ProductSpuSaveReqVO createReqVO);
 
     /**
      * 更新商品 SPU
      *
      * @param updateReqVO 更新信息
      */
-    void updateSpu(@Valid ProductSpuUpdateReqVO updateReqVO);
+    void updateSpu(@Valid ProductSpuSaveReqVO updateReqVO);
 
     /**
      * 删除商品 SPU
@@ -59,16 +58,6 @@ public interface ProductSpuService {
      */
     List<ProductSpuDO> getSpuList(Collection<Long> ids);
 
-    /**
-     * 获得商品 SPU 映射
-     *
-     * @param ids 编号数组
-     * @return 商品 SPU 映射
-     */
-    default Map<Long, ProductSpuDO> getSpuMap(Collection<Long> ids) {
-        return convertMap(getSpuList(ids), ProductSpuDO::getId);
-    }
-
     /**
      * 获得指定状态的商品 SPU 列表
      *
@@ -77,14 +66,6 @@ public interface ProductSpuService {
      */
     List<ProductSpuDO> getSpuListByStatus(Integer status);
 
-    /**
-     * 获得所有商品 SPU 列表
-     *
-     * @param reqVO 导出条件
-     * @return 商品 SPU 列表
-     */
-    List<ProductSpuDO> getSpuList(ProductSpuExportReqVO reqVO);
-
     /**
      * 获得商品 SPU 分页,提供给挂你兰后台使用
      *
@@ -101,15 +82,6 @@ public interface ProductSpuService {
      */
     PageResult<ProductSpuDO> getSpuPage(AppProductSpuPageReqVO pageReqVO);
 
-    /**
-     * 获得商品 SPU 列表,提供给用户 App 使用
-     *
-     * @param recommendType 推荐类型
-     * @param count 数量
-     * @return 商品 SPU 列表
-     */
-    List<ProductSpuDO> getSpuList(String recommendType, Integer count);
-
     /**
      * 更新商品 SPU 库存(增量)
      *

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

@@ -5,11 +5,13 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSkuSaveReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuSaveReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateStatusReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
-import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
@@ -53,15 +55,15 @@ public class ProductSpuServiceImpl implements ProductSpuService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Long createSpu(ProductSpuCreateReqVO createReqVO) {
+    public Long createSpu(ProductSpuSaveReqVO createReqVO) {
         // 校验分类、品牌
         validateCategory(createReqVO.getCategoryId());
         brandService.validateProductBrand(createReqVO.getBrandId());
         // 校验 SKU
-        List<ProductSkuCreateOrUpdateReqVO> skuSaveReqList = createReqVO.getSkus();
+        List<ProductSkuSaveReqVO> skuSaveReqList = createReqVO.getSkus();
         productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
 
-        ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
+        ProductSpuDO spu = BeanUtils.toBean(createReqVO, ProductSpuDO.class);
         // 初始化 SPU 中 SKU 相关属性
         initSpuFromSkus(spu, skuSaveReqList);
         // 插入 SPU
@@ -74,18 +76,18 @@ public class ProductSpuServiceImpl implements ProductSpuService {
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void updateSpu(ProductSpuUpdateReqVO updateReqVO) {
+    public void updateSpu(ProductSpuSaveReqVO updateReqVO) {
         // 校验 SPU 是否存在
         validateSpuExists(updateReqVO.getId());
         // 校验分类、品牌
         validateCategory(updateReqVO.getCategoryId());
         brandService.validateProductBrand(updateReqVO.getBrandId());
         // 校验SKU
-        List<ProductSkuCreateOrUpdateReqVO> skuSaveReqList = updateReqVO.getSkus();
+        List<ProductSkuSaveReqVO> skuSaveReqList = updateReqVO.getSkus();
         productSkuService.validateSkuList(skuSaveReqList, updateReqVO.getSpecType());
 
         // 更新 SPU
-        ProductSpuDO updateObj = ProductSpuConvert.INSTANCE.convert(updateReqVO);
+        ProductSpuDO updateObj = BeanUtils.toBean(updateReqVO, ProductSpuDO.class);
         initSpuFromSkus(updateObj, skuSaveReqList);
         productSpuMapper.updateById(updateObj);
         // 批量更新 SKU
@@ -99,26 +101,20 @@ public class ProductSpuServiceImpl implements ProductSpuService {
      * @param spu  商品 SPU
      * @param skus 商品 SKU 数组
      */
-    private void initSpuFromSkus(ProductSpuDO spu, List<ProductSkuCreateOrUpdateReqVO> skus) {
+    private void initSpuFromSkus(ProductSpuDO spu, List<ProductSkuSaveReqVO> skus) {
         // sku 单价最低的商品的价格
-        spu.setPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getPrice));
+        spu.setPrice(getMinValue(skus, ProductSkuSaveReqVO::getPrice));
         // sku 单价最低的商品的市场价格
-        spu.setMarketPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getMarketPrice));
+        spu.setMarketPrice(getMinValue(skus, ProductSkuSaveReqVO::getMarketPrice));
         // sku 单价最低的商品的成本价格
-        spu.setCostPrice(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getCostPrice));
-        // sku 单价最低的商品的条形码 TODO 芋艿:条形码字段,是不是可以删除
-        spu.setBarCode("");
-//        spu.setBarCode(getMinValue(skus, ProductSkuCreateOrUpdateReqVO::getBarCode));
+        spu.setCostPrice(getMinValue(skus, ProductSkuSaveReqVO::getCostPrice));
         // skus 库存总数
-        spu.setStock(getSumValue(skus, ProductSkuCreateOrUpdateReqVO::getStock, Integer::sum));
+        spu.setStock(getSumValue(skus, ProductSkuSaveReqVO::getStock, Integer::sum));
         // 若是 spu 已有状态则不处理
         if (spu.getStatus() == null) {
-            // 默认状态为上架
-            spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
-            // 默认商品销量
-            spu.setSalesCount(0);
-            // 默认商品浏览量
-            spu.setBrowseCount(0);
+            spu.setStatus(ProductSpuStatusEnum.ENABLE.getStatus()); // 默认状态为上架
+            spu.setSalesCount(0); // 默认商品销量
+            spu.setBrowseCount(0); // 默认商品浏览量
         }
     }
 
@@ -203,11 +199,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         return productSpuMapper.selectList(ProductSpuDO::getStatus, status);
     }
 
-    @Override
-    public List<ProductSpuDO> getSpuList(ProductSpuExportReqVO reqVO) {
-        return productSpuMapper.selectList(reqVO);
-    }
-
     @Override
     public PageResult<ProductSpuDO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
         return productSpuMapper.selectPage(pageReqVO);
@@ -233,11 +224,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         return productSpuMapper.selectPage(pageReqVO, categoryIds);
     }
 
-    @Override
-    public List<ProductSpuDO> getSpuList(String recommendType, Integer count) {
-        return productSpuMapper.selectListByRecommendType(recommendType, count);
-    }
-
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateSpuStock(Map<Long, Integer> stockIncrCounts) {

+ 6 - 6
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceTest.java

@@ -4,7 +4,7 @@ import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
 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.controller.admin.spu.vo.ProductSkuSaveReqVO;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper;
 import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
@@ -74,13 +74,13 @@ public class ProductSkuServiceTest extends BaseDbUnitTest {
         // 准备参数
         Long spuId = 1L;
         String spuName = "测试商品";
-        List<ProductSkuCreateOrUpdateReqVO> skus = Arrays.asList(
-                randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试更新
-                    o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(
+        List<ProductSkuSaveReqVO> skus = Arrays.asList(
+                randomPojo(ProductSkuSaveReqVO.class, o -> { // 测试更新
+                    o.setProperties(singletonList(new ProductSkuSaveReqVO.Property(
                             10L, "颜色", 20L, "红色")));
                 }),
-                randomPojo(ProductSkuCreateOrUpdateReqVO.class, o -> { // 测试新增
-                    o.setProperties(singletonList(new ProductSkuCreateOrUpdateReqVO.Property(
+                randomPojo(ProductSkuSaveReqVO.class, o -> { // 测试新增
+                    o.setProperties(singletonList(new ProductSkuSaveReqVO.Property(
                             10L, "颜色", 20L, "红色")));
                 })
         );

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

@@ -6,12 +6,9 @@ import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSkuSaveReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;
-import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
-import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
+import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuSaveReqVO;
 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.enums.spu.ProductSpuStatusEnum;
@@ -21,13 +18,13 @@ import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
 import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
 import cn.iocoder.yudao.module.product.service.sku.ProductSkuServiceImpl;
 import com.google.common.collect.Lists;
+import jakarta.annotation.Resource;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.Import;
 
-import jakarta.annotation.Resource;
 import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.Date;
@@ -87,20 +84,19 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
     @Test
     public void testCreateSpu_success() {
         // 准备参数
-        ProductSkuCreateOrUpdateReqVO skuCreateOrUpdateReqVO = randomPojo(ProductSkuCreateOrUpdateReqVO.class,o->{
+        ProductSkuSaveReqVO skuCreateOrUpdateReqVO = randomPojo(ProductSkuSaveReqVO.class, o->{
             // 限制范围为正整数
             o.setCostPrice(generaInt());
             o.setPrice(generaInt());
             o.setMarketPrice(generaInt());
             o.setStock(generaInt());
-            o.setWarnStock(10);
             o.setFirstBrokeragePrice(generaInt());
             o.setSecondBrokeragePrice(generaInt());
             // 限制分数为两位数
             o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
             o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
         });
-        ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class,o->{
+        ProductSpuSaveReqVO createReqVO = randomPojo(ProductSpuSaveReqVO.class,o->{
             o.setCategoryId(generateId());
             o.setBrandId(generateId());
             o.setSort(RandomUtil.randomInt(1,100)); // 限制排序范围
@@ -134,13 +130,12 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
         });
         productSpuMapper.insert(createReqVO);
         // 准备参数
-        ProductSkuCreateOrUpdateReqVO skuCreateOrUpdateReqVO = randomPojo(ProductSkuCreateOrUpdateReqVO.class,o->{
+        ProductSkuSaveReqVO skuCreateOrUpdateReqVO = randomPojo(ProductSkuSaveReqVO.class, o->{
             // 限制范围为正整数
             o.setCostPrice(generaInt());
             o.setPrice(generaInt());
             o.setMarketPrice(generaInt());
             o.setStock(generaInt());
-            o.setWarnStock(10);
             o.setFirstBrokeragePrice(generaInt());
             o.setSecondBrokeragePrice(generaInt());
             // 限制分数为两位数
@@ -148,7 +143,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
             o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP));
         });
         // 准备参数
-        ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> {
+        ProductSpuSaveReqVO reqVO = randomPojo(ProductSpuSaveReqVO.class, o -> {
             o.setId(createReqVO.getId()); // 设置更新的 ID
             o.setCategoryId(generateId());
             o.setBrandId(generateId());
@@ -158,7 +153,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
             o.setGiveIntegral(generaInt()); // 限制范围为正整数
             o.setSalesCount(generaInt()); // 限制范围为正整数
             o.setBrowseCount(generaInt()); // 限制范围为正整数
-            o.setStatus(0);
             o.setSkus(newArrayList(skuCreateOrUpdateReqVO,skuCreateOrUpdateReqVO,skuCreateOrUpdateReqVO));
         });
         when(categoryService.getCategoryLevel(eq(reqVO.getCategoryId()))).thenReturn(2);
@@ -171,7 +165,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
 
     @Test
     public void testValidateSpuExists_exception() {
-        ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class);
+        ProductSpuSaveReqVO reqVO = randomPojo(ProductSpuSaveReqVO.class);
         // 调用
         Assertions.assertThrows(ServiceException.class, () -> productSpuService.updateSpu(reqVO));
     }
@@ -394,8 +388,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
 
         PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
 
-        PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO));
-        assertEquals(result.getTotal(), spuPage.getTotal());
+        assertEquals(1, spuPage.getTotal());
     }
 
     /**