diff --git a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java index 85725a18e..b96dde169 100644 --- a/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java +++ b/yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/DictTypeConstants.java @@ -7,7 +7,6 @@ package cn.iocoder.yudao.module.product.enums; */ public interface DictTypeConstants { - String PRODUCT_UNIT = "product_unit"; // 商品单位 String PRODUCT_SPU_STATUS = "product_spu_status"; // 商品 SPU 状态 } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java index 08667939a..8a15a21f4 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.api.sku; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +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; @@ -31,19 +32,19 @@ public class ProductSkuApiImpl implements ProductSkuApi { @Override public CommonResult getSku(Long id) { ProductSkuDO sku = productSkuService.getSku(id); - return success(ProductSkuConvert.INSTANCE.convert02(sku)); + return success(BeanUtils.toBean(sku, ProductSkuRespDTO.class)); } @Override public CommonResult> getSkuList(Collection ids) { List skus = productSkuService.getSkuList(ids); - return success(ProductSkuConvert.INSTANCE.convertList04(skus)); + return success(BeanUtils.toBean(skus, ProductSkuRespDTO.class)); } @Override public CommonResult> getSkuListBySpuId(Collection spuIds) { List skus = productSkuService.getSkuListBySpuId(spuIds); - return success(ProductSkuConvert.INSTANCE.convertList04(skus)); + return success(BeanUtils.toBean(skus, ProductSkuRespDTO.class)); } @Override diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java index 0fffea0b2..1ba42b330 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.product.api.spu; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +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 org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; @@ -28,17 +30,20 @@ public class ProductSpuApiImpl implements ProductSpuApi { @Override public CommonResult> getSpuList(Collection ids) { - return success(ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids))); + List spus = spuService.getSpuList(ids); + return success(BeanUtils.toBean(spus, ProductSpuRespDTO.class)); } @Override public CommonResult> validateSpuList(Collection ids) { - return success(ProductSpuConvert.INSTANCE.convertList2(spuService.validateSpuList(ids))); + List spus = spuService.validateSpuList(ids); + return success(BeanUtils.toBean(spus, ProductSpuRespDTO.class)); } @Override public CommonResult getSpu(Long id) { - return success(ProductSpuConvert.INSTANCE.convert02(spuService.getSpu(id))); + ProductSpuDO spu = spuService.getSpu(id); + return success(BeanUtils.toBean(spu, ProductSpuRespDTO.class)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java index aff47c7fc..c9d3cb9c6 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java @@ -10,12 +10,12 @@ import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; 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.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.validation.Valid; import java.util.Comparator; import java.util.List; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java index 152de7211..4226ffe7e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotNull; +import lombok.Data; /** * 商品品牌 Base VO,提供给添加、修改、详细的子 VO 使用 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java index b9585b62b..5941156c9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java @@ -1,12 +1,11 @@ package cn.iocoder.yudao.module.product.controller.admin.brand.vo; 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; - @Schema(description = "管理后台 - 商品品牌更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java index 16e6a4e6b..f3f598065 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java @@ -1,22 +1,21 @@ package cn.iocoder.yudao.module.product.controller.admin.category; import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +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.category.vo.ProductCategoryRespVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategorySaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; 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.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.validation.Valid; import java.util.Comparator; import java.util.List; @@ -34,14 +33,14 @@ public class ProductCategoryController { @PostMapping("/create") @Operation(summary = "创建商品分类") @PreAuthorize("@ss.hasPermission('product:category:create')") - public CommonResult createCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) { + public CommonResult createCategory(@Valid @RequestBody ProductCategorySaveReqVO createReqVO) { return success(categoryService.createCategory(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新商品分类") @PreAuthorize("@ss.hasPermission('product:category:update')") - public CommonResult updateCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) { + public CommonResult updateCategory(@Valid @RequestBody ProductCategorySaveReqVO updateReqVO) { categoryService.updateCategory(updateReqVO); return success(true); } @@ -61,16 +60,16 @@ public class ProductCategoryController { @PreAuthorize("@ss.hasPermission('product:category:query')") public CommonResult getCategory(@RequestParam("id") Long id) { ProductCategoryDO category = categoryService.getCategory(id); - return success(ProductCategoryConvert.INSTANCE.convert(category)); + return success(BeanUtils.toBean(category, ProductCategoryRespVO.class)); } @GetMapping("/list") @Operation(summary = "获得商品分类列表") @PreAuthorize("@ss.hasPermission('product:category:query')") - public CommonResult> getCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) { - List list = categoryService.getEnableCategoryList(treeListReqVO); + public CommonResult> getCategoryList(@Valid ProductCategoryListReqVO listReqVO) { + List list = categoryService.getCategoryList(listReqVO); list.sort(Comparator.comparing(ProductCategoryDO::getSort)); - return success(ProductCategoryConvert.INSTANCE.convertList(list)); + return success(BeanUtils.toBean(list, ProductCategoryRespVO.class)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java deleted file mode 100644 index 4099b15a8..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 商品分类创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO { - - @Schema(description = "分类描述", example = "描述") - private String description; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java index 16f5df857..9e5364c90 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.util.Collection; + @Schema(description = "管理后台 - 商品分类列表查询 Request VO") @Data public class ProductCategoryListReqVO { @@ -16,4 +18,7 @@ public class ProductCategoryListReqVO { @Schema(description = "父分类编号", example = "1") private Long parentId; + @Schema(description = "父分类编号数组", example = "1,2,3") + private Collection parentIds; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java index 8f46ff60f..c8ef92e17 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java @@ -2,20 +2,34 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; import java.time.LocalDateTime; @Schema(description = "管理后台 - 商品分类 Response VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCategoryRespVO extends ProductCategoryBaseVO { +public class ProductCategoryRespVO { @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") private Long id; + @Schema(description = "父分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long parentId; + + @Schema(description = "分类名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "办公文具") + private String name; + + @Schema(description = "移动端分类图", requiredMode = Schema.RequiredMode.REQUIRED) + private String picUrl; + + @Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer sort; + + @Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + private Integer status; + + @Schema(description = "分类描述", example = "描述") + private String description; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategorySaveReqVO.java similarity index 79% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategorySaveReqVO.java index 4174f3c98..5f03df1fa 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategorySaveReqVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.product.controller.admin.category.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import lombok.Data; -/** -* 商品分类 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ +@Schema(description = "管理后台 - 商品分类新增/更新 Request VO") @Data -public class ProductCategoryBaseVO { +public class ProductCategorySaveReqVO { + + @Schema(description = "分类编号", example = "2") + private Long id; @Schema(description = "父分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "父分类编号不能为空") @@ -25,9 +24,6 @@ public class ProductCategoryBaseVO { @NotBlank(message = "移动端分类图不能为空") private String picUrl; - @Schema(description = "PC 端分类图") - private String bigPicUrl; - @Schema(description = "分类排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") private Integer sort; @@ -35,4 +31,7 @@ public class ProductCategoryBaseVO { @NotNull(message = "开启状态不能为空") private Integer status; + @Schema(description = "分类描述", example = "描述") + private String description; + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java deleted file mode 100644 index b94228786..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.category.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import jakarta.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 商品分类更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO { - - @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - @NotNull(message = "分类编号不能为空") - private Long id; - - @Schema(description = "分类描述", example = "描述") - private String description; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java index c28c28394..3cac6d068 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/ProductCommentController.java @@ -2,19 +2,18 @@ package cn.iocoder.yudao.module.product.controller.admin.comment; 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.product.controller.admin.comment.vo.*; -import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +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.validation.Valid; - import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -32,7 +31,7 @@ public class ProductCommentController { @PreAuthorize("@ss.hasPermission('product:comment:query')") public CommonResult> getCommentPage(@Valid ProductCommentPageReqVO pageVO) { PageResult pageResult = productCommentService.getCommentPage(pageVO); - return success(ProductCommentConvert.INSTANCE.convertPage(pageResult)); + return success(BeanUtils.toBean(pageResult, ProductCommentRespVO.class)); } @PutMapping("/update-visible") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java deleted file mode 100644 index a8394afab..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentBaseVO.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.comment.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.List; - -@Data -public class ProductCommentBaseVO { - - @Schema(description = "评价人", requiredMode = Schema.RequiredMode.REQUIRED, example = "16868") - private Long userId; - - @Schema(description = "评价订单项", requiredMode = Schema.RequiredMode.REQUIRED, example = "19292") - private Long orderItemId; - - @Schema(description = "评价人名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小姑凉") - @NotNull(message = "评价人名称不能为空") - private String userNickname; - - @Schema(description = "评价人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png") - @NotNull(message = "评价人头像不能为空") - private String userAvatar; - - @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") - @NotNull(message = "描述星级不能为空") - private Integer descriptionScores; - - @Schema(description = "服务星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") - @NotNull(message = "服务星级分不能为空") - private Integer benefitScores; - - @Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "穿起来非常丝滑凉快") - @NotNull(message = "评论内容不能为空") - private String content; - - @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]") - @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") - private List picUrls; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java index f976b756d..b411db073 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentCreateReqVO.java @@ -1,14 +1,49 @@ package cn.iocoder.yudao.module.product.controller.admin.comment.vo; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; + +import java.util.List; @Schema(description = "管理后台 - 商品评价创建 Request VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCommentCreateReqVO extends ProductCommentBaseVO { +public class ProductCommentCreateReqVO { + + @Schema(description = "评价人", requiredMode = Schema.RequiredMode.REQUIRED, example = "16868") + private Long userId; + + @Schema(description = "评价订单项", requiredMode = Schema.RequiredMode.REQUIRED, example = "19292") + private Long orderItemId; + + @Schema(description = "评价人名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小姑凉") + @NotNull(message = "评价人名称不能为空") + private String userNickname; + + @Schema(description = "评价人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png") + @NotNull(message = "评价人头像不能为空") + private String userAvatar; + + @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + @NotNull(message = "描述星级不能为空") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + @NotNull(message = "服务星级分不能为空") + private Integer benefitScores; + + @Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "穿起来非常丝滑凉快") + @NotNull(message = "评论内容不能为空") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, + example = "[https://www.iocoder.cn/xx.png]") + @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") + private List picUrls; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java index 9d2aa42c5..239273787 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentReplyReqVO.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.product.controller.admin.comment.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.ToString; @Schema(description = "管理后台 - 商品评价的商家回复 Request VO") @Data diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java index 05ed9b859..605019a19 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentRespVO.java @@ -1,33 +1,69 @@ 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 lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import jakarta.validation.constraints.NotNull; import java.time.LocalDateTime; import java.util.List; @Schema(description = "管理后台 - 商品评价 Response VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductCommentRespVO extends ProductCommentBaseVO { +public class ProductCommentRespVO { @Schema(description = "订单项编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24965") private Long id; + @Schema(description = "评价人", requiredMode = Schema.RequiredMode.REQUIRED, example = "16868") + private Long userId; + + @Schema(description = "评价人名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小姑凉") + private String userNickname; + + @Schema(description = "评价人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png") + private String userAvatar; @Schema(description = "是否匿名", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") private Boolean anonymous; @Schema(description = "交易订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "24428") private Long orderId; + @Schema(description = "评价订单项", requiredMode = Schema.RequiredMode.REQUIRED, example = "19292") + private Long orderItemId; + + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖") + private Long spuId; + + @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Long skuId; + + @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") + private String spuName; + + @Schema(description = "商品 SKU 图片地址", example = "https://www.iocoder.cn/yudao.jpg") + private String skuPicUrl; + + @Schema(description = "商品 SKU 规格值数组") + private List skuProperties; + @Schema(description = "是否可见", requiredMode = Schema.RequiredMode.REQUIRED) private Boolean visible; + @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + private Integer scores; + + @Schema(description = "描述星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + private Integer descriptionScores; + + @Schema(description = "服务星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") + private Integer benefitScores; + + @Schema(description = "评论内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "穿起来非常丝滑凉快") + private String content; + + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]") + private List picUrls; + @Schema(description = "商家是否回复", requiredMode = Schema.RequiredMode.REQUIRED) private Boolean replyStatus; @@ -43,21 +79,4 @@ public class ProductCommentRespVO extends ProductCommentBaseVO { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; - @Schema(description = "评分星级 1-5 分", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") - private Integer scores; - - @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉丝滑透气小短袖") - @NotNull(message = "商品 SPU 编号不能为空") - private Long spuId; - - @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六") - @NotNull(message = "商品 SPU 名称不能为空") - private String spuName; - - @Schema(description = "商品 SKU 图片地址", example = "https://www.iocoder.cn/yudao.jpg") - private String skuPicUrl; - - @Schema(description = "商品 SKU 规格值数组") - private List skuProperties; - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java index d970c3f95..f42803aa7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/comment/vo/ProductCommentUpdateVisibleReqVO.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.product.controller.admin.comment.vo; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.ToString; -import jakarta.validation.constraints.NotNull; - @Schema(description = "管理后台 - 商品评价可见修改 Request VO") @Data @ToString(callSuper = true) diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/ProductFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/ProductFavoriteController.java new file mode 100644 index 000000000..1e9267579 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/ProductFavoriteController.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.product.controller.admin.favorite; + +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.module.product.controller.admin.favorite.vo.ProductFavoritePageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.favorite.vo.ProductFavoriteRespVO; +import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert; +import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +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.RestController; + +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - 商品收藏") +@RestController +@RequestMapping("/product/favorite") +@Validated +public class ProductFavoriteController { + + @Resource + private ProductFavoriteService productFavoriteService; + + @Resource + private ProductSpuService productSpuService; + + @GetMapping("/page") + @Operation(summary = "获得商品收藏分页") + @PreAuthorize("@ss.hasPermission('product:favorite:query')") + public CommonResult> getFavoritePage(@Valid ProductFavoritePageReqVO pageVO) { + PageResult pageResult = productFavoriteService.getFavoritePage(pageVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty()); + } + // 拼接数据 + List spuList = productSpuService.getSpuList(convertSet(pageResult.getList(), ProductFavoriteDO::getSpuId)); + return success(ProductFavoriteConvert.INSTANCE.convertPage(pageResult, spuList)); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteBaseVO.java new file mode 100644 index 000000000..38baa68e6 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteBaseVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.product.controller.admin.favorite.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +/** + * 商品收藏 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +@Data +public class ProductFavoriteBaseVO { + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "5036") + @NotNull(message = "用户编号不能为空") + private Long userId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoritePageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoritePageReqVO.java new file mode 100644 index 000000000..3d78883ec --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoritePageReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.product.controller.admin.favorite.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品收藏分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductFavoritePageReqVO extends PageParam { + + @Schema(description = "用户编号", example = "5036") + private Long userId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteReqVO.java new file mode 100644 index 000000000..cf2e29149 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteReqVO.java @@ -0,0 +1,16 @@ +package cn.iocoder.yudao.module.product.controller.admin.favorite.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品收藏的单个 Response VO") +@Data +@ToString(callSuper = true) +public class ProductFavoriteReqVO extends ProductFavoriteBaseVO { + + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32734") + @NotNull(message = "商品 SPU 编号不能为空") + private Long spuId; +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteRespVO.java new file mode 100644 index 000000000..3c09aa8fc --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/favorite/vo/ProductFavoriteRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.product.controller.admin.favorite.vo; + +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.ToString; + +@Schema(description = "管理后台 - 商品收藏 Response VO") +@Data +@ToString(callSuper = true) +public class ProductFavoriteRespVO extends ProductSpuRespVO { + + @Schema(description = "userId", requiredMode = Schema.RequiredMode.REQUIRED, example = "111") + private Long userId; + + @Schema(description = "spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "111") + private Long spuId; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/ProductBrowseHistoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/ProductBrowseHistoryController.java new file mode 100644 index 000000000..b87e4ee44 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/ProductBrowseHistoryController.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.product.controller.admin.history; + +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.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO; +import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +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.RestController; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 商品浏览记录") +@RestController +@RequestMapping("/product/browse-history") +@Validated +public class ProductBrowseHistoryController { + + @Resource + private ProductBrowseHistoryService browseHistoryService; + + @GetMapping("/page") + @Operation(summary = "获得商品浏览记录分页") + @PreAuthorize("@ss.hasPermission('product:browse-history:query')") + public CommonResult> getBrowseHistoryPage(@Valid ProductBrowseHistoryPageReqVO pageReqVO) { + PageResult pageResult = browseHistoryService.getBrowseHistoryPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, ProductBrowseHistoryRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/vo/ProductBrowseHistoryPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/vo/ProductBrowseHistoryPageReqVO.java new file mode 100644 index 000000000..aa3010212 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/vo/ProductBrowseHistoryPageReqVO.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.product.controller.admin.history.vo; + +import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +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 = "管理后台 - 商品浏览记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class ProductBrowseHistoryPageReqVO extends SortablePageParam { + + @Schema(description = "用户编号", example = "4314") + private Long userId; + + @Schema(description = "用户是否删除", example = "false") + private Boolean userDeleted; + + @Schema(description = "商品 SPU 编号", example = "42") + private Long spuId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/vo/ProductBrowseHistoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/vo/ProductBrowseHistoryRespVO.java new file mode 100644 index 000000000..0e2e0cbed --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/history/vo/ProductBrowseHistoryRespVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.product.controller.admin.history.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 商品浏览记录 Response VO") +@Data +@ExcelIgnoreUnannotated +public class ProductBrowseHistoryRespVO { + + @Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26055") + @ExcelProperty("记录编号") + private Long id; + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4314") + @ExcelProperty("用户编号") + private Long userId; + + @Schema(description = "用户是否删除", example = "false") + private Boolean userDeleted; + + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "42") + @ExcelProperty("商品 SPU 编号") + private Long spuId; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java index 1ebc2d890..fed5d8d69 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java @@ -1,28 +1,23 @@ package cn.iocoder.yudao.module.product.controller.admin.property; -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.module.product.controller.admin.property.vo.property.*; -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertySaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.service.property.ProductPropertyService; -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; 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.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.validation.Valid; -import java.util.Collections; -import java.util.List; - import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @Tag(name = "管理后台 - 商品属性项") @RestController @@ -32,20 +27,18 @@ public class ProductPropertyController { @Resource private ProductPropertyService productPropertyService; - @Resource - private ProductPropertyValueService productPropertyValueService; @PostMapping("/create") @Operation(summary = "创建属性项") @PreAuthorize("@ss.hasPermission('product:property:create')") - public CommonResult createProperty(@Valid @RequestBody ProductPropertyCreateReqVO createReqVO) { + public CommonResult createProperty(@Valid @RequestBody ProductPropertySaveReqVO createReqVO) { return success(productPropertyService.createProperty(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新属性项") @PreAuthorize("@ss.hasPermission('product:property:update')") - public CommonResult updateProperty(@Valid @RequestBody ProductPropertyUpdateReqVO updateReqVO) { + public CommonResult updateProperty(@Valid @RequestBody ProductPropertySaveReqVO updateReqVO) { productPropertyService.updateProperty(updateReqVO); return success(true); } @@ -64,37 +57,16 @@ public class ProductPropertyController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult getProperty(@RequestParam("id") Long id) { - return success(ProductPropertyConvert.INSTANCE.convert(productPropertyService.getProperty(id))); - } - - @GetMapping("/list") - @Operation(summary = "获得属性项列表") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) { - return success(ProductPropertyConvert.INSTANCE.convertList(productPropertyService.getPropertyList(listReqVO))); + ProductPropertyDO property = productPropertyService.getProperty(id); + return success(BeanUtils.toBean(property, ProductPropertyRespVO.class)); } @GetMapping("/page") @Operation(summary = "获得属性项分页") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) { - return success(ProductPropertyConvert.INSTANCE.convertPage(productPropertyService.getPropertyPage(pageVO))); - } - - @PostMapping("/get-value-list") - @Operation(summary = "获得属性项列表") - @PreAuthorize("@ss.hasPermission('product:property:query')") - public CommonResult> getPropertyAndValueList( - @Valid @RequestBody ProductPropertyListReqVO listReqVO) { - // 查询属性项 - List keys = productPropertyService.getPropertyList(listReqVO); - if (CollUtil.isEmpty(keys)) { - return success(Collections.emptyList()); - } - // 查询属性值 - List values = productPropertyValueService.getPropertyValueListByPropertyId( - convertSet(keys, ProductPropertyDO::getId)); - return success(ProductPropertyConvert.INSTANCE.convertList(keys, values)); + PageResult pageResult = productPropertyService.getPropertyPage(pageVO); + return success(BeanUtils.toBean(pageResult, ProductPropertyRespVO.class)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java index 8a0595aa3..4a613fb1f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java @@ -2,22 +2,21 @@ package cn.iocoder.yudao.module.product.controller.admin.property; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyValueConvert; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueSaveReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService; 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.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.validation.Valid; - import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @Tag(name = "管理后台 - 商品属性值") @@ -32,14 +31,14 @@ public class ProductPropertyValueController { @PostMapping("/create") @Operation(summary = "创建属性值") @PreAuthorize("@ss.hasPermission('product:property:create')") - public CommonResult createPropertyValue(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) { + public CommonResult createPropertyValue(@Valid @RequestBody ProductPropertyValueSaveReqVO createReqVO) { return success(productPropertyValueService.createPropertyValue(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新属性值") @PreAuthorize("@ss.hasPermission('product:property:update')") - public CommonResult updatePropertyValue(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) { + public CommonResult updatePropertyValue(@Valid @RequestBody ProductPropertyValueSaveReqVO updateReqVO) { productPropertyValueService.updatePropertyValue(updateReqVO); return success(true); } @@ -58,13 +57,16 @@ public class ProductPropertyValueController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult getPropertyValue(@RequestParam("id") Long id) { - return success(ProductPropertyValueConvert.INSTANCE.convert(productPropertyValueService.getPropertyValue(id))); + ProductPropertyValueDO value = productPropertyValueService.getPropertyValue(id); + return success(BeanUtils.toBean(value, ProductPropertyValueRespVO.class)); } @GetMapping("/page") @Operation(summary = "获得属性值分页") @PreAuthorize("@ss.hasPermission('product:property:query')") public CommonResult> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) { - return success(ProductPropertyValueConvert.INSTANCE.convertPage(productPropertyValueService.getPropertyValuePage(pageVO))); + PageResult pageResult = productPropertyValueService.getPropertyValuePage(pageVO); + return success(BeanUtils.toBean(pageResult, ProductPropertyValueRespVO.class)); } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java deleted file mode 100644 index 6ef051451..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.util.List; - -@Schema(description = "管理后台 - 商品属性项 + 属性值 Response VO") -@Data -public class ProductPropertyAndValueRespVO { - - @Schema(description = "属性项的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long id; - - @Schema(description = "属性项的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "颜色") - private String name; - - /** - * 属性值的集合 - */ - private List values; - - @Schema(description = "管理后台 - 属性值的简单 Response VO") - @Data - public static class Value { - - @Schema(description = "属性值的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") - private Long id; - - @Schema(description = "属性值的名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "红色") - private String name; - - } - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java deleted file mode 100644 index b854dd73c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 属性项创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO { - - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java deleted file mode 100644 index 3ff46484f..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - -import java.util.List; - -@Schema(description = "管理后台 - 属性项 List Request VO") -@Data -@ToString(callSuper = true) -public class ProductPropertyListReqVO { - - @Schema(description = "属性名称", example = "颜色") - private String name; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java index 5f541230a..82a3a0cac 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java @@ -2,20 +2,22 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; import java.time.LocalDateTime; @Schema(description = "管理后台 - 属性项 Response VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyRespVO extends ProductPropertyBaseVO { +public class ProductPropertyRespVO { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") private Long id; + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "颜色") + private String name; + + @Schema(description = "备注", example = "颜色") + private String remark; + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertySaveReqVO.java similarity index 68% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertySaveReqVO.java index cbe2b1ec9..69ebf9f7b 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertySaveReqVO.java @@ -1,16 +1,15 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; import lombok.Data; -import jakarta.validation.constraints.NotBlank; - -/** - * 商品属性项 Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - */ +@Schema(description = "管理后台 - 属性项新增/更新 Request VO") @Data -public class ProductPropertyBaseVO { +public class ProductPropertySaveReqVO { + + @Schema(description = "主键", example = "1") + private Long id; @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "颜色") @NotBlank(message = "名称不能为空") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java deleted file mode 100644 index b32a8511d..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.property; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import jakarta.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 属性项更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO { - - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "主键不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java deleted file mode 100644 index d3fe4d0f1..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Schema(description = "管理后台 - 商品属性值创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyValueCreateReqVO extends ProductPropertyValueBaseVO { - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java deleted file mode 100644 index 4d22f0dbf..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java index 6ef17c32e..1eedf9f4a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java @@ -1,21 +1,30 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; import java.time.LocalDateTime; @Schema(description = "管理后台 - 商品属性值 Response VO") @Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO { +public class ProductPropertyValueRespVO { - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + @Schema(description = "主键", example = "1024") private Long id; + @Schema(description = "属性项的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "属性项的编号不能为空") + private Long propertyId; + + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "红色") + @NotEmpty(message = "名称名字不能为空") + private String name; + + @Schema(description = "备注", example = "颜色") + private String remark; + @Schema(description = "创建时间") private LocalDateTime createTime; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueSaveReqVO.java similarity index 76% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueSaveReqVO.java index c0c2e2593..1a57c6a31 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueSaveReqVO.java @@ -1,17 +1,16 @@ package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.Data; -/** -* 属性值 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ +@Schema(description = "管理后台 - 商品属性值新增/更新 Request VO") @Data -public class ProductPropertyValueBaseVO { +public class ProductPropertyValueSaveReqVO { + + @Schema(description = "主键", example = "1024") + private Long id; @Schema(description = "属性项的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotNull(message = "属性项的编号不能为空") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java deleted file mode 100644 index 4745e7019..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.property.vo.value; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import jakarta.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 商品属性值更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO { - - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @NotNull(message = "主键不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java deleted file mode 100755 index 9acbacd66..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java +++ /dev/null @@ -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 { - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java deleted file mode 100755 index e750013d5..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java +++ /dev/null @@ -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 { - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java deleted file mode 100755 index f068fd135..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.admin.sku.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -@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; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index a74dcbcae..ac1a900a1 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/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.*; @@ -11,28 +12,25 @@ 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.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; -//import cn.iocoder.yudao.module.promotion.api.coupon.CouponTemplateApi; -//import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO; 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 @@ -44,21 +42,18 @@ public class ProductSpuController { private ProductSpuService productSpuService; @Resource private ProductSkuService productSkuService; -// -// @Resource -// private CouponTemplateApi couponTemplateApi; @PostMapping("/create") @Operation(summary = "创建商品 SPU") @PreAuthorize("@ss.hasPermission('product:spu:create')") - public CommonResult createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) { + public CommonResult createProductSpu(@Valid @RequestBody ProductSpuSaveReqVO createReqVO) { return success(productSpuService.createSpu(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新商品 SPU") @PreAuthorize("@ss.hasPermission('product:spu:update')") - public CommonResult updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) { + public CommonResult updateSpu(@Valid @RequestBody ProductSpuSaveReqVO updateReqVO) { productSpuService.updateSpu(updateReqVO); return success(true); } @@ -84,19 +79,15 @@ public class ProductSpuController { @Operation(summary = "获得商品 SPU 明细") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('product:spu:query')") - public CommonResult getSpuDetail(@RequestParam("id") Long id) { + public CommonResult getSpuDetail(@RequestParam("id") Long id) { // 获得商品 SPU ProductSpuDO spu = productSpuService.getSpu(id); if (spu == null) { - throw exception(SPU_NOT_EXISTS); + return success(null); } // 查询商品 SKU List skus = productSkuService.getSkuListBySpuId(spu.getId()); - // 查询优惠卷 - // TODO @puhui999:优惠劵的信息,要不交给前端读取?主要是为了避免商品依赖 promotion 模块哈; -// List couponTemplateList = couponTemplateApi.getCouponTemplateListByIds( -// spu.getGiveCouponTemplateIds()); - return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus)); + return success(ProductSpuConvert.INSTANCE.convert(spu, skus)); } @GetMapping("/list-all-simple") @@ -106,14 +97,14 @@ public class ProductSpuController { List 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> getSpuList(@RequestParam("spuIds") Collection spuIds) { + public CommonResult> getSpuList(@RequestParam("spuIds") Collection spuIds) { return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespListVO( productSpuService.getSpuList(spuIds), productSkuService.getSkuListBySpuId(spuIds))); } @@ -122,7 +113,8 @@ public class ProductSpuController { @Operation(summary = "获得商品 SPU 分页") @PreAuthorize("@ss.hasPermission('product:spu:query')") public CommonResult> getSpuPage(@Valid ProductSpuPageReqVO pageVO) { - return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO))); + PageResult pageResult = productSpuService.getSpuPage(pageVO); + return success(BeanUtils.toBean(pageResult, ProductSpuRespVO.class)); } @GetMapping("/get-count") @@ -136,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 spuList = productSpuService.getSpuList(reqVO); + reqVO.setPageSize(PAGE_SIZE_NONE); + List list = productSpuService.getSpuPage(reqVO).getList(); // 导出 Excel - List datas = ProductSpuConvert.INSTANCE.convertList03(spuList); - ExcelUtils.write(response, "商品列表.xls", "数据", ProductSpuExcelVO.class, datas); + ExcelUtils.write(response, "商品列表.xls", "数据", ProductSpuRespVO.class, + BeanUtils.toBean(list, ProductSpuRespVO.class)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuRespVO.java new file mode 100755 index 000000000..f977d33c9 --- /dev/null +++ b/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 properties; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java similarity index 87% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java index 1acc6a08a..00dc0f031 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSkuSaveReqVO.java @@ -1,20 +1,17 @@ -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 jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; 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 +38,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; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java deleted file mode 100755 index 39bc8a556..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java +++ /dev/null @@ -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 skus; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java deleted file mode 100644 index 1be96632d..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java +++ /dev/null @@ -1,34 +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 ProductSpuBaseVO { - - @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1212") - private Long id; - - @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000") - private Integer salesCount; - - @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20000") - private Integer browseCount; - - @Schema(description = "商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer status; - - // ========== SKU 相关字段 ========= - - @Schema(description = "SKU 数组") - private List skus; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java deleted file mode 100644 index 38cbd8472..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExcelVO.java +++ /dev/null @@ -1,112 +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 String videoUrl; - - @ExcelProperty(value = "商品单位", converter = DictConvert.class) - @DictFormat(DictTypeConstants.PRODUCT_UNIT) - private Integer unit; - - @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 Boolean recommendHot; - - @ExcelProperty("是否优惠推荐") - private Boolean recommendBenefit; - - @ExcelProperty("是否精品推荐") - private Boolean recommendBest; - - @ExcelProperty("是否新品推荐") - private Boolean recommendNew; - - @ExcelProperty("是否优品推荐") - private Boolean recommendGood; - - @ExcelProperty("赠送积分") - private Integer giveIntegral; - - @ExcelProperty("分销类型") - private Boolean subCommissionType; - - @ExcelProperty("商品销量") - private Integer salesCount; - - @ExcelProperty("虚拟销量") - private Integer virtualSalesCount; - - @ExcelProperty("商品点击量") - private Integer browseCount; - - @ExcelProperty("创建时间") - private LocalDateTime createTime; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java deleted file mode 100644 index 3b3dccd7e..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java +++ /dev/null @@ -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; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java index 0148cb2a1..fbc75522a 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java +++ b/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 = "spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "111") + @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 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 skus; - @Schema(description = "商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer status; + // ========== 物流相关字段 ========= + + @Schema(description = "配送方式数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private List 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; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSaveReqVO.java similarity index 56% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSaveReqVO.java index a90a19526..b842df026 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java +++ b/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,16 +43,10 @@ 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 sliderPicUrls; - @Schema(description = "商品视频", example = "https://www.iocoder.cn/xx.mp4") - private String videoUrl; - - @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "商品单位不能为空") - private Integer unit; - @Schema(description = "排序字段", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "商品排序字段不能为空") private Integer sort; @@ -66,61 +59,38 @@ public class ProductSpuBaseVO { // ========== 物流相关字段 ========= + @Schema(description = "配送方式数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotEmpty(message = "配送方式不能为空") + private List deliveryTypes; + @Schema(description = "物流配置模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "111") - @NotNull(message = "物流配置模板编号不能为空") private Long deliveryTemplateId; // ========== 营销相关字段 ========= - @Schema(description = "是否热卖推荐", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - @NotNull(message = "商品推荐不能为空") - private Boolean recommendHot; - - @Schema(description = "是否优惠推荐", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - @NotNull(message = "商品推荐不能为空") - private Boolean recommendBenefit; - - @Schema(description = "是否精品推荐", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - @NotNull(message = "商品推荐不能为空") - private Boolean recommendBest; - - @Schema(description = "是否新品推荐", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - @NotNull(message = "商品推荐不能为空") - private Boolean recommendNew; - - @Schema(description = "是否优品推荐", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") - @NotNull(message = "商品推荐不能为空") - private Boolean recommendGood; - @Schema(description = "赠送积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "111") @NotNull(message = "商品赠送积分不能为空") private Integer giveIntegral; - @Schema(description = "赠送的优惠劵数组包含优惠券编号和名称") - private List giveCouponTemplates; - @Schema(description = "分销类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") @NotNull(message = "商品分销类型不能为空") private Boolean subCommissionType; - @Schema(description = "活动展示顺序", example = "[1, 3, 2, 4, 5]") - private List activityOrders; - // ========== 统计相关字段 ========= @Schema(description = "虚拟销量", example = "66") private Integer virtualSalesCount; - @Schema(description = "管理后台 - 商品 SPU 赠送的优惠卷") - @Data - public static class GiveCouponTemplate { + @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999") + private Integer salesCount; - @Schema(description = "模板编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Long id; + @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1999") + private Integer browseCount; - @Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送") - private String name; + // ========== SKU 相关字段 ========= - } + @Schema(description = "SKU 数组") + @Valid + private List skus; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java deleted file mode 100755 index 7673ca751..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java +++ /dev/null @@ -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 skus; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java index 0bc015897..733f336dd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateStatusReqVO.java @@ -3,9 +3,8 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotNull; +import lombok.Data; @Schema(description = "管理后台 - 商品 SPU Status 更新 Request VO") @Data diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java index 4c13154b5..5b1912257 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java @@ -1,18 +1,22 @@ package cn.iocoder.yudao.module.product.controller.app.category; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO; -import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; 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 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 java.util.Collections; import java.util.Comparator; import java.util.List; @@ -32,7 +36,19 @@ public class AppCategoryController { public CommonResult> getProductCategoryList() { List list = categoryService.getEnableCategoryList(); list.sort(Comparator.comparing(ProductCategoryDO::getSort)); - return success(ProductCategoryConvert.INSTANCE.convertList03(list)); + return success(BeanUtils.toBean(list, AppCategoryRespVO.class)); + } + + @GetMapping("/list-by-ids") + @Operation(summary = "获得商品分类列表,指定编号") + @Parameter(name = "ids", description = "商品分类编号数组", required = true) + public CommonResult> getProductCategoryList(@RequestParam("ids") List ids) { + if (CollUtil.isEmpty(ids)) { + return success(Collections.emptyList()); + } + List list = categoryService.getEnableCategoryList(ids); + list.sort(Comparator.comparing(ProductCategoryDO::getSort)); + return success(BeanUtils.toBean(list, AppCategoryRespVO.class)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java index 1ddec5fe4..e386c5984 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java @@ -1,10 +1,9 @@ package cn.iocoder.yudao.module.product.controller.app.category.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import lombok.Data; @Data @Schema(description = "用户 APP - 商品分类 Response VO") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java index 0fadfeb93..cd9fac80e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java @@ -3,31 +3,21 @@ package cn.iocoder.yudao.module.product.controller.app.comment; 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.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; -import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; -import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; 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 org.springframework.context.annotation.Lazy; +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.List; -import java.util.Set; - import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @Tag(name = "用户 APP - 商品评价") @RestController @@ -38,43 +28,22 @@ public class AppProductCommentController { @Resource private ProductCommentService productCommentService; - @Resource - @Lazy - private ProductSkuService productSkuService; - - @GetMapping("/list") - @Operation(summary = "获得最近的 n 条商品评价") - @Parameters({ - @Parameter(name = "spuId", description = "商品 SPU 编号", required = true, example = "1024"), - @Parameter(name = "count", description = "数量", required = true, example = "10") - }) - public CommonResult> getCommentList( - @RequestParam("spuId") Long spuId, - @RequestParam(value = "count", defaultValue = "10") Integer count) { - return success(productCommentService.getCommentList(spuId, count)); - } - @GetMapping("/page") @Operation(summary = "获得商品评价分页") public CommonResult> getCommentPage(@Valid AppCommentPageReqVO pageVO) { // 查询评论分页 - PageResult commentPageResult = productCommentService.getCommentPage(pageVO, Boolean.TRUE); - if (CollUtil.isEmpty(commentPageResult.getList())) { - return success(PageResult.empty(commentPageResult.getTotal())); + PageResult pageResult = productCommentService.getCommentPage(pageVO, Boolean.TRUE); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty(pageResult.getTotal())); } // 拼接返回 - Set skuIds = convertSet(commentPageResult.getList(), ProductCommentDO::getSkuId); - PageResult commentVOPageResult = ProductCommentConvert.INSTANCE.convertPage02( - commentPageResult, productSkuService.getSkuList(skuIds)); - return success(commentVOPageResult); - } - - // TODO 芋艿:需要搞下 - @GetMapping("/statistics") - @Operation(summary = "获得商品的评价统计") - public CommonResult getCommentStatistics(@Valid @RequestParam("spuId") Long spuId) { - return success(productCommentService.getCommentStatistics(spuId, Boolean.TRUE)); + pageResult.getList().forEach(item -> { + if (Boolean.TRUE.equals(item.getAnonymous())) { + item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS); + } + }); + return success(BeanUtils.toBean(pageResult, AppProductCommentRespVO.class)); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java index e38753997..ca3acb72f 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentPageReqVO.java @@ -2,12 +2,11 @@ package cn.iocoder.yudao.module.product.controller.app.comment.vo; import cn.iocoder.yudao.framework.common.pojo.PageParam; 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; - @Schema(description = "用户 App - 商品评价分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @@ -27,12 +26,12 @@ public class AppCommentPageReqVO extends PageParam { */ public static final Integer NEGATIVE_COMMENT = 3; - @Schema(description = "商品SPU编号", example = "29502") - @NotNull(message = "商品SPU编号不能为空") + @Schema(description = "商品 SPU 编号", example = "29502") + @NotNull(message = "商品 SPU 编号不能为空") private Long spuId; @Schema(description = "app 评论页 tab 类型 (0 全部、1 好评、2 中评、3 差评)", example = "0") - @NotNull(message = "商品SPU编号不能为空") + @NotNull(message = "商品 SPU 编号不能为空") private Integer type; } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java deleted file mode 100644 index e863ab02c..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppCommentStatisticsRespVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.product.controller.app.comment.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - -@Schema(description = "APP - 商品评价页评论分类数统计 Response VO") -@Data -@ToString(callSuper = true) -public class AppCommentStatisticsRespVO { - - @Schema(description = "好评数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15721") - private Long goodCount; - - @Schema(description = "中评数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15721") - private Long mediocreCount; - - @Schema(description = "差评数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "15721") - private Long negativeCount; - - @Schema(description = "总平均分", requiredMode = Schema.RequiredMode.REQUIRED, example = "3.55") - private Double scores; - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java index 1d42bab80..dd626beba 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/vo/AppProductCommentRespVO.java @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.product.controller.app.comment.vo; import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.Data; import lombok.ToString; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; import java.time.LocalDateTime; import java.util.List; @@ -91,7 +91,8 @@ public class AppProductCommentRespVO { @NotNull(message = "评论内容不能为空") private String content; - @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/xx.png]") + @Schema(description = "评论图片地址数组,以逗号分隔最多上传 9 张", requiredMode = Schema.RequiredMode.REQUIRED, + example = "[https://www.iocoder.cn/xx.png]") @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") private List picUrls; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index 9f6b47883..c632171a0 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -4,7 +4,6 @@ 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.security.core.annotations.PreAuthenticated; -import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteBatchReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; @@ -15,10 +14,10 @@ import cn.iocoder.yudao.module.product.service.favorite.ProductFavoriteService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.web.bind.annotation.*; - import jakarta.annotation.Resource; import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.*; + import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -42,14 +41,6 @@ public class AppFavoriteController { return success(productFavoriteService.createFavorite(getLoginUserId(), reqVO.getSpuId())); } - @PostMapping(value = "/create-list") - @Operation(summary = "添加多个商品收藏") - @PreAuthenticated - public CommonResult createFavoriteList(@RequestBody @Valid AppFavoriteBatchReqVO reqVO) { - // todo @jason:待实现;如果有已经收藏的,不用报错,忽略即可; - return success(true); - } - @DeleteMapping(value = "/delete") @Operation(summary = "取消单个商品收藏") @PreAuthenticated @@ -58,15 +49,6 @@ public class AppFavoriteController { return success(Boolean.TRUE); } - @DeleteMapping(value = "/delete-list") - @Operation(summary = "取消多个商品收藏") - @PreAuthenticated - public CommonResult deleteFavoriteList(@RequestBody @Valid AppFavoriteBatchReqVO reqVO) { - // todo @jason:待实现 -// productFavoriteService.deleteFavorite(getLoginUserId(), reqVO.getSpuId()); - return success(Boolean.TRUE); - } - @GetMapping(value = "/page") @Operation(summary = "获得商品收藏分页") @PreAuthenticated diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteBatchReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteBatchReqVO.java index 842cb36c1..0954dd58c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteBatchReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteBatchReqVO.java @@ -1,9 +1,9 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; import lombok.Data; -import jakarta.validation.constraints.NotEmpty; import java.util.List; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java index 8ff1aac84..7bd6462ab 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteReqVO.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotNull; +import lombok.Data; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java index db2ea90a4..306e50048 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/vo/AppFavoriteRespVO.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.controller.app.favorite.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; + import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; @Schema(description = "用户 App - 商品收藏 Response VO") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/AppProductBrowseHistoryController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/AppProductBrowseHistoryController.java new file mode 100644 index 000000000..5b0d292b1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/AppProductBrowseHistoryController.java @@ -0,0 +1,77 @@ +package cn.iocoder.yudao.module.product.controller.app.history; + +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.framework.security.core.annotations.PreAuthenticated; +import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.history.vo.AppProductBrowseHistoryDeleteReqVO; +import cn.iocoder.yudao.module.product.controller.app.history.vo.AppProductBrowseHistoryPageReqVO; +import cn.iocoder.yudao.module.product.controller.app.history.vo.AppProductBrowseHistoryRespVO; +import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO; +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; +import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService; +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 APP - 商品浏览记录") +@RestController +@RequestMapping("/product/browse-history") +public class AppProductBrowseHistoryController { + + @Resource + private ProductBrowseHistoryService productBrowseHistoryService; + @Resource + private ProductSpuService productSpuService; + + @DeleteMapping(value = "/delete") + @Operation(summary = "删除商品浏览记录") + @PreAuthenticated + public CommonResult deleteBrowseHistory(@RequestBody @Valid AppProductBrowseHistoryDeleteReqVO reqVO) { + productBrowseHistoryService.hideUserBrowseHistory(getLoginUserId(), reqVO.getSpuIds()); + return success(Boolean.TRUE); + } + + @DeleteMapping(value = "/clean") + @Operation(summary = "清空商品浏览记录") + @PreAuthenticated + public CommonResult deleteBrowseHistory() { + productBrowseHistoryService.hideUserBrowseHistory(getLoginUserId(), null); + return success(Boolean.TRUE); + } + + @GetMapping(value = "/page") + @Operation(summary = "获得商品浏览记录分页") + @PreAuthenticated + public CommonResult> getBrowseHistoryPage(AppProductBrowseHistoryPageReqVO reqVO) { + ProductBrowseHistoryPageReqVO pageReqVO = BeanUtils.toBean(reqVO, ProductBrowseHistoryPageReqVO.class) + .setUserId(getLoginUserId()) + .setUserDeleted(false); // 排除用户已删除的(隐藏的) + PageResult pageResult = productBrowseHistoryService.getBrowseHistoryPage(pageReqVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty()); + } + + // 得到商品 spu 信息 + Set spuIds = convertSet(pageResult.getList(), ProductBrowseHistoryDO::getSpuId); + Map spuMap = convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId); + return success(BeanUtils.toBean(pageResult, AppProductBrowseHistoryRespVO.class, + vo -> Optional.ofNullable(spuMap.get(vo.getSpuId())) + .ifPresent(spu -> vo.setSpuName(spu.getName()).setPicUrl(spu.getPicUrl()).setPrice(spu.getPrice())))); + } + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryDeleteReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryDeleteReqVO.java new file mode 100644 index 000000000..5eb9d439a --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryDeleteReqVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.product.controller.app.history.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotEmpty; +import lombok.Data; + +import java.util.List; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +@Schema(description = "用户 APP - 删除商品浏览记录的 Request VO") +@Data +public class AppProductBrowseHistoryDeleteReqVO { + + @Schema(description = "商品 SPU 编号数组", requiredMode = REQUIRED, example = "29502") + @NotEmpty(message = "商品 SPU 编号数组不能为空") + private List spuIds; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryPageReqVO.java new file mode 100644 index 000000000..f959fd0d1 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryPageReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.product.controller.app.history.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +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 = "用户 APP - 商品浏览记录分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class AppProductBrowseHistoryPageReqVO extends PageParam { + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryRespVO.java new file mode 100644 index 000000000..05b528cdb --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/history/vo/AppProductBrowseHistoryRespVO.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.product.controller.app.history.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; + +@Schema(description = "用户 App - 商品浏览记录 Response VO") +@Data +public class AppProductBrowseHistoryRespVO { + + @Schema(description = "编号", requiredMode = REQUIRED, example = "1") + private Long id; + + @Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502") + private Long spuId; + + // ========== 商品相关字段 ========== + + @Schema(description = "商品 SPU 名称", example = "赵六") + private String spuName; + + @Schema(description = "商品封面图", example = "https://domain/pic.png") + private String picUrl; + + @Schema(description = "商品单价", example = "100") + private Integer price; + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java index 4ee7e27f7..dc9d919eb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java @@ -3,33 +3,34 @@ 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; +import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService; 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; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -47,28 +48,26 @@ public class AppProductSpuController { private ProductSpuService productSpuService; @Resource private ProductSkuService productSkuService; + @Resource + private ProductBrowseHistoryService productBrowseHistoryService; @Resource private MemberLevelApi memberLevelApi; @Resource private MemberUserApi memberUserApi; - @GetMapping("/list") + @GetMapping("/list-by-ids") @Operation(summary = "获得商品 SPU 列表") - @Parameters({ - @Parameter(name = "recommendType", description = "推荐类型", required = true), // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量 - @Parameter(name = "count", description = "数量", required = true) - }) - public CommonResult> getSpuList( - @RequestParam("recommendType") String recommendType, - @RequestParam(value = "count", defaultValue = "10") Integer count) { - List list = productSpuService.getSpuList(recommendType, count); + @Parameter(name = "ids", description = "编号列表", required = true) + public CommonResult> getSpuList(@RequestParam("ids") Set ids) { + List list = productSpuService.getSpuList(ids); if (CollUtil.isEmpty(list)) { return success(Collections.emptyList()); } // 拼接返回 - List voList = ProductSpuConvert.INSTANCE.convertListForGetSpuList(list); + list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); + List voList = BeanUtils.toBean(list, AppProductSpuRespVO.class); // 处理 vip 价格 MemberLevelRespDTO memberLevel = getMemberLevel(); voList.forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel))); @@ -77,14 +76,15 @@ public class AppProductSpuController { @GetMapping("/page") @Operation(summary = "获得商品 SPU 分页") - public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { + public CommonResult> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) { PageResult pageResult = productSpuService.getSpuPage(pageVO); if (CollUtil.isEmpty(pageResult.getList())) { return success(PageResult.empty(pageResult.getTotal())); } // 拼接返回 - PageResult voPageResult = ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult); + pageResult.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); + PageResult voPageResult = BeanUtils.toBean(pageResult, AppProductSpuRespVO.class); // 处理 vip 价格 MemberLevelRespDTO memberLevel = getMemberLevel(); voPageResult.getList().forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel))); @@ -103,14 +103,22 @@ public class AppProductSpuController { if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) { throw exception(SPU_NOT_ENABLE); } + // 获得商品 SKU + List skus = productSkuService.getSkuListBySpuId(spu.getId()); + + // 增加浏览量 + productSpuService.updateBrowseCount(id, 1); + // 保存浏览记录 + productBrowseHistoryService.createBrowseHistory(getLoginUserId(), id); // 拼接返回 - List 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() { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java index c890a7961..f1ee49b10 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java @@ -33,17 +33,8 @@ public class AppProductSpuDetailRespVO { @Schema(description = "商品轮播图", requiredMode = Schema.RequiredMode.REQUIRED) private List sliderPicUrls; - @Schema(description = "商品视频", requiredMode = Schema.RequiredMode.REQUIRED) - private String videoUrl; - - @Schema(description = "单位名", requiredMode = Schema.RequiredMode.REQUIRED, example = "个") - private String unitName; - // ========== 营销相关字段 ========= - @Schema(description = "活动排序数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private List activityOrders; - // ========== SKU 相关字段 ========= @Schema(description = "规格类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java index cda799d46..9e7930e58 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java @@ -4,11 +4,12 @@ import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageParam; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.AssertTrue; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import jakarta.validation.constraints.AssertTrue; +import java.util.List; @Schema(description = "用户 App - 商品 SPU 分页 Request VO") @Data @@ -18,16 +19,17 @@ public class AppProductSpuPageReqVO extends PageParam { public static final String SORT_FIELD_PRICE = "price"; 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 ids; @Schema(description = "分类编号", example = "1") private Long categoryId; + @Schema(description = "分类编号数组", example = "1,2,3") + private List categoryIds; + @Schema(description = "关键字", example = "好看") private String keyword; @@ -37,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() { diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuRespVO.java similarity index 85% rename from yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java rename to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuRespVO.java index c4a66afd2..df61090bb 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java +++ b/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; @@ -15,6 +15,9 @@ public class AppProductSpuPageRespVO { @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道") private String name; + @Schema(description = "商品简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "清凉小短袖简介") + private String introduction; + @Schema(description = "分类编号", requiredMode = Schema.RequiredMode.REQUIRED) private Long categoryId; @@ -24,9 +27,6 @@ public class AppProductSpuPageRespVO { @Schema(description = "商品轮播图", requiredMode = Schema.RequiredMode.REQUIRED) private List sliderPicUrls; - @Schema(description = "单位名", requiredMode = Schema.RequiredMode.REQUIRED, example = "个") - private String unitName; - // ========== SKU 相关字段 ========= @Schema(description = "规格类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") @@ -40,15 +40,12 @@ public class AppProductSpuPageRespVO { @Schema(description = "VIP 价格,单位使用:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "968") // 通过会员等级,计算出折扣后价格 private Integer vipPrice; - + @Schema(description = "库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "666") private Integer stock; // ========== 营销相关字段 ========= - @Schema(description = "活动排序数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private List activityOrders; - // ========== 统计相关字段 ========= @Schema(description = "商品销量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java deleted file mode 100644 index ae01ca9d5..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.category; - -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO; -import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * 商品分类 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductCategoryConvert { - - ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class); - - ProductCategoryDO convert(ProductCategoryCreateReqVO bean); - - ProductCategoryDO convert(ProductCategoryUpdateReqVO bean); - - ProductCategoryRespVO convert(ProductCategoryDO bean); - - List convertList(List list); - - List convertList03(List list); -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index 944eb2bc2..7a3a3c011 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -1,29 +1,17 @@ package cn.iocoder.yudao.module.product.convert.comment; -import cn.hutool.core.util.ObjectUtil; -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.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; -import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; 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.math.BigDecimal; import java.math.RoundingMode; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; /** * 商品评价 Convert @@ -35,48 +23,35 @@ public interface ProductCommentConvert { ProductCommentConvert INSTANCE = Mappers.getMapper(ProductCommentConvert.class); - ProductCommentRespVO convert(ProductCommentDO bean); - - @Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))") - AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount); - - @Named("calculateOverallScore") - default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) { - return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount); + default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, + ProductSpuDO spu, ProductSkuDO sku, MemberUserRespDTO user) { + ProductCommentDO comment = BeanUtils.toBean(createReqDTO, ProductCommentDO.class) + .setScores(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores())); + if (user != null) { + comment.setUserId(user.getId()).setUserNickname(user.getNickname()).setUserAvatar(user.getAvatar()); + } + if (spu != null) { + comment.setSpuId(spu.getId()).setSpuName(spu.getName()); + } + if (sku != null) { + comment.setSkuPicUrl(sku.getPicUrl()).setSkuProperties(sku.getProperties()); + } + return comment; } - List convertList(List list); - - PageResult convertPage(PageResult page); - - PageResult convertPage01(PageResult pageResult); - - default PageResult convertPage02(PageResult pageResult, - List skuList) { - Map skuMap = CollectionUtils.convertMap(skuList, ProductSkuDO::getId); - PageResult page = convertPage01(pageResult); - page.getList().forEach(item -> { - // 判断用户是否选择匿名 - if (ObjectUtil.equal(item.getAnonymous(), true)) { - item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS); - } - // 设置 SKU 规格值 - findAndThen(skuMap, item.getSkuId(), - sku -> item.setSkuProperties(convertList01(sku.getProperties()))); - }); - return page; + default ProductCommentDO convert(ProductCommentCreateReqVO createReq, ProductSpuDO spu, ProductSkuDO sku) { + ProductCommentDO comment = BeanUtils.toBean(createReq, ProductCommentDO.class) + .setVisible(true).setUserId(0L).setAnonymous(false) + .setScores(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores())); + if (spu != null) { + comment.setSpuId(spu.getId()).setSpuName(spu.getName()); + } + if (sku != null) { + comment.setSkuPicUrl(sku.getPicUrl()).setSkuProperties(sku.getProperties()); + } + return comment; } - List convertList01(List properties); - - /** - * 计算综合评分 - * - * @param descriptionScores 描述星级 - * @param benefitScores 服务星级 - * @return 综合评分 - */ - @Named("convertScores") default Integer convertScores(Integer descriptionScores, Integer benefitScores) { // 计算评价最终综合评分 最终星数 = (商品评星 + 服务评星) / 2 BigDecimal sumScore = new BigDecimal(descriptionScores + benefitScores); @@ -84,49 +59,4 @@ public interface ProductCommentConvert { return divide.intValue(); } - ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO); - - @Mapping(target = "scores", - expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") - default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, ProductSkuDO skuDO, MemberUserRespDTO user) { - ProductCommentDO commentDO = convert(createReqDTO); - if (user != null) { - commentDO.setUserId(user.getId()); - commentDO.setUserNickname(user.getNickname()); - commentDO.setUserAvatar(user.getAvatar()); - } - if (spuDO != null) { - commentDO.setSpuId(spuDO.getId()); - commentDO.setSpuName(spuDO.getName()); - } - if (skuDO != null) { - commentDO.setSkuPicUrl(skuDO.getPicUrl()); - commentDO.setSkuProperties(skuDO.getProperties()); - } - return commentDO; - } - - @Mapping(target = "visible", constant = "true") - @Mapping(target = "replyStatus", constant = "false") - @Mapping(target = "userId", constant = "0L") - @Mapping(target = "orderId", constant = "0L") - @Mapping(target = "orderItemId", constant = "0L") - @Mapping(target = "anonymous", expression = "java(Boolean.FALSE)") - @Mapping(target = "scores", - expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))") - ProductCommentDO convert(ProductCommentCreateReqVO createReq); - - List convertList02(List list); - - default ProductCommentDO convert(ProductCommentCreateReqVO createReq, ProductSpuDO spu, ProductSkuDO sku) { - ProductCommentDO commentDO = convert(createReq); - if (spu != null) { - commentDO.setSpuId(spu.getId()).setSpuName(spu.getName()); - } - if (sku != null) { - commentDO.setSkuPicUrl(sku.getPicUrl()).setSkuProperties(sku.getProperties()); - } - return commentDO; - } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java index b15afacb2..7b419b6a8 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/favorite/ProductFavoriteConvert.java @@ -1,5 +1,8 @@ package cn.iocoder.yudao.module.product.convert.favorite; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.product.controller.admin.favorite.vo.ProductFavoriteRespVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoriteRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -34,4 +37,18 @@ public interface ProductFavoriteConvert { return resultList; } + default PageResult convertPage(PageResult pageResult, List spuList) { + Map spuMap = convertMap(spuList, ProductSpuDO::getId); + List voList = CollectionUtils.convertList(pageResult.getList(), favorite -> { + ProductSpuDO spu = spuMap.get(favorite.getSpuId()); + return convert02(spu, favorite); + }); + return new PageResult<>(voList, pageResult.getTotal()); + } + @Mapping(target = "id", source = "favorite.id") + @Mapping(target = "userId", source = "favorite.userId") + @Mapping(target = "spuId", source = "favorite.spuId") + @Mapping(target = "createTime", source = "favorite.createTime") + ProductFavoriteRespVO convert02(ProductSpuDO spu, ProductFavoriteDO favorite); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java deleted file mode 100644 index 368da9416..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java +++ /dev/null @@ -1,57 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.property; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -/** - * 属性项 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductPropertyConvert { - - ProductPropertyConvert INSTANCE = Mappers.getMapper(ProductPropertyConvert.class); - - ProductPropertyDO convert(ProductPropertyCreateReqVO bean); - - ProductPropertyDO convert(ProductPropertyUpdateReqVO bean); - - ProductPropertyRespVO convert(ProductPropertyDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - default List convertList(List keys, List values) { - Map> valueMap = CollectionUtils.convertMultiMap(values, ProductPropertyValueDO::getPropertyId); - return CollectionUtils.convertList(keys, key -> { - ProductPropertyAndValueRespVO respVO = convert02(key); - // 如果属性值为空value不为null,返回空列表 - if (CollUtil.isEmpty(values)) { - respVO.setValues(Collections.emptyList()); - }else { - respVO.setValues(convertList02(valueMap.get(key.getId()))); - } - return respVO; - }); - } - ProductPropertyAndValueRespVO convert02(ProductPropertyDO bean); - List convertList02(List list); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyValueConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyValueConvert.java deleted file mode 100644 index 57ac4e172..000000000 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyValueConvert.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.product.convert.property; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * 属性值 Convert - * - * @author 芋道源码 - */ -@Mapper -public interface ProductPropertyValueConvert { - - ProductPropertyValueConvert INSTANCE = Mappers.getMapper(ProductPropertyValueConvert.class); - - ProductPropertyValueDO convert(ProductPropertyValueCreateReqVO bean); - - ProductPropertyValueDO convert(ProductPropertyValueUpdateReqVO bean); - - ProductPropertyValueRespVO convert(ProductPropertyValueDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java index 5065a9c40..492f483c0 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java +++ b/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 convertList(List list); - - List convertList06(List list); - - default List convertList06(List list, Long spuId) { - List result = convertList06(list); - result.forEach(item -> item.setSpuId(spuId)); - return result; - } - - ProductSkuRespDTO convert02(ProductSkuDO bean); - - List convertList04(List list); - /** * 获得 SPU 的库存变化 Map * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java index 8f7194b43..364434241 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java @@ -1,28 +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.framework.dict.core.util.DictFrameworkUtils; -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 cn.iocoder.yudao.module.product.enums.DictTypeConstants; -//import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponTemplateRespDTO; 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; /** @@ -35,82 +26,17 @@ public interface ProductSpuConvert { ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); - ProductSpuDO convert(ProductSpuCreateReqVO bean); - - ProductSpuDO convert(ProductSpuUpdateReqVO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean); - List convertList2(List list); - - List convertList02(List 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 convertList03(List list) { - List 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 convertPageForGetSpuPage(PageResult page); - - default List convertListForGetSpuList(List list) { - // 处理虚拟销量 - list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount())); - // 处理 VO 字段 - List voList = convertListForGetSpuList0(list); - for (int i = 0; i < list.size(); i++) { - ProductSpuDO spu = list.get(i); - AppProductSpuPageRespVO spuVO = voList.get(i); - spuVO.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); - } - return voList; - } - - @Named("convertListForGetSpuList0") - List convertListForGetSpuList0(List list); - - default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List skus) { - // 处理 SPU - AppProductSpuDetailRespVO spuVO = convertForGetSpuDetail(spu) - .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0)) - .setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); - // 处理 SKU - spuVO.setSkus(convertListForGetSpuDetail(skus)); + default ProductSpuRespVO convert(ProductSpuDO spu, List skus) { + ProductSpuRespVO spuVO = BeanUtils.toBean(spu, ProductSpuRespVO.class); + spuVO.setSkus(BeanUtils.toBean(skus, ProductSkuRespVO.class)); return spuVO; } - AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu); - - List convertListForGetSpuDetail(List skus); - - default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List skus) { - ProductSpuDetailRespVO respVO = convert03(spu); - respVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skus)); - return respVO; - } - - default List convertForSpuDetailRespListVO(List spus, List skus) { + default List convertForSpuDetailRespListVO(List spus, List skus) { Map> 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()))); } } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java index bf69e0028..78e35d6f5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java @@ -48,12 +48,6 @@ public class ProductCategoryDO extends BaseDO { * 建议 180*180 分辨率 */ private String picUrl; - /** - * PC 端分类图 - * - * 建议 468*340 分辨率 - */ - private String bigPicUrl; /** * 分类排序 */ diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/history/ProductBrowseHistoryDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/history/ProductBrowseHistoryDO.java new file mode 100644 index 000000000..472574bd9 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/history/ProductBrowseHistoryDO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.product.dal.dataobject.history; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商品浏览记录 DO + * + * @author owen + */ +@TableName("product_browse_history") +@KeySequence("product_browse_history_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductBrowseHistoryDO extends BaseDO { + + /** + * 记录编号 + */ + @TableId + private Long id; + /** + * 商品 SPU 编号 + */ + private Long spuId; + /** + * 用户编号 + */ + private Long userId; + /** + * 用户是否删除 + */ + private Boolean userDeleted; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java index 9ce55a096..d2b519596 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.product.dal.dataobject.spu; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; @@ -53,11 +54,6 @@ public class ProductSpuDO extends BaseDO { * 商品详情 */ private String description; - // TODO @芋艿:是不是要删除 - /** - * 商品条码(一维码) - */ - private String barCode; /** * 商品分类编号 @@ -80,17 +76,7 @@ public class ProductSpuDO extends BaseDO { */ @TableField(typeHandler = JacksonTypeHandler.class) private List sliderPicUrls; - /** - * 商品视频 - */ - private String videoUrl; - /** - * 单位 - * - * 对应 product_unit 数据字典 - */ - private Integer unit; /** * 排序字段 */ @@ -138,6 +124,13 @@ public class ProductSpuDO extends BaseDO { // ========== 物流相关字段 ========= + /** + * 配送方式数组 + * + * 对应 DeliveryTypeEnum 枚举 + */ + @TableField(typeHandler = IntegerListTypeHandler.class) + private List deliveryTypes; /** * 物流配置模板编号 * @@ -146,38 +139,11 @@ public class ProductSpuDO extends BaseDO { private Long deliveryTemplateId; // ========== 营销相关字段 ========= - /** - * 是否热卖推荐 - */ - private Boolean recommendHot; - /** - * 是否优惠推荐 - */ - private Boolean recommendBenefit; - /** - * 是否精品推荐 - */ - private Boolean recommendBest; - /** - * 是否新品推荐 - */ - private Boolean recommendNew; - /** - * 是否优品推荐 - */ - private Boolean recommendGood; /** * 赠送积分 */ private Integer giveIntegral; - /** - * 赠送的优惠劵编号的数组 - * - * 对应 CouponTemplateDO 的 id 属性 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List giveCouponTemplateIds; // TODO @puhui999:字段估计要改成 brokerageType /** @@ -188,14 +154,6 @@ public class ProductSpuDO extends BaseDO { */ private Boolean subCommissionType; - /** - * 活动展示顺序 - * - * 对应 PromotionTypeEnum 枚举 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List activityOrders; // TODO @芋艿: 活动顺序字段长度需要增加 - // ========== 统计相关字段 ========= /** diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java index fbb88f592..4c212de94 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCateg import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import org.apache.ibatis.annotations.Mapper; +import java.util.Collection; import java.util.List; /** @@ -20,6 +21,7 @@ public interface ProductCategoryMapper extends BaseMapperX { return selectList(new LambdaQueryWrapperX() .likeIfPresent(ProductCategoryDO::getName, listReqVO.getName()) .eqIfPresent(ProductCategoryDO::getParentId, listReqVO.getParentId()) + .inIfPresent(ProductCategoryDO::getId, listReqVO.getParentIds()) .eqIfPresent(ProductCategoryDO::getStatus, listReqVO.getStatus()) .orderByDesc(ProductCategoryDO::getId)); } @@ -32,4 +34,10 @@ public interface ProductCategoryMapper extends BaseMapperX { return selectList(ProductCategoryDO::getStatus, status); } + default List selectListByIdAndStatus(Collection ids, Integer status) { + return selectList(new LambdaQueryWrapperX() + .in(ProductCategoryDO::getId, ids) + .eq(ProductCategoryDO::getStatus, status)); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java index 387a3736b..ca04c507c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.product.dal.mysql.comment; import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.pojo.PageParam; 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; @@ -59,21 +58,4 @@ public interface ProductCommentMapper extends BaseMapperX { .eq(ProductCommentDO::getOrderItemId, orderItemId)); } - default Long selectCountBySpuId(Long spuId, Boolean visible, Integer type) { - LambdaQueryWrapperX queryWrapper = new LambdaQueryWrapperX() - .eqIfPresent(ProductCommentDO::getSpuId, spuId) - .eqIfPresent(ProductCommentDO::getVisible, visible); - // 构建评价查询语句 - appendTabQuery(queryWrapper, type); - return selectCount(queryWrapper); - } - - default PageResult selectCommentList(Long spuId, Integer count) { - // 构建分页查询条件 - return selectPage(new PageParam().setPageSize(count), new LambdaQueryWrapperX() - .eqIfPresent(ProductCommentDO::getSpuId, spuId) - .orderByDesc(ProductCommentDO::getCreateTime) - ); - } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java index 54d9d2dd6..a681d42a7 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/favorite/ProductFavoriteMapper.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.product.dal.mysql.favorite; 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.module.product.controller.admin.favorite.vo.ProductFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -21,6 +23,12 @@ public interface ProductFavoriteMapper extends BaseMapperX { .orderByDesc(ProductFavoriteDO::getId)); } + default PageResult selectPageByUserId(ProductFavoritePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ProductFavoriteDO::getUserId, reqVO.getUserId()) + .orderByDesc(ProductFavoriteDO::getId)); + } + default Long selectCountByUserId(Long userId) { return selectCount(ProductFavoriteDO::getUserId, userId); } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/history/ProductBrowseHistoryMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/history/ProductBrowseHistoryMapper.java new file mode 100644 index 000000000..124357cac --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/history/ProductBrowseHistoryMapper.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.product.dal.mysql.history; + +import cn.hutool.core.collection.CollUtil; +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.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; + +/** + * 商品浏览记录 Mapper + * + * @author owen + */ +@Mapper +public interface ProductBrowseHistoryMapper extends BaseMapperX { + + default ProductBrowseHistoryDO selectByUserIdAndSpuId(Long userId, Long spuId) { + return selectOne(new LambdaQueryWrapperX() + .eq(ProductBrowseHistoryDO::getUserId, userId) + .eq(ProductBrowseHistoryDO::getSpuId, spuId)); + } + + default PageResult selectPage(ProductBrowseHistoryPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ProductBrowseHistoryDO::getUserId, reqVO.getUserId()) + .eqIfPresent(ProductBrowseHistoryDO::getUserDeleted, reqVO.getUserDeleted()) + .eqIfPresent(ProductBrowseHistoryDO::getSpuId, reqVO.getSpuId()) + .betweenIfPresent(ProductBrowseHistoryDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(ProductBrowseHistoryDO::getId)); + } + + default void updateUserDeletedByUserId(Long userId, Collection spuIds, Boolean userDeleted) { + update(new LambdaUpdateWrapper() + .eq(ProductBrowseHistoryDO::getUserId, userId) + .in(CollUtil.isNotEmpty(spuIds), ProductBrowseHistoryDO::getSpuId, spuIds) + .set(ProductBrowseHistoryDO::getUserDeleted, userDeleted)); + } + + default Page selectPageByUserIdOrderByCreateTimeAsc(Long userId, Integer pageNo, Integer pageSize) { + Page page = Page.of(pageNo, pageSize); + return selectPage(page, new LambdaQueryWrapperX() + .eqIfPresent(ProductBrowseHistoryDO::getUserId, userId) + .orderByAsc(ProductBrowseHistoryDO::getCreateTime)); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java index 26f8d5239..8a55eaf48 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java @@ -3,13 +3,10 @@ package cn.iocoder.yudao.module.product.dal.mysql.property; 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.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import org.apache.ibatis.annotations.Mapper; -import java.util.List; - @Mapper public interface ProductPropertyMapper extends BaseMapperX { @@ -24,9 +21,4 @@ public interface ProductPropertyMapper extends BaseMapperX { return selectOne(ProductPropertyDO::getName, name); } - default List selectList(ProductPropertyListReqVO listReqVO) { - return selectList(new LambdaQueryWrapperX() - .eqIfPresent(ProductPropertyDO::getName, listReqVO.getName())); - } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java index 6da00caf4..82bfc87fa 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java +++ b/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 { return update(null, updateWrapper); } - default List selectListByAlarmStock() { - return selectList(new QueryWrapper().apply("stock <= warn_stock")); - } - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java index 0448381fa..68f2d210f 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java +++ b/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; @@ -63,19 +59,7 @@ public interface ProductSpuMapper extends BaseMapperX { // 分类 .inIfPresent(ProductSpuDO::getCategoryId, categoryIds); // 上架状态 且有库存 - query.eq(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()).gt(ProductSpuDO::getStock, 0); - // 推荐类型的过滤条件 - if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) { - query.eq(ProductSpuDO::getRecommendHot, true); - } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_BENEFIT)) { - query.eq(ProductSpuDO::getRecommendBenefit, true); - } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_BEST)) { - query.eq(ProductSpuDO::getRecommendBest, true); - } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_NEW)) { - query.eq(ProductSpuDO::getRecommendNew, true); - } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) { - query.eq(ProductSpuDO::getRecommendGood, true); - } + query.eq(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()); // 排序逻辑 if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) { @@ -84,27 +68,15 @@ public interface ProductSpuMapper extends BaseMapperX { } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_PRICE)) { query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getPrice) .orderByDesc(ProductSpuDO::getSort).orderByDesc(ProductSpuDO::getId); + } else if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_CREATE_TIME)) { + query.orderBy(true, pageReqVO.getSortAsc(), ProductSpuDO::getCreateTime) + .orderByDesc(ProductSpuDO::getSort).orderByDesc(ProductSpuDO::getId); } else { query.orderByDesc(ProductSpuDO::getSort).orderByDesc(ProductSpuDO::getId); } return selectPage(pageReqVO, query); } - default List selectListByRecommendType(String recommendType, Integer count) { - QueryWrapperX 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 库存 * @@ -119,27 +91,11 @@ public interface ProductSpuMapper extends BaseMapperX { update(null, updateWrapper); } - /** - * 获得 Spu 列表 - * - * @param reqVO 查询条件 - * @return Spu 列表 - */ - default List selectList(ProductSpuExportReqVO reqVO) { - Integer tabType = reqVO.getTabType(); - LambdaQueryWrapperX 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 选项的查询条件 * - * @param tabType 标签类型 - * @param query 查询条件 + * @param tabType 标签类型 + * @param query 查询条件 */ static void appendTabQuery(Integer tabType, LambdaQueryWrapperX query) { // 出售中商品 @@ -166,4 +122,17 @@ public interface ProductSpuMapper extends BaseMapperX { } } + /** + * 更新商品 SPU 浏览量 + * + * @param id 商品 SPU 编号 + * @param incrCount 增加的数量 + */ + default void updateBrowseCount(Long id, int incrCount) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() + .setSql(" browse_count = browse_count +" + incrCount) + .eq(ProductSpuDO::getId, id); + update(null, updateWrapper); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java index a7ed6b4f4..3255c6df2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandService.java @@ -1,10 +1,13 @@ package cn.iocoder.yudao.module.product.service.brand; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; - import jakarta.validation.Valid; + import java.util.Collection; import java.util.List; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java index a3fc91834..0e83af56c 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/brand/ProductBrandServiceImpl.java @@ -10,10 +10,10 @@ import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert; import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO; import cn.iocoder.yudao.module.product.dal.mysql.brand.ProductBrandMapper; import com.google.common.annotations.VisibleForTesting; +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; diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java index 1079bfabb..5cacccdb5 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryService.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.product.service.category; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategorySaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; - import jakarta.validation.Valid; + import java.util.Collection; import java.util.List; @@ -22,14 +21,14 @@ public interface ProductCategoryService { * @param createReqVO 创建信息 * @return 编号 */ - Long createCategory(@Valid ProductCategoryCreateReqVO createReqVO); + Long createCategory(@Valid ProductCategorySaveReqVO createReqVO); /** * 更新商品分类 * * @param updateReqVO 更新信息 */ - void updateCategory(@Valid ProductCategoryUpdateReqVO updateReqVO); + void updateCategory(@Valid ProductCategorySaveReqVO updateReqVO); /** * 删除商品分类 @@ -67,7 +66,7 @@ public interface ProductCategoryService { * @param listReqVO 查询条件 * @return 商品分类列表 */ - List getEnableCategoryList(ProductCategoryListReqVO listReqVO); + List getCategoryList(ProductCategoryListReqVO listReqVO); /** * 获得开启状态的商品分类列表 @@ -76,6 +75,14 @@ public interface ProductCategoryService { */ List getEnableCategoryList(); + /** + * 获得开启状态的商品分类列表,指定编号 + * + * @param ids 商品分类编号数组 + * @return 商品分类列表 + */ + List getEnableCategoryList(List ids); + /** * 校验商品分类是否有效。如下情况,视为无效: * 1. 商品分类编号不存在 @@ -84,4 +91,5 @@ public interface ProductCategoryService { * @param ids 商品分类编号数组 */ void validateCategoryList(Collection ids); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java index 93c39374e..64b8a6127 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImpl.java @@ -3,18 +3,17 @@ package cn.iocoder.yudao.module.product.service.category; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert; +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategorySaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; 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.validation.annotation.Validated; -import jakarta.annotation.Resource; import java.util.Collection; import java.util.List; import java.util.Map; @@ -40,26 +39,26 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { private ProductSpuService productSpuService; @Override - public Long createCategory(ProductCategoryCreateReqVO createReqVO) { + public Long createCategory(ProductCategorySaveReqVO createReqVO) { // 校验父分类存在 validateParentProductCategory(createReqVO.getParentId()); // 插入 - ProductCategoryDO category = ProductCategoryConvert.INSTANCE.convert(createReqVO); + ProductCategoryDO category = BeanUtils.toBean(createReqVO, ProductCategoryDO.class); productCategoryMapper.insert(category); // 返回 return category.getId(); } @Override - public void updateCategory(ProductCategoryUpdateReqVO updateReqVO) { + public void updateCategory(ProductCategorySaveReqVO updateReqVO) { // 校验分类是否存在 validateProductCategoryExists(updateReqVO.getId()); // 校验父分类存在 validateParentProductCategory(updateReqVO.getParentId()); // 更新 - ProductCategoryDO updateObj = ProductCategoryConvert.INSTANCE.convert(updateReqVO); + ProductCategoryDO updateObj = BeanUtils.toBean(updateReqVO, ProductCategoryDO.class); productCategoryMapper.updateById(updateObj); } @@ -161,7 +160,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { } @Override - public List getEnableCategoryList(ProductCategoryListReqVO listReqVO) { + public List getCategoryList(ProductCategoryListReqVO listReqVO) { return productCategoryMapper.selectList(listReqVO); } @@ -170,4 +169,9 @@ public class ProductCategoryServiceImpl implements ProductCategoryService { return productCategoryMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); } + @Override + public List getEnableCategoryList(List ids) { + return productCategoryMapper.selectListByIdAndStatus(ids, CommonStatusEnum.ENABLE.getStatus()); + } + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java index e531f5513..b54e21918 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentService.java @@ -7,14 +7,10 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import java.util.List; - /** * 商品评论 Service 接口 * @@ -73,22 +69,4 @@ public interface ProductCommentService { */ PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible); - /** - * 获得商品的评价统计 - * - * @param spuId spu id - * @param visible 是否可见 - * @return 评价统计 - */ - AppCommentStatisticsRespVO getCommentStatistics(Long spuId, Boolean visible); - - /** - * 得到评论列表 - * - * @param spuId 商品 id - * @param count 数量 - * @return {@link Object} - */ - List getCommentList(Long spuId, Integer count); - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java index d49574f3e..5d3df8eff 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java @@ -9,8 +9,6 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppProductCommentRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; @@ -18,13 +16,12 @@ import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; 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.validation.annotation.Validated; -import jakarta.annotation.Resource; import java.time.LocalDateTime; -import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; @@ -54,28 +51,28 @@ public class ProductCommentServiceImpl implements ProductCommentService { @Override public void createComment(ProductCommentCreateReqVO createReqVO) { // 校验 SKU - ProductSkuDO skuDO = validateSku(createReqVO.getSkuId()); + ProductSkuDO sku = validateSku(createReqVO.getSkuId()); // 校验 SPU - ProductSpuDO spuDO = validateSpu(skuDO.getSpuId()); + ProductSpuDO spu = validateSpu(sku.getSpuId()); // 创建评论 - ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqVO, spuDO, skuDO); + ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqVO, spu, sku); productCommentMapper.insert(comment); } @Override public Long createComment(ProductCommentCreateReqDTO createReqDTO) { // 校验 SKU - ProductSkuDO skuDO = validateSku(createReqDTO.getSkuId()); + ProductSkuDO sku = validateSku(createReqDTO.getSkuId()); // 校验 SPU - ProductSpuDO spuDO = validateSpu(skuDO.getSpuId()); + ProductSpuDO spu = validateSpu(sku.getSpuId()); // 校验评论 validateCommentExists(createReqDTO.getUserId(), createReqDTO.getOrderId()); // 获取用户详细信息 MemberUserRespDTO user = memberUserApi.getUser(createReqDTO.getUserId()).getCheckedData(); // 创建评论 - ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqDTO, spuDO, skuDO, user); + ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqDTO, spu, sku, user); productCommentMapper.insert(comment); return comment.getId(); } @@ -137,23 +134,6 @@ public class ProductCommentServiceImpl implements ProductCommentService { return productComment; } - @Override - public AppCommentStatisticsRespVO getCommentStatistics(Long spuId, Boolean visible) { - return ProductCommentConvert.INSTANCE.convert( - // 查询商品 id = spuId 的所有好评数量 - productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.GOOD_COMMENT), - // 查询商品 id = spuId 的所有中评数量 - productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.MEDIOCRE_COMMENT), - // 查询商品 id = spuId 的所有差评数量 - productCommentMapper.selectCountBySpuId(spuId, visible, AppCommentPageReqVO.NEGATIVE_COMMENT) - ); - } - - @Override - public List getCommentList(Long spuId, Integer count) { - return ProductCommentConvert.INSTANCE.convertList02(productCommentMapper.selectCommentList(spuId, count).getList()); - } - @Override public PageResult getCommentPage(AppCommentPageReqVO pageVO, Boolean visible) { return productCommentMapper.selectPage(pageVO, visible); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java index ca93ba21b..410fe47a9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteService.java @@ -1,9 +1,9 @@ package cn.iocoder.yudao.module.product.service.favorite; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.favorite.vo.ProductFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; - import jakarta.validation.Valid; /** @@ -37,6 +37,13 @@ public interface ProductFavoriteService { */ PageResult getFavoritePage(Long userId, @Valid AppFavoritePageReqVO reqVO); + /** + * 分页查询用户收藏列表 + * + * @param reqVO 请求 vo + */ + PageResult getFavoritePage(@Valid ProductFavoritePageReqVO reqVO); + /** * 获取收藏过商品 * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java index 387869640..453420cbd 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/favorite/ProductFavoriteServiceImpl.java @@ -1,15 +1,15 @@ package cn.iocoder.yudao.module.product.service.favorite; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.favorite.vo.ProductFavoritePageReqVO; import cn.iocoder.yudao.module.product.controller.app.favorite.vo.AppFavoritePageReqVO; import cn.iocoder.yudao.module.product.convert.favorite.ProductFavoriteConvert; import cn.iocoder.yudao.module.product.dal.dataobject.favorite.ProductFavoriteDO; import cn.iocoder.yudao.module.product.dal.mysql.favorite.ProductFavoriteMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - import jakarta.annotation.Resource; import jakarta.validation.Valid; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.FAVORITE_EXISTS; @@ -54,6 +54,11 @@ public class ProductFavoriteServiceImpl implements ProductFavoriteService { return productFavoriteMapper.selectPageByUserAndType(userId, reqVO); } + @Override + public PageResult getFavoritePage(@Valid ProductFavoritePageReqVO reqVO) { + return productFavoriteMapper.selectPageByUserId(reqVO); + } + @Override public ProductFavoriteDO getFavorite(Long userId, Long spuId) { return productFavoriteMapper.selectByUserIdAndSpuId(userId, spuId); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryService.java new file mode 100644 index 000000000..10f3a71d5 --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryService.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.product.service.history; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO; +import org.springframework.scheduling.annotation.Async; + +import java.util.Collection; + +/** + * 商品浏览记录 Service 接口 + * + * @author owen + */ +public interface ProductBrowseHistoryService { + + /** + * 创建商品浏览记录 + * + * @param userId 用户编号 + * @param spuId SPU 编号 + */ + @Async + void createBrowseHistory(Long userId, Long spuId); + + /** + * 隐藏用户商品浏览记录 + * + * @param userId 用户编号 + * @param spuId SPU 编号 + */ + void hideUserBrowseHistory(Long userId, Collection spuId); + + /** + * 获得商品浏览记录分页 + * + * @param pageReqVO 分页查询 + * @return 商品浏览记录分页 + */ + PageResult getBrowseHistoryPage(ProductBrowseHistoryPageReqVO pageReqVO); + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryServiceImpl.java new file mode 100644 index 000000000..b0152995f --- /dev/null +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/history/ProductBrowseHistoryServiceImpl.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.module.product.service.history; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO; +import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO; +import cn.iocoder.yudao.module.product.dal.mysql.history.ProductBrowseHistoryMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.Collection; + +/** + * 商品浏览记录 Service 实现类 + * + * @author owen + */ +@Service +@Validated +public class ProductBrowseHistoryServiceImpl implements ProductBrowseHistoryService { + + private static final int USER_STORE_MAXIMUM = 100; + + @Resource + private ProductBrowseHistoryMapper browseHistoryMapper; + + @Override + public void createBrowseHistory(Long userId, Long spuId) { + // 用户未登录时不记录 + if (userId == null) { + return; + } + + // 情况一:同一个商品,只保留最新的一条记录 + ProductBrowseHistoryDO history = browseHistoryMapper.selectByUserIdAndSpuId(userId, spuId); + if (history != null) { + browseHistoryMapper.deleteById(history); + } else { + // 情况二:限制每个用户的浏览记录的条数(只查一条最早地记录、记录总数) + // TODO @疯狂:这里最好先查询一次数量。如果发现超过了,再删除;主要考虑,可能有部分不超过,提前就多了一次 sql 查询了 + Page pageResult = browseHistoryMapper.selectPageByUserIdOrderByCreateTimeAsc(userId, 1, 1); + if (pageResult.getTotal() >= USER_STORE_MAXIMUM) { + browseHistoryMapper.deleteById(CollUtil.getFirst(pageResult.getRecords())); + } + } + + // 插入 + ProductBrowseHistoryDO browseHistory = new ProductBrowseHistoryDO() + .setUserId(userId) + .setSpuId(spuId); + browseHistoryMapper.insert(browseHistory); + } + + @Override + public void hideUserBrowseHistory(Long userId, Collection spuIds) { + browseHistoryMapper.updateUserDeletedByUserId(userId, spuIds, true); + } + + @Override + public PageResult getBrowseHistoryPage(ProductBrowseHistoryPageReqVO pageReqVO) { + return browseHistoryMapper.selectPage(pageReqVO); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java index d9417ee4c..6eb939264 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyService.java @@ -1,10 +1,11 @@ package cn.iocoder.yudao.module.product.service.property; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertySaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; - import jakarta.validation.Valid; + import java.util.Collection; import java.util.List; @@ -22,14 +23,14 @@ public interface ProductPropertyService { * @param createReqVO 创建信息 * @return 编号 */ - Long createProperty(@Valid ProductPropertyCreateReqVO createReqVO); + Long createProperty(@Valid ProductPropertySaveReqVO createReqVO); /** * 更新属性项 * * @param updateReqVO 更新信息 */ - void updateProperty(@Valid ProductPropertyUpdateReqVO updateReqVO); + void updateProperty(@Valid ProductPropertySaveReqVO updateReqVO); /** * 删除属性项 @@ -38,14 +39,6 @@ public interface ProductPropertyService { */ void deleteProperty(Long id); - /** - * 获得属性项列表 - * - * @param listReqVO 集合查询 - * @return 属性项集合 - */ - List getPropertyList(ProductPropertyListReqVO listReqVO); - /** * 获取属性名称分页 * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java index cafebe3c3..4747b1703 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyServiceImpl.java @@ -2,20 +2,18 @@ package cn.iocoder.yudao.module.product.service.property; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertySaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO; import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyMapper; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +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.Collection; import java.util.List; @@ -43,7 +41,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @Override @Transactional(rollbackFor = Exception.class) - public Long createProperty(ProductPropertyCreateReqVO createReqVO) { + public Long createProperty(ProductPropertySaveReqVO createReqVO) { // 如果已经添加过该属性项,直接返回 ProductPropertyDO dbProperty = productPropertyMapper.selectByName(createReqVO.getName()); if (dbProperty != null) { @@ -51,7 +49,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { } // 插入 - ProductPropertyDO property = ProductPropertyConvert.INSTANCE.convert(createReqVO); + ProductPropertyDO property = BeanUtils.toBean(createReqVO, ProductPropertyDO.class); productPropertyMapper.insert(property); // 返回 return property.getId(); @@ -59,17 +57,17 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { @Override @Transactional(rollbackFor = Exception.class) - public void updateProperty(ProductPropertyUpdateReqVO updateReqVO) { + public void updateProperty(ProductPropertySaveReqVO updateReqVO) { validatePropertyExists(updateReqVO.getId()); // 校验名字重复 - ProductPropertyDO productPropertyDO = productPropertyMapper.selectByName(updateReqVO.getName()); - if (productPropertyDO != null && - ObjUtil.notEqual(productPropertyDO.getId(), updateReqVO.getId())) { + ProductPropertyDO property = productPropertyMapper.selectByName(updateReqVO.getName()); + if (property != null && + ObjUtil.notEqual(property.getId(), updateReqVO.getId())) { throw exception(PROPERTY_EXISTS); } // 更新 - ProductPropertyDO updateObj = ProductPropertyConvert.INSTANCE.convert(updateReqVO); + ProductPropertyDO updateObj = BeanUtils.toBean(updateReqVO, ProductPropertyDO.class); productPropertyMapper.updateById(updateObj); // 更新 sku 相关属性 productSkuService.updateSkuProperty(updateObj.getId(), updateObj.getName()); @@ -96,11 +94,6 @@ public class ProductPropertyServiceImpl implements ProductPropertyService { } } - @Override - public List getPropertyList(ProductPropertyListReqVO listReqVO) { - return productPropertyMapper.selectList(listReqVO); - } - @Override public PageResult getPropertyPage(ProductPropertyPageReqVO pageReqVO) { return productPropertyMapper.selectPage(pageReqVO); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java index 29f5e55ec..aaa7ff12a 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java @@ -1,9 +1,8 @@ package cn.iocoder.yudao.module.product.service.property; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueSaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import java.util.Collection; @@ -23,14 +22,14 @@ public interface ProductPropertyValueService { * @param createReqVO 创建信息 * @return 编号 */ - Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO); + Long createPropertyValue(ProductPropertyValueSaveReqVO createReqVO); /** * 更新属性值 * * @param updateReqVO 更新信息 */ - void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO); + void updatePropertyValue(ProductPropertyValueSaveReqVO updateReqVO); /** * 删除属性值 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java index 632aa8f84..12934586e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java @@ -1,18 +1,17 @@ package cn.iocoder.yudao.module.product.service.property; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO; -import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO; -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyValueConvert; +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueSaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO; import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; +import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; import java.util.Collection; import java.util.List; @@ -37,7 +36,7 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ private ProductSkuService productSkuService; @Override - public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) { + public Long createPropertyValue(ProductPropertyValueSaveReqVO createReqVO) { // 如果已经添加过该属性值,直接返回 ProductPropertyValueDO dbValue = productPropertyValueMapper.selectByName( createReqVO.getPropertyId(), createReqVO.getName()); @@ -46,23 +45,23 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ } // 新增 - ProductPropertyValueDO value = ProductPropertyValueConvert.INSTANCE.convert(createReqVO); + ProductPropertyValueDO value = BeanUtils.toBean(createReqVO, ProductPropertyValueDO.class); productPropertyValueMapper.insert(value); return value.getId(); } @Override - public void updatePropertyValue(ProductPropertyValueUpdateReqVO updateReqVO) { + public void updatePropertyValue(ProductPropertyValueSaveReqVO updateReqVO) { validatePropertyValueExists(updateReqVO.getId()); // 校验名字唯一 - ProductPropertyValueDO productPropertyValueDO = productPropertyValueMapper.selectByName + ProductPropertyValueDO value = productPropertyValueMapper.selectByName (updateReqVO.getPropertyId(), updateReqVO.getName()); - if (productPropertyValueDO != null && !productPropertyValueDO.getId().equals(updateReqVO.getId())) { + if (value != null && !value.getId().equals(updateReqVO.getId())) { throw exception(PROPERTY_VALUE_EXISTS); } // 更新 - ProductPropertyValueDO updateObj = ProductPropertyValueConvert.INSTANCE.convert(updateReqVO); + ProductPropertyValueDO updateObj = BeanUtils.toBean(updateReqVO, ProductPropertyValueDO.class); productPropertyValueMapper.updateById(updateObj); // 更新 sku 相关属性 productSkuService.updateSkuPropertyValue(updateObj.getId(), updateObj.getName()); diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java index fbc9830bf..a6d3f02b5 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuService.java +++ b/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 getSkuList(); - /** * 获得商品 SKU 列表 * @@ -49,7 +42,7 @@ public interface ProductSkuService { * * @param list sku组合的集合 */ - void validateSkuList(List list, Boolean specType); + void validateSkuList(List list, Boolean specType); /** * 批量创建 SKU @@ -57,7 +50,7 @@ public interface ProductSkuService { * @param spuId 商品 SPU 编号 * @param list SKU 对象集合 */ - void createSkuList(Long spuId, List list); + void createSkuList(Long spuId, List list); /** * 根据 SPU 编号,批量更新它的 SKU 信息 @@ -65,7 +58,7 @@ public interface ProductSkuService { * @param spuId SPU 编码 * @param skus SKU 的集合 */ - void updateSkuList(Long spuId, List skus); + void updateSkuList(Long spuId, List skus); /** * 更新 SKU 库存(增量) @@ -99,13 +92,6 @@ public interface ProductSkuService { */ void deleteSkuBySpuId(Long spuId); - /** - * 获得库存预警的 SKU 数组 - * - * @return SKU 数组 - */ - List getSkuListByAlarmStock(); - /** * 更新 sku 属性 * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java index 693c574de..753ff06c9 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java +++ b/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 getSkuList() { - return productSkuMapper.selectList(); - } - @Override public List getSkuList(Collection ids) { if (CollUtil.isEmpty(ids)) { @@ -82,20 +77,18 @@ public class ProductSkuServiceImpl implements ProductSkuService { } @Override - public void validateSkuList(List skus, Boolean specType) { + public void validateSkuList(List 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 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 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 propertyList = productPropertyService.getPropertyList(propertyIds); if (propertyList.size() != propertyIds.size()) { @@ -133,17 +126,18 @@ public class ProductSkuServiceImpl implements ProductSkuService { // 4. 最后校验,每个 Sku 之间不是重复的 // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. Set> 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 skuCreateReqList) { - productSkuMapper.insertBatch(ProductSkuConvert.INSTANCE.convertList06(skuCreateReqList, spuId)); + public void createSkuList(Long spuId, List skuCreateReqList) { + List 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 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 skus) { + public void updateSkuList(Long spuId, List skus) { // 构建属性与 SKU 的映射关系; Map existsSkuMap = convertMap(productSkuMapper.selectListBySpuId(spuId), ProductSkuConvert.INSTANCE::buildPropertyKey, ProductSkuDO::getId); @@ -228,7 +217,7 @@ public class ProductSkuServiceImpl implements ProductSkuService { // 拆分三个集合,新插入的、需要更新的、需要删除的 List insertSkus = new ArrayList<>(); List updateSkus = new ArrayList<>(); - List allUpdateSkus = ProductSkuConvert.INSTANCE.convertList06(skus, spuId); + List allUpdateSkus = BeanUtils.toBean(skus, ProductSkuDO.class, sku -> sku.setSpuId(spuId)); allUpdateSkus.forEach(sku -> { String propertiesKey = ProductSkuConvert.INSTANCE.buildPropertyKey(sku); // 1、找得到的,进行更新 diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java index 513f9c36d..c288a76ca 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java @@ -1,17 +1,18 @@ 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; + 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 接口 * @@ -25,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 @@ -57,16 +58,6 @@ public interface ProductSpuService { */ List getSpuList(Collection ids); - /** - * 获得商品 SPU 映射 - * - * @param ids 编号数组 - * @return 商品 SPU 映射 - */ - default Map getSpuMap(Collection ids) { - return convertMap(getSpuList(ids), ProductSpuDO::getId); - } - /** * 获得指定状态的商品 SPU 列表 * @@ -75,14 +66,6 @@ public interface ProductSpuService { */ List getSpuListByStatus(Integer status); - /** - * 获得所有商品 SPU 列表 - * - * @param reqVO 导出条件 - * @return 商品 SPU 列表 - */ - List getSpuList(ProductSpuExportReqVO reqVO); - /** * 获得商品 SPU 分页,提供给挂你兰后台使用 * @@ -99,15 +82,6 @@ public interface ProductSpuService { */ PageResult getSpuPage(AppProductSpuPageReqVO pageReqVO); - /** - * 获得商品 SPU 列表,提供给用户 App 使用 - * - * @param recommendType 推荐类型 - * @param count 数量 - * @return 商品 SPU 列表 - */ - List getSpuList(String recommendType, Integer count); - /** * 更新商品 SPU 库存(增量) * @@ -148,4 +122,13 @@ public interface ProductSpuService { */ List validateSpuList(Collection ids); + /** + * 更新商品 SPU 浏览量 + * + * @param id 商品 SPU 编号 + * @param incrCount 增加的数量 + */ + @Async + void updateBrowseCount(Long id, int incrCount); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java index 28fad734e..9986c7e61 100755 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java +++ b/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; @@ -18,12 +20,12 @@ import cn.iocoder.yudao.module.product.service.brand.ProductBrandService; import cn.iocoder.yudao.module.product.service.category.ProductCategoryService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import com.google.common.collect.Maps; +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 static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -51,28 +53,19 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Resource private ProductCategoryService categoryService; -// @Resource -// @Lazy -// private CouponTemplateApi couponTemplateApi; - @Override @Transactional(rollbackFor = Exception.class) - public Long createSpu(ProductSpuCreateReqVO createReqVO) { + public Long createSpu(ProductSpuSaveReqVO createReqVO) { // 校验分类、品牌 validateCategory(createReqVO.getCategoryId()); brandService.validateProductBrand(createReqVO.getBrandId()); - // 校验优惠券 - Set giveCouponTemplateIds = convertSet(createReqVO.getGiveCouponTemplates(), ProductSpuCreateReqVO.GiveCouponTemplate::getId); -// validateCouponTemplate(giveCouponTemplateIds); // 校验 SKU - List skuSaveReqList = createReqVO.getSkus(); + List 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.setGiveCouponTemplateIds(CollUtil.newArrayList(giveCouponTemplateIds)); // 插入 SPU productSpuMapper.insert(spu); // 插入 SKU @@ -83,24 +76,19 @@ 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()); - // 校验优惠券 - Set giveCouponTemplateIds = convertSet(updateReqVO.getGiveCouponTemplates(), ProductSpuUpdateReqVO.GiveCouponTemplate::getId); -// validateCouponTemplate(giveCouponTemplateIds); // 校验SKU - List skuSaveReqList = updateReqVO.getSkus(); + List 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); - // 设置优惠券 - updateObj.setGiveCouponTemplateIds(CollUtil.newArrayList(giveCouponTemplateIds)); productSpuMapper.updateById(updateObj); // 批量更新 SKU productSkuService.updateSkuList(updateObj.getId(), updateReqVO.getSkus()); @@ -113,32 +101,21 @@ public class ProductSpuServiceImpl implements ProductSpuService { * @param spu 商品 SPU * @param skus 商品 SKU 数组 */ - private void initSpuFromSkus(ProductSpuDO spu, List skus) { + private void initSpuFromSkus(ProductSpuDO spu, List 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); // 默认商品浏览量 } - // 如果活动顺序为空则默认初始化 - // TODO 芋艿:后续再优化 -// if (CollUtil.isEmpty(spu.getActivityOrders())) { -// spu.setActivityOrders(Arrays.stream(PromotionTypeEnum.ARRAYS).boxed().collect(Collectors.toList())); -// } } /** @@ -154,13 +131,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { } } -// private void validateCouponTemplate(Collection ids) { -// List couponTemplateList = couponTemplateApi.getCouponTemplateListByIds(ids); -// if (couponTemplateList.size() != ids.size()) { -// throw exception(SPU_SAVE_FAIL_COUPON_TEMPLATE_NOT_EXISTS); -// } -// } - @Override public List validateSpuList(Collection ids) { if (CollUtil.isEmpty(ids)) { @@ -182,6 +152,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { return list; } + @Override + public void updateBrowseCount(Long id, int incrCount) { + productSpuMapper.updateBrowseCount(id , incrCount); + } + @Override @Transactional(rollbackFor = Exception.class) public void deleteSpu(Long id) { @@ -193,6 +168,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { if (ObjectUtil.notEqual(spuDO.getStatus(), ProductSpuStatusEnum.RECYCLE.getStatus())) { throw exception(SPU_NOT_RECYCLE); } + // TODO 芋艿:【可选】参与活动中的商品,不允许删除??? // 删除 SPU productSpuMapper.deleteById(id); @@ -224,11 +200,6 @@ public class ProductSpuServiceImpl implements ProductSpuService { return productSpuMapper.selectList(ProductSpuDO::getStatus, status); } - @Override - public List getSpuList(ProductSpuExportReqVO reqVO) { - return productSpuMapper.selectList(reqVO); - } - @Override public PageResult getSpuPage(ProductSpuPageReqVO pageReqVO) { return productSpuMapper.selectPage(pageReqVO); @@ -240,19 +211,20 @@ public class ProductSpuServiceImpl implements ProductSpuService { Set categoryIds = new HashSet<>(); if (pageReqVO.getCategoryId() != null && pageReqVO.getCategoryId() > 0) { categoryIds.add(pageReqVO.getCategoryId()); - List categoryChildren = categoryService.getEnableCategoryList(new ProductCategoryListReqVO() - .setParentId(pageReqVO.getCategoryId()).setStatus(CommonStatusEnum.ENABLE.getStatus())); - categoryIds.addAll(CollectionUtils.convertList(categoryChildren, ProductCategoryDO::getId)); + List categoryChildren = categoryService.getCategoryList(new ProductCategoryListReqVO() + .setStatus(CommonStatusEnum.ENABLE.getStatus()).setParentId(pageReqVO.getCategoryId())); + categoryIds.addAll(convertList(categoryChildren, ProductCategoryDO::getId)); + } + if (CollUtil.isNotEmpty(pageReqVO.getCategoryIds())) { + categoryIds.addAll(pageReqVO.getCategoryIds()); + List categoryChildren = categoryService.getCategoryList(new ProductCategoryListReqVO() + .setStatus(CommonStatusEnum.ENABLE.getStatus()).setParentIds(pageReqVO.getCategoryIds())); + categoryIds.addAll(convertList(categoryChildren, ProductCategoryDO::getId)); } // 分页查询 return productSpuMapper.selectPage(pageReqVO, categoryIds); } - @Override - public List getSpuList(String recommendType, Integer count) { - return productSpuMapper.selectListByRecommendType(recommendType, count); - } - @Override @Transactional(rollbackFor = Exception.class) public void updateSpuStock(Map stockIncrCounts) { @@ -264,6 +236,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { public void updateSpuStatus(ProductSpuUpdateStatusReqVO updateReqVO) { // 校验存在 validateSpuExists(updateReqVO.getId()); + // TODO 芋艿:【可选】参与活动中的商品,不允许下架??? // 更新状态 ProductSpuDO productSpuDO = productSpuMapper.selectById(updateReqVO.getId()).setStatus(updateReqVO.getStatus()); diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/ProductStatisticsController.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/ProductStatisticsController.java index 4e5684fb9..c1eb5ed99 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/ProductStatisticsController.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/ProductStatisticsController.java @@ -2,40 +2,86 @@ package cn.iocoder.yudao.module.statistics.controller.admin.product; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.statistics.dal.mysql.product.ProductSpuStatisticsDO; -import cn.iocoder.yudao.module.statistics.dal.mysql.product.ProductStatisticsDO; +import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; +import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsReqVO; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO; +import cn.iocoder.yudao.module.statistics.dal.dataobject.product.ProductStatisticsDO; +import cn.iocoder.yudao.module.statistics.service.product.ProductStatisticsService; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.extern.slf4j.Slf4j; +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.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.time.LocalDateTime; +import java.io.IOException; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @Tag(name = "管理后台 - 商品统计") @RestController @RequestMapping("/statistics/product") @Validated -@Slf4j public class ProductStatisticsController { - // TODO @麦子:返回 ProductStatisticsComparisonResp, 里面有两个字段,一个是选择的时间范围的合计结果,一个是对比的时间范围的合计结果; - // 例如说,选择时间范围是 2023-10-01 ~ 2023-10-02,那么对比就是 2023-09-30,再倒推 2 天; - public CommonResult getProductStatisticsComparison() { - return null; + @Resource + private ProductStatisticsService productStatisticsService; + + @Resource + private ProductSpuApi productSpuApi; + + @GetMapping("/analyse") + @Operation(summary = "获得商品统计分析") + @PreAuthorize("@ss.hasPermission('statistics:product:query')") + public CommonResult> getProductStatisticsAnalyse(ProductStatisticsReqVO reqVO) { + return success(productStatisticsService.getProductStatisticsAnalyse(reqVO)); } - // TODO @麦子:查询指定时间范围内的商品统计数据;DO 到时需要改成 VO 哈 - public CommonResult> getProductStatisticsList( - LocalDateTime[] times) { - return null; + @GetMapping("/list") + @Operation(summary = "获得商品统计明细(日期维度)") + @PreAuthorize("@ss.hasPermission('statistics:product:query')") + public CommonResult> getProductStatisticsList(ProductStatisticsReqVO reqVO) { + List list = productStatisticsService.getProductStatisticsList(reqVO); + return success(BeanUtils.toBean(list, ProductStatisticsRespVO.class)); } - // TODO @麦子:查询指定时间范围内的商品 SPU 统计数据;DO 到时需要改成 VO 哈 - // 入参是分页参数 + 时间范围 + 排序字段 - public CommonResult> getProductSpuStatisticsPage() { - return null; + @GetMapping("/export-excel") + @Operation(summary = "导出获得商品统计明细 Excel(日期维度)") + @PreAuthorize("@ss.hasPermission('statistics:product:export')") + public void exportProductStatisticsExcel(ProductStatisticsReqVO reqVO, HttpServletResponse response) throws IOException { + List list = productStatisticsService.getProductStatisticsList(reqVO); + // 导出 Excel + List voList = BeanUtils.toBean(list, ProductStatisticsRespVO.class); + ExcelUtils.write(response, "商品状况.xls", "数据", ProductStatisticsRespVO.class, voList); } -} + @GetMapping("/rank-page") + @Operation(summary = "获得商品统计排行榜分页(商品维度)") + @PreAuthorize("@ss.hasPermission('statistics:product:query')") + public CommonResult> getProductStatisticsRankPage(@Valid ProductStatisticsReqVO reqVO, + @Valid SortablePageParam pageParam) { + PageResult pageResult = productStatisticsService.getProductStatisticsRankPage(reqVO, pageParam); + // 处理商品信息 + Set spuIds = convertSet(pageResult.getList(), ProductStatisticsDO::getSpuId); + Map spuMap = convertMap(productSpuApi.getSpuList(spuIds).getCheckedData(), ProductSpuRespDTO::getId); + return success(BeanUtils.toBean(pageResult, ProductStatisticsRespVO.class, + item -> Optional.ofNullable(spuMap.get(item.getSpuId())) + .ifPresent(spu -> item.setName(spu.getName()).setPicUrl(spu.getPicUrl())))); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsReqVO.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsReqVO.java new file mode 100644 index 000000000..02387c32f --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsReqVO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.statistics.controller.admin.product.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; +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 = "管理后台 - 商品统计分析 Request VO") +@Data +@ToString(callSuper = true) +@AllArgsConstructor +@NoArgsConstructor +public class ProductStatisticsReqVO { + + @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[] times; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsRespVO.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsRespVO.java new file mode 100644 index 000000000..9d93142e3 --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/product/vo/ProductStatisticsRespVO.java @@ -0,0 +1,81 @@ +package cn.iocoder.yudao.module.statistics.controller.admin.product.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDate; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; + +@Schema(description = "管理后台 - 商品统计 Response VO") +@Data +@ExcelIgnoreUnannotated +public class ProductStatisticsRespVO { + + @Schema(description = "编号,主键自增", requiredMode = Schema.RequiredMode.REQUIRED, example = "12393") + private Long id; + + @Schema(description = "统计日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-12-16") + @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY) + @ExcelProperty("统计日期") + private LocalDate time; + + @Schema(description = "商品SPU编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15114") + @ExcelProperty("商品SPU编号") + private Long spuId; + + // region 商品信息 + + @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "商品名称") + @ExcelProperty("商品名称") + private String name; + + @Schema(description = "商品封面图", requiredMode = Schema.RequiredMode.REQUIRED, example = "15114") + @ExcelProperty("商品封面图") + private String picUrl; + + // endregion + + @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "17505") + @ExcelProperty("浏览量") + private Integer browseCount; + + @Schema(description = "访客量", requiredMode = Schema.RequiredMode.REQUIRED, example = "11814") + @ExcelProperty("访客量") + private Integer browseUserCount; + + @Schema(description = "收藏数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20950") + @ExcelProperty("收藏数量") + private Integer favoriteCount; + + @Schema(description = "加购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "28493") + @ExcelProperty("加购数量") + private Integer cartCount; + + @Schema(description = "下单件数", requiredMode = Schema.RequiredMode.REQUIRED, example = "18966") + @ExcelProperty("下单件数") + private Integer orderCount; + + @Schema(description = "支付件数", requiredMode = Schema.RequiredMode.REQUIRED, example = "15142") + @ExcelProperty("支付件数") + private Integer orderPayCount; + + @Schema(description = "支付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "11595") + @ExcelProperty("支付金额,单位:分") + private Integer orderPayPrice; + + @Schema(description = "退款件数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2591") + @ExcelProperty("退款件数") + private Integer afterSaleCount; + + @Schema(description = "退款金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "21709") + @ExcelProperty("退款金额,单位:分") + private Integer afterSaleRefundPrice; + + @Schema(description = "访客支付转化率(百分比)", requiredMode = Schema.RequiredMode.REQUIRED, example = "15") + private Integer browseConvertPercent; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java index 0b304e0a3..43814da20 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/TradeStatisticsController.java @@ -18,6 +18,9 @@ import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; @@ -25,9 +28,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; import java.io.IOException; import java.util.List; @@ -49,7 +49,6 @@ public class TradeStatisticsController { @Resource private BrokerageStatisticsService brokerageStatisticsService; - // TODO 芋艿:已经 review @GetMapping("/summary") @Operation(summary = "获得交易统计") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") @@ -67,17 +66,14 @@ public class TradeStatisticsController { return success(TradeStatisticsConvert.INSTANCE.convert(yesterdayData, beforeYesterdayData, monthData, lastMonthData)); } - // TODO @疯狂:【晚点再改和讨论;等首页的接口出来】这个要不还是叫 analyse,对比选中的时间段,和上一个时间段;类似 MemberStatisticsController 的 getMemberAnalyse - @GetMapping("/trend/summary") + @GetMapping("/analyse") @Operation(summary = "获得交易状况统计") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") - public CommonResult> getTradeTrendSummaryComparison( - TradeTrendReqVO reqVO) { - return success(tradeStatisticsService.getTradeTrendSummaryComparison(ArrayUtil.get(reqVO.getTimes(), 0), + public CommonResult> getTradeStatisticsAnalyse(TradeTrendReqVO reqVO) { + return success(tradeStatisticsService.getTradeStatisticsAnalyse(ArrayUtil.get(reqVO.getTimes(), 0), ArrayUtil.get(reqVO.getTimes(), 1))); } - // TODO 芋艿:已经 review @GetMapping("/list") @Operation(summary = "获得交易状况明细") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") @@ -87,7 +83,6 @@ public class TradeStatisticsController { return success(TradeStatisticsConvert.INSTANCE.convertList(list)); } - // TODO 芋艿:已经 review @GetMapping("/export-excel") @Operation(summary = "导出获得交易状况明细 Excel") @PreAuthorize("@ss.hasPermission('statistics:trade:export')") @@ -100,7 +95,6 @@ public class TradeStatisticsController { ExcelUtils.write(response, "交易状况.xls", "数据", TradeTrendSummaryExcelVO.class, data); } - // TODO 芋艿:已经 review @GetMapping("/order-count") @Operation(summary = "获得交易订单数量") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") @@ -118,7 +112,6 @@ public class TradeStatisticsController { return success(TradeStatisticsConvert.INSTANCE.convert(undeliveredCount, pickUpCount, afterSaleApplyCount, auditingWithdrawCount)); } - // TODO 芋艿:已经 review @GetMapping("/order-comparison") @Operation(summary = "获得交易订单数量") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") @@ -126,7 +119,6 @@ public class TradeStatisticsController { return success(tradeOrderStatisticsService.getOrderComparison()); } - // TODO 芋艿:已经 review @GetMapping("/order-count-trend") @Operation(summary = "获得订单量趋势统计") @PreAuthorize("@ss.hasPermission('statistics:trade:query')") diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/vo/TradeTrendSummaryRespVO.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/vo/TradeTrendSummaryRespVO.java index f76d02e91..be5a93a51 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/vo/TradeTrendSummaryRespVO.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/controller/admin/trade/vo/TradeTrendSummaryRespVO.java @@ -12,7 +12,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @Data public class TradeTrendSummaryRespVO { - @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-12-16") @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY) private LocalDate date; diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/product/ProductStatisticsDO.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/product/ProductStatisticsDO.java new file mode 100644 index 000000000..426906d47 --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/product/ProductStatisticsDO.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.statistics.dal.dataobject.product; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.time.LocalDate; + +/** + * 商品统计 DO + * + * @author owen + */ +@TableName("product_statistics") +@KeySequence("product_statistics_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ProductStatisticsDO extends BaseDO { + + /** + * 编号,主键自增 + */ + @TableId + private Long id; + /** + * 统计日期 + */ + private LocalDate time; + /** + * 商品 SPU 编号 + */ + private Long spuId; + /** + * 浏览量 + */ + private Integer browseCount; + /** + * 访客量 + */ + private Integer browseUserCount; + /** + * 收藏数量 + */ + private Integer favoriteCount; + /** + * 加购数量 + */ + private Integer cartCount; + /** + * 下单件数 + */ + private Integer orderCount; + /** + * 支付件数 + */ + private Integer orderPayCount; + /** + * 支付金额,单位:分 + */ + private Integer orderPayPrice; + /** + * 退款件数 + */ + private Integer afterSaleCount; + /** + * 退款金额,单位:分 + */ + private Integer afterSaleRefundPrice; + /** + * 访客支付转化率(百分比) + */ + private Integer browseConvertPercent; + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/product/ProductStatisticsMapper.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/product/ProductStatisticsMapper.java new file mode 100644 index 000000000..4cf10f102 --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/product/ProductStatisticsMapper.java @@ -0,0 +1,80 @@ +package cn.iocoder.yudao.module.statistics.dal.mysql.product; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; +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.MPJLambdaWrapperX; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsReqVO; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO; +import cn.iocoder.yudao.module.statistics.dal.dataobject.product.ProductStatisticsDO; +import com.baomidou.mybatisplus.core.metadata.IPage; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 商品统计 Mapper + * + * @author owen + */ +@Mapper +public interface ProductStatisticsMapper extends BaseMapperX { + + default PageResult selectPageGroupBySpuId(ProductStatisticsReqVO reqVO, SortablePageParam pageParam) { + return selectPage(pageParam, buildWrapper(reqVO) + .groupBy(ProductStatisticsDO::getSpuId) + .select(ProductStatisticsDO::getSpuId) + ); + } + + default List selectListByTimeBetween(ProductStatisticsReqVO reqVO) { + return selectList(buildWrapper(reqVO) + .groupBy(ProductStatisticsDO::getTime) + .select(ProductStatisticsDO::getTime)); + } + + default ProductStatisticsRespVO selectVoByTimeBetween(ProductStatisticsReqVO reqVO) { + return selectJoinOne(ProductStatisticsRespVO.class, buildWrapper(reqVO)); + } + + /** + * 构建 LambdaWrapper + * + * @param reqVO 查询参数 + * @return LambdaWrapper + */ + private static MPJLambdaWrapperX buildWrapper(ProductStatisticsReqVO reqVO) { + return new MPJLambdaWrapperX() + .betweenIfPresent(ProductStatisticsDO::getTime, reqVO.getTimes()) + .selectSum(ProductStatisticsDO::getBrowseCount) + .selectSum(ProductStatisticsDO::getBrowseUserCount) + .selectSum(ProductStatisticsDO::getFavoriteCount) + .selectSum(ProductStatisticsDO::getCartCount) + .selectSum(ProductStatisticsDO::getOrderCount) + .selectSum(ProductStatisticsDO::getOrderPayCount) + .selectSum(ProductStatisticsDO::getOrderPayPrice) + .selectSum(ProductStatisticsDO::getAfterSaleCount) + .selectSum(ProductStatisticsDO::getAfterSaleRefundPrice) + .selectAvg(ProductStatisticsDO::getBrowseConvertPercent); + } + + /** + * 根据时间范围统计商品信息 + * + * @param page 分页参数 + * @param beginTime 起始时间 + * @param endTime 截止时间 + * @return 统计 + */ + IPage selectStatisticsResultPageByTimeBetween(IPage page, + @Param("beginTime") LocalDateTime beginTime, + @Param("endTime") LocalDateTime endTime); + + default Long selectCountByTimeBetween(LocalDateTime beginTime, LocalDateTime endTime) { + return selectCount(new LambdaQueryWrapperX().between(ProductStatisticsDO::getTime, beginTime, endTime)); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/framework/rpc/config/RpcConfiguration.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/framework/rpc/config/RpcConfiguration.java new file mode 100644 index 000000000..6c613ecfe --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/framework/rpc/config/RpcConfiguration.java @@ -0,0 +1,10 @@ +package cn.iocoder.yudao.module.statistics.framework.rpc.config; + +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +@EnableFeignClients(clients = {ProductSpuApi.class}) +public class RpcConfiguration { +} diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/framework/rpc/package-info.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/framework/rpc/package-info.java new file mode 100644 index 000000000..ead659f46 --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/framework/rpc/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.statistics.framework.rpc; diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/job/product/ProductStatisticsJob.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/job/product/ProductStatisticsJob.java new file mode 100644 index 000000000..f360f080c --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/job/product/ProductStatisticsJob.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.statistics.job.product; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; +import cn.iocoder.yudao.module.statistics.service.product.ProductStatisticsService; +import com.xxl.job.core.handler.annotation.XxlJob; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +// TODO 芋艿:缺个 Job 的配置;等和 Product 一起配置 + +/** + * 商品统计 Job + * + * @author owen + */ +@Component +public class ProductStatisticsJob { + + @Resource + private ProductStatisticsService productStatisticsService; + + /** + * 执行商品统计任务 + * + * @param param 要统计的天数,只能是正整数,1 代表昨日数据 + * @return 统计结果 + */ + @XxlJob("productStatisticsJob") + @TenantJob + public String execute(String param) { + // 默认昨日 + param = ObjUtil.defaultIfBlank(param, "1"); + // 校验参数的合理性 + if (!NumberUtil.isInteger(param)) { + throw new RuntimeException("商品统计任务的参数只能为是正整数"); + } + Integer days = Convert.toInt(param, 0); + if (days < 1) { + throw new RuntimeException("商品统计任务的参数只能为是正整数"); + } + String result = productStatisticsService.statisticsProduct(days); + return StrUtil.format("商品统计:\n{}", result); + } + +} diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/pay/PayWalletStatisticsServiceImpl.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/pay/PayWalletStatisticsServiceImpl.java index 7c5cba0fe..4774a0658 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/pay/PayWalletStatisticsServiceImpl.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/pay/PayWalletStatisticsServiceImpl.java @@ -1,8 +1,8 @@ package cn.iocoder.yudao.module.statistics.service.pay; +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; -import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.statistics.dal.mysql.pay.PayWalletStatisticsMapper; import cn.iocoder.yudao.module.statistics.service.pay.bo.RechargeSummaryRespBO; import cn.iocoder.yudao.module.statistics.service.trade.bo.WalletSummaryRespBO; diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/product/ProductStatisticsService.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/product/ProductStatisticsService.java new file mode 100644 index 000000000..09d84bdea --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/product/ProductStatisticsService.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.statistics.service.product; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; +import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsReqVO; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO; +import cn.iocoder.yudao.module.statistics.dal.dataobject.product.ProductStatisticsDO; + +import java.util.List; + +/** + * 商品统计 Service 接口 + * + * @author owen + */ +public interface ProductStatisticsService { + + /** + * 获得商品统计排行榜分页 + * + * @param reqVO 查询条件 + * @param pageParam 分页排序查询 + * @return 商品统计分页 + */ + PageResult getProductStatisticsRankPage(ProductStatisticsReqVO reqVO, SortablePageParam pageParam); + + /** + * 获得商品状况统计分析 + * + * @param reqVO 查询条件 + * @return 统计数据对照 + */ + DataComparisonRespVO getProductStatisticsAnalyse(ProductStatisticsReqVO reqVO); + + /** + * 获得商品状况明细 + * + * @param reqVO 查询条件 + * @return 统计数据对照 + */ + List getProductStatisticsList(ProductStatisticsReqVO reqVO); + + /** + * 统计指定天数的商品数据 + * + * @return 统计结果 + */ + String statisticsProduct(Integer days); + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/product/ProductStatisticsServiceImpl.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/product/ProductStatisticsServiceImpl.java new file mode 100644 index 000000000..2356fef36 --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/product/ProductStatisticsServiceImpl.java @@ -0,0 +1,117 @@ +package cn.iocoder.yudao.module.statistics.service.product; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.SortablePageParam; +import cn.iocoder.yudao.framework.common.util.object.PageUtils; +import cn.iocoder.yudao.module.statistics.controller.admin.common.vo.DataComparisonRespVO; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsReqVO; +import cn.iocoder.yudao.module.statistics.controller.admin.product.vo.ProductStatisticsRespVO; +import cn.iocoder.yudao.module.statistics.dal.dataobject.product.ProductStatisticsDO; +import cn.iocoder.yudao.module.statistics.dal.mysql.product.ProductStatisticsMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.util.StopWatch; +import org.springframework.validation.annotation.Validated; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + + +/** + * 商品统计 Service 实现类 + * + * @author owen + */ +@Service +@Validated +public class ProductStatisticsServiceImpl implements ProductStatisticsService { + + @Resource + private ProductStatisticsMapper productStatisticsMapper; + + + @Override + public PageResult getProductStatisticsRankPage(ProductStatisticsReqVO reqVO, SortablePageParam pageParam) { + PageUtils.buildDefaultSortingField(pageParam, ProductStatisticsDO::getBrowseCount); // 默认浏览量倒序 + return productStatisticsMapper.selectPageGroupBySpuId(reqVO, pageParam); + } + + @Override + public DataComparisonRespVO getProductStatisticsAnalyse(ProductStatisticsReqVO reqVO) { + LocalDateTime beginTime = ArrayUtil.get(reqVO.getTimes(), 0); + LocalDateTime endTime = ArrayUtil.get(reqVO.getTimes(), 1); + + // 统计数据 + ProductStatisticsRespVO value = productStatisticsMapper.selectVoByTimeBetween(reqVO); + // 对照数据 + LocalDateTime referenceBeginTime = beginTime.minus(Duration.between(beginTime, endTime)); + ProductStatisticsReqVO referenceReqVO = new ProductStatisticsReqVO(new LocalDateTime[]{referenceBeginTime, beginTime}); + ProductStatisticsRespVO reference = productStatisticsMapper.selectVoByTimeBetween(referenceReqVO); + return new DataComparisonRespVO<>(value, reference); + } + + @Override + public List getProductStatisticsList(ProductStatisticsReqVO reqVO) { + return productStatisticsMapper.selectListByTimeBetween(reqVO); + } + + @Override + public String statisticsProduct(Integer days) { + LocalDateTime today = LocalDateTime.now(); + return IntStream.rangeClosed(1, days) + .mapToObj(day -> statisticsProduct(today.minusDays(day))) + .sorted() + .collect(Collectors.joining("\n")); + } + + /** + * 统计商品数据 + * + * @param date 需要统计的日期 + * @return 统计结果 + */ + private String statisticsProduct(LocalDateTime date) { + // 1. 处理统计时间范围 + LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(date); + LocalDateTime endTime = LocalDateTimeUtil.endOfDay(date); + String dateStr = DatePattern.NORM_DATE_FORMATTER.format(date); + // 2. 检查该日是否已经统计过 + Long count = productStatisticsMapper.selectCountByTimeBetween(beginTime, endTime); + if (count != null && count > 0) { + return dateStr + " 数据已存在,如果需要重新统计,请先删除对应的数据"; + } + + StopWatch stopWatch = new StopWatch(dateStr); + stopWatch.start(); + // 4. 分页统计,避免商品表数据较多时,出现超时问题 + final int pageSize = 100; + for (int pageNo = 1; ; pageNo++) { + IPage page = productStatisticsMapper.selectStatisticsResultPageByTimeBetween( + Page.of(pageNo, pageSize, false), beginTime, endTime); + if (CollUtil.isEmpty(page.getRecords())) { + break; + } + // 4.1 计算访客支付转化率(百分比) + for (ProductStatisticsDO record : page.getRecords()) { + record.setTime(date.toLocalDate()); + if (record.getBrowseUserCount() != null && ObjUtil.notEqual(record.getBrowseUserCount(), 0)) { + record.setBrowseConvertPercent(100 * record.getOrderPayCount() / record.getBrowseUserCount()); + } + } + // 4.2 插入数据 + productStatisticsMapper.insertBatch(page.getRecords()); + } + return stopWatch.prettyPrint(); + } + +} \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsService.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsService.java index ec2e5bd5a..225bccf9f 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsService.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsService.java @@ -20,7 +20,7 @@ public interface TradeStatisticsService { * * @return 统计数据对照 */ - DataComparisonRespVO getTradeTrendSummaryComparison( + DataComparisonRespVO getTradeStatisticsAnalyse( LocalDateTime beginTime, LocalDateTime endTime); /** diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java index a6b9b1633..88f3aa2b1 100644 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/service/trade/TradeStatisticsServiceImpl.java @@ -60,7 +60,7 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService { } @Override - public DataComparisonRespVO getTradeTrendSummaryComparison(LocalDateTime beginTime, + public DataComparisonRespVO getTradeStatisticsAnalyse(LocalDateTime beginTime, LocalDateTime endTime) { // 统计数据 TradeTrendSummaryRespVO value = tradeStatisticsMapper.selectVoByTimeBetween(beginTime, endTime); @@ -99,7 +99,7 @@ public class TradeStatisticsServiceImpl implements TradeStatisticsService { // 1. 处理统计时间范围 LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(date); LocalDateTime endTime = LocalDateTimeUtil.endOfDay(date); - String dateStr = DatePattern.NORM_DATE_FORMAT.format(date); + String dateStr = DatePattern.NORM_DATE_FORMATTER.format(date); // 2. 检查该日是否已经统计过 TradeStatisticsDO entity = tradeStatisticsMapper.selectByTimeBetween(beginTime, endTime); if (entity != null) { diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/resources/mapper/product/ProductStatisticsMapper.xml b/yudao-module-mall/yudao-module-statistics-biz/src/main/resources/mapper/product/ProductStatisticsMapper.xml new file mode 100644 index 000000000..e640d1d83 --- /dev/null +++ b/yudao-module-mall/yudao-module-statistics-biz/src/main/resources/mapper/product/ProductStatisticsMapper.xml @@ -0,0 +1,64 @@ + + + + + + + diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java deleted file mode 100644 index 5e3dc3f37..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.member.framework.web.config; - -import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; -import org.springdoc.core.models.GroupedOpenApi; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * member 模块的 web 组件的 Configuration - * - * @author 芋道源码 - */ -@Configuration(proxyBeanMethods = false) -public class MemberWebConfiguration { - - /** - * member 模块的 API 分组 - */ - @Bean - public GroupedOpenApi memberGroupedOpenApi() { - return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("member"); - } - -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java deleted file mode 100644 index 3a964cfc2..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * member 模块的 web 配置 - */ -package cn.iocoder.yudao.module.member.framework.web;