Commit 6bf5eb013385e4b46ef5763a38114c5ec41eb515

Authored by YunaiV
1 parent 71cb5fdc

适配 mall 模块的 openapi

Showing 339 changed files with 21163 additions and 11 deletions

Too many changes.

To preserve performance only 100 of 339 files are displayed.

@@ -17,10 +17,10 @@ @@ -17,10 +17,10 @@
17 <module>yudao-module-system</module> 17 <module>yudao-module-system</module>
18 <module>yudao-module-infra</module> 18 <module>yudao-module-infra</module>
19 <module>yudao-module-pay</module> 19 <module>yudao-module-pay</module>
20 - <module>yudao-module-bpm</module> 20 +<!-- <module>yudao-module-bpm</module>-->
21 <!-- <module>yudao-module-visualization</module>--> 21 <!-- <module>yudao-module-visualization</module>-->
22 <!-- <module>yudao-module-mp</module>--> 22 <!-- <module>yudao-module-mp</module>-->
23 - <!-- <module>yudao-module-mall</module>--> 23 +<!-- <module>yudao-module-mall</module>-->
24 <!-- 示例项目 --> 24 <!-- 示例项目 -->
25 <module>yudao-example</module> 25 <module>yudao-example</module>
26 </modules> 26 </modules>
yudao-module-mall/README.md deleted
1 -mall 后端的代码,暂时归档成一个 yudao-module-mall 的压缩包。  
2 -  
3 -精力有限,近期还是以管理后台的工作流、大屏报表等功能为主!  
4 -  
yudao-module-mall/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <artifactId>yudao</artifactId>
  7 + <groupId>cn.iocoder.boot</groupId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 +
  12 + <artifactId>yudao-module-mall</artifactId>
  13 + <packaging>pom</packaging>
  14 +
  15 + <name>${project.artifactId}</name>
  16 +
  17 + <description>
  18 + 商城大模块,由 product 商品、promotion 营销、trade 交易等组成
  19 + </description>
  20 + <modules>
  21 + <module>yudao-module-promotion-api</module>
  22 + <module>yudao-module-promotion-biz</module>
  23 + <module>yudao-module-product-api</module>
  24 + <module>yudao-module-product-biz</module>
  25 + <module>yudao-module-trade-api</module>
  26 + <module>yudao-module-trade-biz</module>
  27 + </modules>
  28 +
  29 +</project>
yudao-module-mall/yudao-module-mall.zip deleted
No preview for this file type
yudao-module-mall/yudao-module-product-api/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <modelVersion>4.0.0</modelVersion>
  6 + <parent>
  7 + <groupId>cn.iocoder.boot</groupId>
  8 + <artifactId>yudao-module-mall</artifactId>
  9 + <version>${revision}</version>
  10 + </parent>
  11 +
  12 + <artifactId>yudao-module-product-api</artifactId>
  13 + <packaging>jar</packaging>
  14 +
  15 + <name>${project.artifactId}</name>
  16 + <description>
  17 + product 模块 API,暴露给其它模块调用
  18 + </description>
  19 +
  20 + <dependencies>
  21 + <dependency>
  22 + <groupId>cn.iocoder.boot</groupId>
  23 + <artifactId>yudao-common</artifactId>
  24 + </dependency>
  25 +
  26 + <!-- 参数校验 -->
  27 + <dependency>
  28 + <groupId>org.springframework.boot</groupId>
  29 + <artifactId>spring-boot-starter-validation</artifactId>
  30 + <optional>true</optional>
  31 + </dependency>
  32 + </dependencies>
  33 +
  34 +</project>
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java 0 → 100644
  1 +/**
  2 + * 占位
  3 + */
  4 +package cn.iocoder.yudao.module.product.api;
0 \ No newline at end of file 5 \ No newline at end of file
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.property;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
  4 +
  5 +import java.util.Collection;
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * 商品属性值 API 接口
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +public interface ProductPropertyValueApi {
  14 +
  15 + /**
  16 + * 根据编号数组,获得属性值列表
  17 + *
  18 + * @param ids 编号数组
  19 + * @return 属性值明细列表
  20 + */
  21 + List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids);
  22 +
  23 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/dto/ProductPropertyValueDetailRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.property.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * 商品属性项的明细 Response DTO
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +@Data
  11 +public class ProductPropertyValueDetailRespDTO {
  12 +
  13 + /**
  14 + * 属性的编号
  15 + */
  16 + private Long propertyId;
  17 +
  18 + /**
  19 + * 属性的名称
  20 + */
  21 + private String propertyName;
  22 +
  23 + /**
  24 + * 属性值的编号
  25 + */
  26 + private Long valueId;
  27 +
  28 + /**
  29 + * 属性值的名称
  30 + */
  31 + private String valueName;
  32 +
  33 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
  4 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  5 +
  6 +import java.util.Collection;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 商品 SKU API 接口
  11 + *
  12 + * @author LeeYan9
  13 + * @since 2022-08-26
  14 + */
  15 +public interface ProductSkuApi {
  16 +
  17 + /**
  18 + * 查询 SKU 信息
  19 + *
  20 + * @param id SKU 编号
  21 + * @return SKU 信息
  22 + */
  23 + ProductSkuRespDTO getSku(Long id);
  24 +
  25 + /**
  26 + * 批量查询 SKU 数组
  27 + *
  28 + * @param ids SKU 编号列表
  29 + * @return SKU 数组
  30 + */
  31 + List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
  32 +
  33 + /**
  34 + * 更新 SKU 库存
  35 + *
  36 + * @param updateStockReqDTO 更新请求
  37 + */
  38 + void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO);
  39 +
  40 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku.dto;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * 商品 SKU 信息 Response DTO
  10 + *
  11 + * @author LeeYan9
  12 + * @since 2022-08-26
  13 + */
  14 +@Data
  15 +public class ProductSkuRespDTO {
  16 +
  17 + /**
  18 + * 商品 SKU 编号,自增
  19 + */
  20 + private Long id;
  21 + /**
  22 + * SPU 编号
  23 + */
  24 + private Long spuId;
  25 + /**
  26 + * SPU 名字
  27 + */
  28 + private String spuName;
  29 +
  30 + /**
  31 + * 属性数组,JSON 格式
  32 + */
  33 + private List<Property> properties;
  34 + /**
  35 + * 销售价格,单位:分
  36 + */
  37 + private Integer price;
  38 + /**
  39 + * 市场价,单位:分
  40 + */
  41 + private Integer marketPrice;
  42 + /**
  43 + * 成本价,单位:分
  44 + */
  45 + private Integer costPrice;
  46 + /**
  47 + * SKU 的条形码
  48 + */
  49 + private String barCode;
  50 + /**
  51 + * 图片地址
  52 + */
  53 + private String picUrl;
  54 + /**
  55 + * SKU 状态
  56 + * <p>
  57 + * 枚举 {@link CommonStatusEnum}
  58 + */
  59 + private Integer status;
  60 + /**
  61 + * 库存
  62 + */
  63 + private Integer stock;
  64 + /**
  65 + * 预警预存
  66 + */
  67 + private Integer warnStock;
  68 + /**
  69 + * 商品重量,单位:kg 千克
  70 + */
  71 + private Double weight;
  72 + /**
  73 + * 商品体积,单位:m^3 平米
  74 + */
  75 + private Double volume;
  76 +
  77 + /**
  78 + * 商品属性
  79 + */
  80 + @Data
  81 + public static class Property {
  82 +
  83 + /**
  84 + * 属性编号
  85 + */
  86 + private Long propertyId;
  87 + /**
  88 + * 属性值编号
  89 + */
  90 + private Long valueId;
  91 +
  92 + }
  93 +
  94 +
  95 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuUpdateStockReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku.dto;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 商品 SKU 更新库存 Request DTO
  12 + *
  13 + * @author LeeYan9
  14 + * @since 2022-08-26
  15 + */
  16 +@Data
  17 +@NoArgsConstructor
  18 +@AllArgsConstructor
  19 +public class ProductSkuUpdateStockReqDTO {
  20 +
  21 + /**
  22 + * 商品 SKU
  23 + */
  24 + @NotNull(message = "商品 SKU 不能为空")
  25 + private List<Item> items;
  26 +
  27 + @Data
  28 + public static class Item {
  29 +
  30 + /**
  31 + * 商品 SKU 编号
  32 + */
  33 + @NotNull(message = "商品 SKU 编号不能为空")
  34 + private Long id;
  35 +
  36 + /**
  37 + * 库存变化数量
  38 + *
  39 + * 正数:增加库存
  40 + * 负数:扣减库存
  41 + */
  42 + @NotNull(message = "库存变化数量不能为空")
  43 + private Integer incrCount;
  44 +
  45 + }
  46 +
  47 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.spu;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  4 +
  5 +import java.util.Collection;
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * 商品 SPU API 接口
  10 + *
  11 + * @author LeeYan9
  12 + * @since 2022-08-26
  13 + */
  14 +public interface ProductSpuApi {
  15 +
  16 + /**
  17 + * 批量查询 SPU 数组
  18 + *
  19 + * @param ids SPU 编号列表
  20 + * @return SPU 数组
  21 + */
  22 + List<ProductSpuRespDTO> getSpuList(Collection<Long> ids);
  23 +
  24 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.spu.dto;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  4 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
  5 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
  6 +import lombok.Data;
  7 +
  8 +import java.util.List;
  9 +
  10 +// TODO @LeeYan9: ProductSpuRespDTO
  11 +/**
  12 + * 商品 SPU 信息 Response DTO
  13 + *
  14 + * @author LeeYan9
  15 + * @since 2022-08-26
  16 + */
  17 +@Data
  18 +public class ProductSpuRespDTO {
  19 +
  20 + /**
  21 + * 商品 SPU 编号,自增
  22 + */
  23 + private Long id;
  24 +
  25 + // ========== 基本信息 =========
  26 +
  27 + /**
  28 + * 商品名称
  29 + */
  30 + private String name;
  31 + /**
  32 + * 商品编码
  33 + */
  34 + private String code;
  35 + /**
  36 + * 促销语
  37 + */
  38 + private String sellPoint;
  39 + /**
  40 + * 商品详情
  41 + */
  42 + private String description;
  43 + /**
  44 + * 商品分类编号
  45 + */
  46 + private Long categoryId;
  47 + /**
  48 + * 商品品牌编号
  49 + */
  50 + private Long brandId;
  51 + /**
  52 + * 商品图片的数组
  53 + * <p>
  54 + * 1. 第一张图片将作为商品主图,支持同时上传多张图;
  55 + * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片;
  56 + * 3. 至少 1 张,最多上传 10 张
  57 + */
  58 + private List<String> picUrls;
  59 + /**
  60 + * 商品视频
  61 + */
  62 + private String videoUrl;
  63 +
  64 + /**
  65 + * 排序字段
  66 + */
  67 + private Integer sort;
  68 + /**
  69 + * 商品状态
  70 + * <p>
  71 + * 枚举 {@link ProductSpuStatusEnum}
  72 + */
  73 + private Integer status;
  74 +
  75 + // ========== SKU 相关字段 =========
  76 +
  77 + /**
  78 + * 规格类型
  79 + * <p>
  80 + * 枚举 {@link ProductSpuSpecTypeEnum}
  81 + */
  82 + private Integer specType;
  83 + /**
  84 + * 最小价格,单位使用:分
  85 + * <p>
  86 + * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最小值
  87 + */
  88 + private Integer minPrice;
  89 + /**
  90 + * 最大价格,单位使用:分
  91 + * <p>
  92 + * 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最大值
  93 + */
  94 + private Integer maxPrice;
  95 + /**
  96 + * 市场价,单位使用:分
  97 + * <p>
  98 + * 基于其对应的 {@link ProductSkuRespDTO#getMarketPrice()} 最大值
  99 + */
  100 + private Integer marketPrice;
  101 + /**
  102 + * 总库存
  103 + * <p>
  104 + * 基于其对应的 {@link ProductSkuRespDTO#getStock()} 求和
  105 + */
  106 + private Integer totalStock;
  107 + /**
  108 + * 是否展示库存
  109 + */
  110 + private Boolean showStock;
  111 +
  112 + // ========== 统计相关字段 =========
  113 +
  114 + /**
  115 + * 商品销量
  116 + */
  117 + private Integer salesCount;
  118 + /**
  119 + * 虚拟销量
  120 + */
  121 + private Integer virtualSalesCount;
  122 + /**
  123 + * 商品点击量
  124 + */
  125 + private Integer clickCount;
  126 +
  127 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums;
  2 +
  3 +import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  4 +
  5 +/**
  6 + * Product 错误码枚举类
  7 + *
  8 + * product 系统,使用 1-008-000-000 段
  9 + */
  10 +public interface ErrorCodeConstants {
  11 +
  12 + // ========== 商品分类相关 1008001000 ============
  13 + ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");
  14 + ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");
  15 + ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
  16 + ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
  17 + ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
  18 +
  19 + // ========== 商品品牌相关编号 1008002000 ==========
  20 + ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
  21 + ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在");
  22 + ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在");
  23 +
  24 + // ========== 商品属性项 1008003000 ==========
  25 + ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "属性项不存在");
  26 + ErrorCode PROPERTY_EXISTS = new ErrorCode(1008003001, "属性项的名称已存在");
  27 + ErrorCode PROPERTY_DELETE_FAIL_VALUE_EXISTS = new ErrorCode(1008003002, "属性项下存在属性值,无法删除");
  28 +
  29 + // ========== 商品属性值 1008004000 ==========
  30 + ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "属性值不存在");
  31 + ErrorCode PROPERTY_VALUE_EXISTS = new ErrorCode(1008004001, "属性值的名称已存在");
  32 +
  33 + // ========== 商品 SPU 1008005000 ==========
  34 + ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
  35 + ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下");
  36 + ErrorCode SPU_NOT_ENABLE = new ErrorCode(1008005002, "商品 SPU 不处于上架状态");
  37 +
  38 + // ========== 商品 SKU 1008006000 ==========
  39 + ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");
  40 + ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品 SKU 的属性组合存在重复");
  41 + ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 SPU 下的每个 SKU,其属性项必须一致");
  42 + ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU,必须不重复");
  43 + ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
  44 +
  45 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.comment;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品评论的审批状态枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductCommentAuditStatusEnum implements IntArrayValuable {
  17 +
  18 + NONE(1, "待审核"),
  19 + APPROVE(2, "审批通过"),
  20 + REJECT(2, "审批不通过"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentAuditStatusEnum::getStatus).toArray();
  23 +
  24 + /**
  25 + * 审批状态
  26 + */
  27 + private final Integer status;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.delivery;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 配送方式枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum DeliveryTypeEnum implements IntArrayValuable {
  17 +
  18 + // TODO 芋艿:英文单词,需要再想下;
  19 + EXPRESS(1, "快递发货"),
  20 + USER(2, "用户自提"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getMode).toArray();
  23 +
  24 + /**
  25 + * 配送方式
  26 + */
  27 + private final Integer mode;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.group;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品分组的样式枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductGroupStyleEnum implements IntArrayValuable {
  17 +
  18 + ONE(1, "每列一个"),
  19 + TWO(2, "每列两个"),
  20 + THREE(2, "每列三个"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductGroupStyleEnum::getStyle).toArray();
  23 +
  24 + /**
  25 + * 列表样式
  26 + */
  27 + private final Integer style;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品 SPU 规格类型
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductSpuSpecTypeEnum implements IntArrayValuable {
  17 +
  18 + RECYCLE(1, "统一规格"),
  19 + DISABLE(2, "多规格");
  20 +
  21 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray();
  22 +
  23 + /**
  24 + * 规格类型
  25 + */
  26 + private final Integer type;
  27 + /**
  28 + * 规格名称
  29 + */
  30 + private final String name;
  31 +
  32 + @Override
  33 + public int[] array() {
  34 + return ARRAYS;
  35 + }
  36 +
  37 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品 SPU 状态
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductSpuStatusEnum implements IntArrayValuable {
  17 +
  18 + RECYCLE(-1, "回收站"),
  19 + DISABLE(0, "下架"),
  20 + ENABLE(1, "上架"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStatus).toArray();
  23 +
  24 + /**
  25 + * 状态
  26 + */
  27 + private final Integer status;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 + /**
  39 + * 判断是否处于【上架】状态
  40 + *
  41 + * @param status 状态
  42 + * @return 是否处于【上架】状态
  43 + */
  44 + public static boolean isEnable(Integer status) {
  45 + return ENABLE.getStatus().equals(status);
  46 + }
  47 +
  48 +}
yudao-module-mall/yudao-module-product-biz/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <groupId>cn.iocoder.boot</groupId>
  7 + <artifactId>yudao-module-mall</artifactId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 + <artifactId>yudao-module-product-biz</artifactId>
  12 + <packaging>jar</packaging>
  13 +
  14 + <name>${project.artifactId}</name>
  15 + <description>
  16 + product 模块,主要实现商品相关功能
  17 + 例如:品牌、商品分类、spu、sku等功能。
  18 + </description>
  19 +
  20 + <dependencies>
  21 + <dependency>
  22 + <groupId>cn.iocoder.boot</groupId>
  23 + <artifactId>yudao-module-product-api</artifactId>
  24 + <version>${revision}</version>
  25 + </dependency>
  26 +
  27 + <!-- 业务组件 -->
  28 + <dependency>
  29 + <groupId>cn.iocoder.boot</groupId>
  30 + <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
  31 + </dependency>
  32 +
  33 + <!-- Web 相关 -->
  34 + <dependency>
  35 + <groupId>cn.iocoder.boot</groupId>
  36 + <artifactId>yudao-spring-boot-starter-web</artifactId>
  37 + </dependency>
  38 + <dependency>
  39 + <groupId>cn.iocoder.boot</groupId>
  40 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  41 + </dependency>
  42 +
  43 + <!-- DB 相关 -->
  44 + <dependency>
  45 + <groupId>cn.iocoder.boot</groupId>
  46 + <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
  47 + </dependency>
  48 +
  49 + <!-- Test 测试相关 -->
  50 + <dependency>
  51 + <groupId>cn.iocoder.boot</groupId>
  52 + <artifactId>yudao-spring-boot-starter-test</artifactId>
  53 + </dependency>
  54 +
  55 + <!-- 工具类相关 -->
  56 + <dependency>
  57 + <groupId>cn.iocoder.boot</groupId>
  58 + <artifactId>yudao-spring-boot-starter-excel</artifactId>
  59 + </dependency>
  60 + </dependencies>
  61 +
  62 +</project>
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.property;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
  4 +import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert;
  5 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
  6 +import org.springframework.stereotype.Service;
  7 +import org.springframework.validation.annotation.Validated;
  8 +
  9 +import javax.annotation.Resource;
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 商品属性值 API 实现类
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Service
  19 +@Validated
  20 +public class ProductPropertyValueApiImpl implements ProductPropertyValueApi {
  21 +
  22 + @Resource
  23 + private ProductPropertyValueService productPropertyValueService;
  24 +
  25 + @Override
  26 + public List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids) {
  27 + return ProductPropertyValueConvert.INSTANCE.convertList02(
  28 + productPropertyValueService.getPropertyValueDetailList(ids));
  29 + }
  30 +
  31 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  5 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
  6 +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
  7 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  8 +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import javax.annotation.Resource;
  13 +import java.util.Collection;
  14 +import java.util.Collections;
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * TODO LeeYan9: 类注释;
  19 + * @author LeeYan9
  20 + * @since 2022-09-06
  21 + */
  22 +@Service
  23 +@Validated
  24 +public class ProductSkuApiImpl implements ProductSkuApi {
  25 +
  26 + @Resource
  27 + private ProductSkuService productSkuService;
  28 +
  29 + @Override
  30 + public ProductSkuRespDTO getSku(Long id) {
  31 + // TODO TODO LeeYan9: 需要实现
  32 + return null;
  33 + }
  34 +
  35 + @Override
  36 + public List<ProductSkuRespDTO> getSkuList(Collection<Long> ids) {
  37 + if (CollUtil.isEmpty(ids)) {
  38 + return Collections.emptyList();
  39 + }
  40 + List<ProductSkuDO> skus = productSkuService.getSkuList(ids);
  41 + return ProductSkuConvert.INSTANCE.convertList04(skus);
  42 + }
  43 +
  44 + @Override
  45 + public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) {
  46 + productSkuService.updateSkuStock(updateStockReqDTO);
  47 + }
  48 +
  49 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  5 +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
  6 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  7 +import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.validation.annotation.Validated;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.util.Collection;
  13 +import java.util.Collections;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * TODO LeeYan9: 类注释;
  18 + *
  19 + * @author LeeYan9
  20 + * @since 2022-09-06
  21 + */
  22 +@Service
  23 +@Validated
  24 +public class ProductSpuApiImpl implements ProductSpuApi {
  25 +
  26 + @Resource
  27 + private ProductSpuMapper productSpuMapper;
  28 +
  29 + @Override
  30 + public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) {
  31 + // TODO TODO LeeYan9: AllEmpty?
  32 + if (CollectionUtils.isAnyEmpty(spuIds)) {
  33 + return Collections.emptyList();
  34 + }
  35 + List<ProductSpuDO> productSpuDOList = productSpuMapper.selectBatchIds(spuIds);
  36 + return ProductSpuConvert.INSTANCE.convertList2(productSpuDOList);
  37 + }
  38 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*;
  6 +import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert;
  7 +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
  8 +import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import javax.annotation.Resource;
  17 +import javax.validation.Valid;
  18 +import java.util.Comparator;
  19 +import java.util.List;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +
  23 +@Tag(name = "管理后台 - 商品品牌")
  24 +@RestController
  25 +@RequestMapping("/product/brand")
  26 +@Validated
  27 +public class ProductBrandController {
  28 +
  29 + @Resource
  30 + private ProductBrandService brandService;
  31 +
  32 + @PostMapping("/create")
  33 + @Operation(summary = "创建品牌")
  34 + @PreAuthorize("@ss.hasPermission('product:brand:create')")
  35 + public CommonResult<Long> createBrand(@Valid @RequestBody ProductBrandCreateReqVO createReqVO) {
  36 + return success(brandService.createBrand(createReqVO));
  37 + }
  38 +
  39 + @PutMapping("/update")
  40 + @Operation(summary = "更新品牌")
  41 + @PreAuthorize("@ss.hasPermission('product:brand:update')")
  42 + public CommonResult<Boolean> updateBrand(@Valid @RequestBody ProductBrandUpdateReqVO updateReqVO) {
  43 + brandService.updateBrand(updateReqVO);
  44 + return success(true);
  45 + }
  46 +
  47 + @DeleteMapping("/delete")
  48 + @Operation(summary = "删除品牌")
  49 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  50 + @PreAuthorize("@ss.hasPermission('product:brand:delete')")
  51 + public CommonResult<Boolean> deleteBrand(@RequestParam("id") Long id) {
  52 + brandService.deleteBrand(id);
  53 + return success(true);
  54 + }
  55 +
  56 + @GetMapping("/get")
  57 + @Operation(summary = "获得品牌")
  58 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  59 + @PreAuthorize("@ss.hasPermission('product:brand:query')")
  60 + public CommonResult<ProductBrandRespVO> getBrand(@RequestParam("id") Long id) {
  61 + ProductBrandDO brand = brandService.getBrand(id);
  62 + return success(ProductBrandConvert.INSTANCE.convert(brand));
  63 + }
  64 +
  65 + @GetMapping("/page")
  66 + @Operation(summary = "获得品牌分页")
  67 + @PreAuthorize("@ss.hasPermission('product:brand:query')")
  68 + public CommonResult<PageResult<ProductBrandRespVO>> getBrandPage(@Valid ProductBrandPageReqVO pageVO) {
  69 + PageResult<ProductBrandDO> pageResult = brandService.getBrandPage(pageVO);
  70 + return success(ProductBrandConvert.INSTANCE.convertPage(pageResult));
  71 + }
  72 +
  73 + @GetMapping("/list")
  74 + @Operation(summary = "获得品牌列表")
  75 + @PreAuthorize("@ss.hasPermission('product:brand:query')")
  76 + public CommonResult<List<ProductBrandRespVO>> getBrandList(@Valid ProductBrandListReqVO listVO) {
  77 + List<ProductBrandDO> list = brandService.getBrandList(listVO);
  78 + list.sort(Comparator.comparing(ProductBrandDO::getSort));
  79 + return success(ProductBrandConvert.INSTANCE.convertList(list));
  80 + }
  81 +
  82 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +/**
  9 +* 商品品牌 Base VO,提供给添加、修改、详细的子 VO 使用
  10 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 +*/
  12 +@Data
  13 +public class ProductBrandBaseVO {
  14 +
  15 + @Schema(description = "品牌名称", required = true, example = "芋道")
  16 + @NotNull(message = "品牌名称不能为空")
  17 + private String name;
  18 +
  19 + @Schema(description = "品牌图片", required = true)
  20 + @NotNull(message = "品牌图片不能为空")
  21 + private String picUrl;
  22 +
  23 + @Schema(description = "品牌排序", required = true, example = "1")
  24 + @NotNull(message = "品牌排序不能为空")
  25 + private Integer sort;
  26 +
  27 + @Schema(description = "品牌描述", example = "描述")
  28 + private String description;
  29 +
  30 + @Schema(description = "状态", required = true, example = "0")
  31 + @NotNull(message = "状态不能为空")
  32 + private Integer status;
  33 +
  34 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 商品品牌创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class ProductBrandCreateReqVO extends ProductBrandBaseVO {
  13 +
  14 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - 商品品牌分页 Request VO")
  7 +@Data
  8 +public class ProductBrandListReqVO {
  9 +
  10 + @Schema(description = "品牌名称", example = "芋道")
  11 + private String name;
  12 +
  13 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 商品品牌分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class ProductBrandPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "品牌名称", example = "芋道")
  21 + private String name;
  22 +
  23 + @Schema(description = "状态", example = "0")
  24 + private Integer status;
  25 +
  26 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  27 + @Schema(description = "创建时间")
  28 + private LocalDateTime[] createTime;
  29 +
  30 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 品牌 Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductBrandRespVO extends ProductBrandBaseVO {
  15 +
  16 + @Schema(description = "品牌编号", required = true, example = "1")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间", required = true)
  20 + private LocalDateTime createTime;
  21 +
  22 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "管理后台 - 商品品牌更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductBrandUpdateReqVO extends ProductBrandBaseVO {
  15 +
  16 + @Schema(description = "品牌编号", required = true, example = "1")
  17 + @NotNull(message = "品牌编号不能为空")
  18 + private Long id;
  19 +
  20 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/ProductCategoryController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.category;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
  8 +import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
  10 +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.validation.Valid;
  20 +import java.util.Comparator;
  21 +import java.util.List;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  24 +
  25 +@Tag(name = "管理后台 - 商品分类")
  26 +@RestController
  27 +@RequestMapping("/product/category")
  28 +@Validated
  29 +public class ProductCategoryController {
  30 +
  31 + @Resource
  32 + private ProductCategoryService categoryService;
  33 +
  34 + @PostMapping("/create")
  35 + @Operation(summary = "创建商品分类")
  36 + @PreAuthorize("@ss.hasPermission('product:category:create')")
  37 + public CommonResult<Long> createCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) {
  38 + return success(categoryService.createCategory(createReqVO));
  39 + }
  40 +
  41 + @PutMapping("/update")
  42 + @Operation(summary = "更新商品分类")
  43 + @PreAuthorize("@ss.hasPermission('product:category:update')")
  44 + public CommonResult<Boolean> updateCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) {
  45 + categoryService.updateCategory(updateReqVO);
  46 + return success(true);
  47 + }
  48 +
  49 + @DeleteMapping("/delete")
  50 + @Operation(summary = "删除商品分类")
  51 + @Parameter(name = "id", description = "编号", required = true)
  52 + @PreAuthorize("@ss.hasPermission('product:category:delete')")
  53 + public CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id) {
  54 + categoryService.deleteCategory(id);
  55 + return success(true);
  56 + }
  57 +
  58 + @GetMapping("/get")
  59 + @Operation(summary = "获得商品分类")
  60 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  61 + @PreAuthorize("@ss.hasPermission('product:category:query')")
  62 + public CommonResult<ProductCategoryRespVO> getCategory(@RequestParam("id") Long id) {
  63 + ProductCategoryDO category = categoryService.getCategory(id);
  64 + return success(ProductCategoryConvert.INSTANCE.convert(category));
  65 + }
  66 +
  67 + @GetMapping("/list")
  68 + @Operation(summary = "获得商品分类列表")
  69 + @PreAuthorize("@ss.hasPermission('product:category:query')")
  70 + public CommonResult<List<ProductCategoryRespVO>> getCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) {
  71 + List<ProductCategoryDO> list = categoryService.getEnableCategoryList(treeListReqVO);
  72 + list.sort(Comparator.comparing(ProductCategoryDO::getSort));
  73 + return success(ProductCategoryConvert.INSTANCE.convertList(list));
  74 + }
  75 +
  76 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.category.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotBlank;
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +/**
  10 +* 商品分类 Base VO,提供给添加、修改、详细的子 VO 使用
  11 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  12 +*/
  13 +@Data
  14 +public class ProductCategoryBaseVO {
  15 +
  16 + @Schema(description = "父分类编号", required = true, example = "1")
  17 + @NotNull(message = "父分类编号不能为空")
  18 + private Long parentId;
  19 +
  20 + @Schema(description = "分类名称", required = true, example = "办公文具")
  21 + @NotBlank(message = "分类名称不能为空")
  22 + private String name;
  23 +
  24 + @Schema(description = "分类图片", required = true)
  25 + @NotBlank(message = "分类图片不能为空")
  26 + private String picUrl;
  27 +
  28 + @Schema(description = "分类排序", required = true, example = "1")
  29 + private Integer sort;
  30 +
  31 + @Schema(description = "分类描述", required = true, example = "描述")
  32 + private String description;
  33 +
  34 + @Schema(description = "开启状态", required = true, example = "0")
  35 + @NotNull(message = "开启状态不能为空")
  36 + private Integer status;
  37 +
  38 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.category.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 商品分类创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO {
  13 +
  14 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.category.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - 商品分类列表查询 Request VO")
  7 +@Data
  8 +public class ProductCategoryListReqVO {
  9 +
  10 + @Schema(description = "分类名称", example = "办公文具")
  11 + private String name;
  12 +
  13 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.category.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 商品分类 Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductCategoryRespVO extends ProductCategoryBaseVO {
  15 +
  16 + @Schema(description = "分类编号", required = true, example = "2")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间", required = true)
  20 + private LocalDateTime createTime;
  21 +
  22 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/ProductCategoryUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.category.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "管理后台 - 商品分类更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO {
  15 +
  16 + @Schema(description = "分类编号", required = true, example = "2")
  17 + @NotNull(message = "分类编号不能为空")
  18 + private Long id;
  19 +
  20 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
  7 +import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
  10 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
  11 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +import io.swagger.v3.oas.annotations.Parameter;
  14 +import io.swagger.v3.oas.annotations.tags.Tag;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.*;
  18 +
  19 +import javax.annotation.Resource;
  20 +import javax.validation.Valid;
  21 +import java.util.Collections;
  22 +import java.util.List;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  26 +
  27 +@Tag(name = "管理后台 - 商品属性项")
  28 +@RestController
  29 +@RequestMapping("/product/property")
  30 +@Validated
  31 +public class ProductPropertyController {
  32 +
  33 + @Resource
  34 + private ProductPropertyService productPropertyService;
  35 + @Resource
  36 + private ProductPropertyValueService productPropertyValueService;
  37 +
  38 + @PostMapping("/create")
  39 + @Operation(summary = "创建属性项")
  40 + @PreAuthorize("@ss.hasPermission('product:property:create')")
  41 + public CommonResult<Long> createProperty(@Valid @RequestBody ProductPropertyCreateReqVO createReqVO) {
  42 + return success(productPropertyService.createProperty(createReqVO));
  43 + }
  44 +
  45 + @PutMapping("/update")
  46 + @Operation(summary = "更新属性项")
  47 + @PreAuthorize("@ss.hasPermission('product:property:update')")
  48 + public CommonResult<Boolean> updateProperty(@Valid @RequestBody ProductPropertyUpdateReqVO updateReqVO) {
  49 + productPropertyService.updateProperty(updateReqVO);
  50 + return success(true);
  51 + }
  52 +
  53 + @DeleteMapping("/delete")
  54 + @Operation(summary = "删除属性项")
  55 + @Parameter(name = "id", description = "编号", required = true)
  56 + @PreAuthorize("@ss.hasPermission('product:property:delete')")
  57 + public CommonResult<Boolean> deleteProperty(@RequestParam("id") Long id) {
  58 + productPropertyService.deleteProperty(id);
  59 + return success(true);
  60 + }
  61 +
  62 + @GetMapping("/get")
  63 + @Operation(summary = "获得属性项")
  64 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  65 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  66 + public CommonResult<ProductPropertyRespVO> getProperty(@RequestParam("id") Long id) {
  67 + return success(ProductPropertyConvert.INSTANCE.convert(productPropertyService.getProperty(id)));
  68 + }
  69 +
  70 + @GetMapping("/list")
  71 + @Operation(summary = "获得属性项列表")
  72 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  73 + public CommonResult<List<ProductPropertyRespVO>> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) {
  74 + return success(ProductPropertyConvert.INSTANCE.convertList(productPropertyService.getPropertyList(listReqVO)));
  75 + }
  76 +
  77 + @GetMapping("/page")
  78 + @Operation(summary = "获得属性项分页")
  79 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  80 + public CommonResult<PageResult<ProductPropertyRespVO>> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) {
  81 + return success(ProductPropertyConvert.INSTANCE.convertPage(productPropertyService.getPropertyPage(pageVO)));
  82 + }
  83 +
  84 + @GetMapping("/get-value-list")
  85 + @Operation(summary = "获得属性项列表")
  86 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  87 + public CommonResult<List<ProductPropertyAndValueRespVO>> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) {
  88 + // 查询属性项
  89 + List<ProductPropertyDO> keys = productPropertyService.getPropertyList(listReqVO);
  90 + if (CollUtil.isEmpty(keys)) {
  91 + return success(Collections.emptyList());
  92 + }
  93 + // 查询属性值
  94 + List<ProductPropertyValueDO> values = productPropertyValueService.getPropertyValueListByPropertyId(
  95 + convertSet(keys, ProductPropertyDO::getId));
  96 + return success(ProductPropertyConvert.INSTANCE.convertList(keys, values));
  97 + }
  98 +
  99 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/ProductPropertyValueController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
  8 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
  9 +import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert;
  10 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import org.springframework.security.access.prepost.PreAuthorize;
  15 +import org.springframework.validation.annotation.Validated;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.validation.Valid;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +
  23 +@Tag(name = "管理后台 - 商品属性值")
  24 +@RestController
  25 +@RequestMapping("/product/property/value")
  26 +@Validated
  27 +public class ProductPropertyValueController {
  28 +
  29 + @Resource
  30 + private ProductPropertyValueService productPropertyValueService;
  31 +
  32 + @PostMapping("/create")
  33 + @Operation(summary = "创建属性值")
  34 + @PreAuthorize("@ss.hasPermission('product:property:create')")
  35 + public CommonResult<Long> createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) {
  36 + return success(productPropertyValueService.createPropertyValue(createReqVO));
  37 + }
  38 +
  39 + @PutMapping("/update")
  40 + @Operation(summary = "更新属性值")
  41 + @PreAuthorize("@ss.hasPermission('product:property:update')")
  42 + public CommonResult<Boolean> updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) {
  43 + productPropertyValueService.updatePropertyValue(updateReqVO);
  44 + return success(true);
  45 + }
  46 +
  47 + @DeleteMapping("/delete")
  48 + @Operation(summary = "删除属性值")
  49 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  50 + @PreAuthorize("@ss.hasPermission('product:property:delete')")
  51 + public CommonResult<Boolean> deleteProperty(@RequestParam("id") Long id) {
  52 + productPropertyValueService.deletePropertyValue(id);
  53 + return success(true);
  54 + }
  55 +
  56 + @GetMapping("/get")
  57 + @Operation(summary = "获得属性值")
  58 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  59 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  60 + public CommonResult<ProductPropertyValueRespVO> getProperty(@RequestParam("id") Long id) {
  61 + return success(ProductPropertyValueConvert.INSTANCE.convert(productPropertyValueService.getPropertyValue(id)));
  62 + }
  63 +
  64 + @GetMapping("/page")
  65 + @Operation(summary = "获得属性值分页")
  66 + @PreAuthorize("@ss.hasPermission('product:property:query')")
  67 + public CommonResult<PageResult<ProductPropertyValueRespVO>> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) {
  68 + return success(ProductPropertyValueConvert.INSTANCE.convertPage(productPropertyValueService.getPropertyValuePage(pageVO)));
  69 + }
  70 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyAndValueRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Schema(description = "管理后台 - 商品属性项 + 属性值 Response VO")
  9 +@Data
  10 +public class ProductPropertyAndValueRespVO {
  11 +
  12 + @Schema(description = "属性项的编号", required = true, example = "1024")
  13 + private Long id;
  14 +
  15 + @Schema(description = "属性项的名称", required = true, example = "颜色")
  16 + private String name;
  17 +
  18 + /**
  19 + * 属性值的集合
  20 + */
  21 + private List<Value> values;
  22 +
  23 + @Schema(description = "管理后台 - 属性值的简单 Response VO")
  24 + @Data
  25 + public static class Value {
  26 +
  27 + @Schema(description = "属性值的编号", required = true, example = "2048")
  28 + private Long id;
  29 +
  30 + @Schema(description = "属性值的名称", required = true, example = "红色")
  31 + private String name;
  32 +
  33 + }
  34 +
  35 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotBlank;
  7 +
  8 +/**
  9 + * 商品属性项 Base VO,提供给添加、修改、详细的子 VO 使用
  10 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 + */
  12 +@Data
  13 +public class ProductPropertyBaseVO {
  14 +
  15 + @Schema(description = "名称", required = true, example = "颜色")
  16 + @NotBlank(message = "名称不能为空")
  17 + private String name;
  18 +
  19 + @Schema(description = "备注", example = "颜色")
  20 + private String remark;
  21 +
  22 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 属性项创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO {
  13 +
  14 +
  15 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.ToString;
  6 +
  7 +@Schema(description = "管理后台 - 属性项 List Request VO")
  8 +@Data
  9 +@ToString(callSuper = true)
  10 +public class ProductPropertyListReqVO {
  11 +
  12 + @Schema(description = "名称", example = "颜色")
  13 + private String name;
  14 +
  15 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 属性项 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class ProductPropertyPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "名称", example = "颜色")
  21 + private String name;
  22 +
  23 + @Schema(description = "状态", required = true, example = "1")
  24 + private Integer status;
  25 +
  26 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  27 + @Schema(description = "创建时间")
  28 + private LocalDateTime[] createTime;
  29 +
  30 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 属性项 Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductPropertyRespVO extends ProductPropertyBaseVO {
  15 +
  16 + @Schema(description = "编号", required = true, example = "1024")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间", required = true)
  20 + private LocalDateTime createTime;
  21 +
  22 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/property/ProductPropertyUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "管理后台 - 属性项更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO {
  15 +
  16 + @Schema(description = "主键", required = true, example = "1")
  17 + @NotNull(message = "主键不能为空")
  18 + private Long id;
  19 +
  20 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotEmpty;
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +/**
  10 +* 属性值 Base VO,提供给添加、修改、详细的子 VO 使用
  11 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  12 +*/
  13 +@Data
  14 +public class ProductPropertyValueBaseVO {
  15 +
  16 + @Schema(description = "属性项的编号", required = true, example = "1024")
  17 + @NotNull(message = "属性项的编号不能为空")
  18 + private Long propertyId;
  19 +
  20 + @Schema(description = "名称", required = true, example = "红色")
  21 + @NotEmpty(message = "名称名字不能为空")
  22 + private String name;
  23 +
  24 + @Schema(description = "备注", example = "颜色")
  25 + private String remark;
  26 +
  27 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 商品属性值创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class ProductPropertyValueCreateReqVO extends ProductPropertyValueBaseVO {
  13 +
  14 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - 商品属性值的明细 Response VO")
  7 +@Data
  8 +public class ProductPropertyValueDetailRespVO {
  9 +
  10 + @Schema(description = "属性的编号", required = true, example = "1")
  11 + private Long propertyId;
  12 +
  13 + @Schema(description = "属性的名称", required = true, example = "颜色")
  14 + private String propertyName;
  15 +
  16 + @Schema(description = "属性值的编号", required = true, example = "1024")
  17 + private Long valueId;
  18 +
  19 + @Schema(description = "属性值的名称", required = true, example = "红色")
  20 + private String valueName;
  21 +
  22 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValuePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - 商品属性值分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class ProductPropertyValuePageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "属性项的编号", example = "1024")
  16 + private String propertyId;
  17 +
  18 + @Schema(description = "名称", example = "红色")
  19 + private String name;
  20 +
  21 + @Schema(description = "状态", required = true, example = "1")
  22 + private Integer status;
  23 +
  24 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 商品属性值 Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO {
  15 +
  16 + @Schema(description = "编号", required = true, example = "10")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间")
  20 + private LocalDateTime createTime;
  21 +
  22 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/property/vo/value/ProductPropertyValueUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "管理后台 - 商品属性值更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO {
  15 +
  16 + @Schema(description = "主键", required = true, example = "1024")
  17 + @NotNull(message = "主键不能为空")
  18 + private Long id;
  19 +
  20 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/ProductSkuController.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.sku;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
  7 +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  10 +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
  11 +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import org.springframework.validation.annotation.Validated;
  15 +import org.springframework.web.bind.annotation.GetMapping;
  16 +import org.springframework.web.bind.annotation.RequestMapping;
  17 +import org.springframework.web.bind.annotation.RestController;
  18 +
  19 +import javax.annotation.Resource;
  20 +import java.util.Collections;
  21 +import java.util.List;
  22 +import java.util.Map;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  26 +
  27 +@Tag(name = "管理后台 - 商品 sku")
  28 +@RestController
  29 +@RequestMapping("/product/sku")
  30 +@Validated
  31 +public class ProductSkuController {
  32 +
  33 + @Resource
  34 + private ProductSkuService productSkuService;
  35 + @Resource
  36 + private ProductSpuService productSpuService;
  37 +
  38 + @GetMapping("/get-option-list")
  39 + @Operation(summary = "获得商品 SKU 选项的列表")
  40 +// @PreAuthorize("@ss.hasPermission('product:sku:query')")
  41 + public CommonResult<List<ProductSkuOptionRespVO>> getSkuOptionList() {
  42 + // 获得 SKU 列表
  43 + List<ProductSkuDO> skus = productSkuService.getSkuList();
  44 + if (CollUtil.isEmpty(skus)) {
  45 + return success(Collections.emptyList());
  46 + }
  47 +
  48 + // 获得对应的 SPU 映射
  49 + Map<Long, ProductSpuDO> spuMap = productSpuService.getSpuMap(convertSet(skus, ProductSkuDO::getSpuId));
  50 + // 转换为返回结果
  51 + List<ProductSkuOptionRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList05(skus);
  52 + skuVOs.forEach(sku -> MapUtils.findAndThen(spuMap, sku.getSpuId(),
  53 + spu -> sku.setSpuId(spu.getId()).setSpuName(spu.getName())));
  54 + return success(skuVOs);
  55 + }
  56 +
  57 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.AllArgsConstructor;
  7 +import lombok.Data;
  8 +import lombok.NoArgsConstructor;
  9 +
  10 +import javax.validation.constraints.NotEmpty;
  11 +import javax.validation.constraints.NotNull;
  12 +
  13 +/**
  14 +* 商品 SKU Base VO,提供给添加、修改、详细的子 VO 使用
  15 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  16 +*/
  17 +@Data
  18 +public class ProductSkuBaseVO {
  19 +
  20 + @Schema(description = "商品 SKU 名字", required = true, example = "芋道")
  21 + @NotEmpty(message = "商品 SKU 名字不能为空")
  22 + private String name;
  23 +
  24 + @Schema(description = "销售价格,单位:分", required = true, example = "1024")
  25 + @NotNull(message = "销售价格,单位:分不能为空")
  26 + private Integer price;
  27 +
  28 + @Schema(description = "市场价", example = "1024")
  29 + private Integer marketPrice;
  30 +
  31 + @Schema(description = "成本价", example = "1024")
  32 + private Integer costPrice;
  33 +
  34 + @Schema(description = "条形码", example = "haha")
  35 + private String barCode;
  36 +
  37 + @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
  38 + @NotNull(message = "图片地址不能为空")
  39 + private String picUrl;
  40 +
  41 + @Schema(description = "SKU 状态", required = true, example = "1")
  42 + @NotNull(message = "SKU 状态不能为空")
  43 + @InEnum(CommonStatusEnum.class)
  44 + private Integer status;
  45 +
  46 + @Schema(description = "库存", required = true, example = "1")
  47 + @NotNull(message = "库存不能为空")
  48 + private Integer stock;
  49 +
  50 + @Schema(description = "预警预存", example = "1")
  51 + private Integer warnStock;
  52 +
  53 + @Schema(description = "商品重量", example = "1") // 单位:kg 千克
  54 + private Double weight;
  55 +
  56 + @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米
  57 + private Double volume;
  58 +
  59 + @Schema(description = "商品属性")
  60 + @Data
  61 + @AllArgsConstructor
  62 + @NoArgsConstructor
  63 + public static class Property {
  64 +
  65 + @Schema(description = "属性编号", required = true, example = "1")
  66 + @NotNull(message = "属性编号不能为空")
  67 + private Long propertyId;
  68 +
  69 + @Schema(description = "属性值编号", required = true, example = "1024")
  70 + @NotNull(message = "属性值编号不能为空")
  71 + private Long valueId;
  72 +
  73 + }
  74 +
  75 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateOrUpdateReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.util.List;
  9 +
  10 +@Schema(description = "管理后台 - 商品 SKU 创建/更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO {
  15 +
  16 + /**
  17 + * 属性数组
  18 + */
  19 + private List<Property> properties;
  20 +
  21 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuOptionRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - 商品 SKU 选项 Response VO") // 用于前端 SELECT 选项
  7 +@Data
  8 +public class ProductSkuOptionRespVO {
  9 +
  10 + @Schema(description = "主键", required = true, example = "1024")
  11 + private Long id;
  12 +
  13 + @Schema(description = "商品 SKU 名字", example = "红色")
  14 + private String name;
  15 +
  16 + @Schema(description = "销售价格", required = true, example = "100")
  17 + private String price;
  18 +
  19 + @Schema(description = "库存", required = true, example = "100")
  20 + private Integer stock;
  21 +
  22 + // ========== 商品 SPU 信息 ==========
  23 +
  24 + @Schema(description = "商品 SPU 编号", required = true, example = "1")
  25 + private Long spuId;
  26 +
  27 + @Schema(description = "商品 SPU 名字", required = true, example = "iPhone 11")
  28 + private String spuName;
  29 +
  30 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +import java.util.List;
  10 +
  11 +@Schema(description = "管理后台 - 商品 SKU Response VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class ProductSkuRespVO extends ProductSkuBaseVO {
  16 +
  17 + @Schema(description = "主键", required = true, example = "1024")
  18 + private Long id;
  19 +
  20 + @Schema(description = "创建时间")
  21 + private LocalDateTime createTime;
  22 +
  23 + /**
  24 + * 属性数组
  25 + */
  26 + private List<Property> properties;
  27 +
  28 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.http 0 → 100644
  1 +### 获得商品 SPU 明细
  2 +GET {{baseUrl}}/product/spu/get-detail?id=4
  3 +Authorization: Bearer {{token}}
  4 +tenant-id: {{adminTenentId}}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
  6 +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
  7 +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  10 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
  11 +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
  12 +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
  13 +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
  14 +import io.swagger.v3.oas.annotations.Operation;
  15 +import io.swagger.v3.oas.annotations.Parameter;
  16 +import io.swagger.v3.oas.annotations.tags.Tag;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
  18 +import org.springframework.validation.annotation.Validated;
  19 +import org.springframework.web.bind.annotation.*;
  20 +
  21 +import javax.annotation.Resource;
  22 +import javax.validation.Valid;
  23 +import java.util.List;
  24 +
  25 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  26 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  27 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
  28 +
  29 +@Tag(name = "管理后台 - 商品 SPU")
  30 +@RestController
  31 +@RequestMapping("/product/spu")
  32 +@Validated
  33 +public class ProductSpuController {
  34 +
  35 + @Resource
  36 + private ProductSpuService productSpuService;
  37 + @Resource
  38 + private ProductSkuService productSkuService;
  39 + @Resource
  40 + private ProductPropertyValueService productPropertyValueService;
  41 +
  42 + @PostMapping("/create")
  43 + @Operation(summary = "创建商品 SPU")
  44 + @PreAuthorize("@ss.hasPermission('product:spu:create')")
  45 + public CommonResult<Long> createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) {
  46 + return success(productSpuService.createSpu(createReqVO));
  47 + }
  48 +
  49 + @PutMapping("/update")
  50 + @Operation(summary = "更新商品 SPU")
  51 + @PreAuthorize("@ss.hasPermission('product:spu:update')")
  52 + public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) {
  53 + productSpuService.updateSpu(updateReqVO);
  54 + return success(true);
  55 + }
  56 +
  57 + @DeleteMapping("/delete")
  58 + @Operation(summary = "删除商品 SPU")
  59 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  60 + @PreAuthorize("@ss.hasPermission('product:spu:delete')")
  61 + public CommonResult<Boolean> deleteSpu(@RequestParam("id") Long id) {
  62 + productSpuService.deleteSpu(id);
  63 + return success(true);
  64 + }
  65 +
  66 + @GetMapping("/get-detail")
  67 + @Operation(summary = "获得商品 SPU 明细")
  68 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  69 + @PreAuthorize("@ss.hasPermission('product:spu:query')")
  70 + public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
  71 + // 获得商品 SPU
  72 + ProductSpuDO spu = productSpuService.getSpu(id);
  73 + if (spu == null) {
  74 + throw exception(SPU_NOT_EXISTS);
  75 + }
  76 +
  77 + // 查询商品 SKU
  78 + List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), null);
  79 + // 查询商品属性
  80 + List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
  81 + .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
  82 + // 拼接
  83 + return success(ProductSpuConvert.INSTANCE.convert03(spu, skus, propertyValues));
  84 + }
  85 +
  86 + @GetMapping("/get-simple-list")
  87 + @Operation(summary = "获得商品 SPU 精简列表")
  88 + @PreAuthorize("@ss.hasPermission('product:spu:query')")
  89 + public CommonResult<List<ProductSpuSimpleRespVO>> getSpuSimpleList() {
  90 + List<ProductSpuDO> list = productSpuService.getSpuList();
  91 + return success(ProductSpuConvert.INSTANCE.convertList02(list));
  92 + }
  93 +
  94 + @GetMapping("/page")
  95 + @Operation(summary = "获得商品 SPU 分页")
  96 + @PreAuthorize("@ss.hasPermission('product:spu:query')")
  97 + public CommonResult<PageResult<ProductSpuRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) {
  98 + return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO)));
  99 + }
  100 +
  101 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
  5 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +
  9 +import javax.validation.constraints.NotEmpty;
  10 +import javax.validation.constraints.NotNull;
  11 +import java.util.List;
  12 +
  13 +/**
  14 +* 商品 SPU Base VO,提供给添加、修改、详细的子 VO 使用
  15 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  16 +*/
  17 +@Data
  18 +public class ProductSpuBaseVO {
  19 +
  20 + @Schema(description = "商品名称", required = true, example = "芋道")
  21 + @NotEmpty(message = "商品名称不能为空")
  22 + private String name;
  23 +
  24 + @Schema(description = "商品编码", example = "yudaoyuanma")
  25 + private String code;
  26 +
  27 + @Schema(description = "促销语", example = "好吃!")
  28 + private String sellPoint;
  29 +
  30 + @Schema(description = "商品详情", required = true, example = "我是商品描述")
  31 + @NotNull(message = "商品详情不能为空")
  32 + private String description;
  33 +
  34 + @Schema(description = "商品分类编号", required = true, example = "1")
  35 + @NotNull(message = "商品分类编号不能为空")
  36 + private Long categoryId;
  37 +
  38 + @Schema(description = "商品品牌编号", example = "1")
  39 + private Long brandId;
  40 +
  41 + @Schema(description = "商品图片的数组", required = true)
  42 + @NotNull(message = "商品图片的数组不能为空")
  43 + private List<String> picUrls;
  44 +
  45 + @Schema(description = "商品视频", required = true)
  46 + private String videoUrl;
  47 +
  48 + @Schema(description = "排序字段", required = true, example = "1")
  49 + private Integer sort;
  50 +
  51 + @Schema(description = "商品状态", required = true, example = "1")
  52 + @NotNull(message = "商品状态不能为空")
  53 + @InEnum(ProductSpuStatusEnum.class)
  54 + private Integer status;
  55 +
  56 + // ========== SKU 相关字段 =========
  57 +
  58 + @Schema(description = "规格类型", required = true, example = "1")
  59 + @NotNull(message = "规格类型不能为空")
  60 + @InEnum(ProductSpuSpecTypeEnum.class)
  61 + private Integer specType;
  62 +
  63 + @Schema(description = "是否展示库存", required = true, example = "true")
  64 + @NotNull(message = "是否展示库存不能为空")
  65 + private Boolean showStock;
  66 +
  67 + @Schema(description = "市场价", example = "1024")
  68 + private Integer marketPrice;
  69 +
  70 + // ========== 统计相关字段 =========
  71 +
  72 + @Schema(description = "虚拟销量", required = true, example = "1024")
  73 + @NotNull(message = "虚拟销量不能为空")
  74 + private Integer virtualSalesCount;
  75 +
  76 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuCreateReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
  2 +
  3 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import java.util.List;
  11 +
  12 +@Schema(description = "管理后台 - 商品 SPU 创建 Request VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class ProductSpuCreateReqVO extends ProductSpuBaseVO {
  17 +
  18 + /**
  19 + * SKU 数组
  20 + */
  21 + @Valid
  22 + private List<ProductSkuCreateOrUpdateReqVO> skus;
  23 +
  24 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
  2 +
  3 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
  4 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +import lombok.ToString;
  9 +
  10 +import java.util.List;
  11 +
  12 +@Schema(description = "管理后台 - 商品 SPU 详细 Response VO") // 包括关联的 SKU 等信息
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class ProductSpuDetailRespVO extends ProductSpuRespVO {
  17 +
  18 + // ========== SKU 相关字段 =========
  19 +
  20 + /**
  21 + * SKU 数组
  22 + */
  23 + private List<Sku> skus;
  24 +
  25 + @Schema(description = "管理后台 - 商品 SKU 详细 Response VO")
  26 + @Data
  27 + @EqualsAndHashCode(callSuper = true)
  28 + @ToString(callSuper = true)
  29 + public static class Sku extends ProductSkuBaseVO {
  30 +
  31 + /**
  32 + * 属性数组
  33 + */
  34 + private List<ProductPropertyValueDetailRespVO> properties;
  35 +
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuPageReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +@Schema(description = "管理后台 - 商品 SPU 分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +@ToString(callSuper = true)
  13 +public class ProductSpuPageReqVO extends PageParam {
  14 +
  15 + @Schema(description = "商品名称", example = "yutou")
  16 + private String name;
  17 +
  18 + @Schema(description = "商品编码", example = "yudaoyuanma")
  19 + private String code;
  20 +
  21 + @Schema(description = "分类编号", example = "1")
  22 + private Long categoryId;
  23 +
  24 + @Schema(description = "商品品牌编号", example = "1")
  25 + private Long brandId;
  26 +
  27 + @Schema(description = "上下架状态", example = "1")
  28 + private Integer status;
  29 +
  30 + @Schema(description = "销量最小值", example = "1")
  31 + private Integer salesCountMin;
  32 +
  33 + @Schema(description = "销量最大值", example = "1024")
  34 + private Integer salesCountMax;
  35 +
  36 + @Schema(description = "市场价最小值", example = "1")
  37 + private Integer marketPriceMin;
  38 +
  39 + @Schema(description = "市场价最大值", example = "1024")
  40 + private Integer marketPriceMax;
  41 +
  42 + @Schema(description = "是否库存告警", example = "true")
  43 + private Boolean alarmStock;
  44 +
  45 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 商品 SPU Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ProductSpuRespVO extends ProductSpuBaseVO {
  15 +
  16 + @Schema(description = "主键", required = true, example = "1")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间")
  20 + private LocalDateTime createTime;
  21 +
  22 + // ========== SKU 相关字段 =========
  23 +
  24 + @Schema(description = "库存", required = true, example = "true")
  25 + private Integer totalStock;
  26 +
  27 + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024")
  28 + private Integer minPrice;
  29 +
  30 + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024")
  31 + private Integer maxPrice;
  32 +
  33 + @Schema(description = "商品销量", example = "1024")
  34 + private Integer salesCount;
  35 +
  36 + // ========== 统计相关字段 =========
  37 +
  38 + @Schema(description = "点击量", example = "1024")
  39 + private Integer clickCount;
  40 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuSimpleRespVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 商品 SPU 精简 Response VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class ProductSpuSimpleRespVO extends ProductSpuBaseVO {
  13 +
  14 + @Schema(description = "主键", required = true, example = "1")
  15 + private Long id;
  16 +
  17 + @Schema(description = "商品名称", required = true, example = "芋道")
  18 + private String name;
  19 +
  20 + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024")
  21 + private Integer minPrice;
  22 +
  23 + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024")
  24 + private Integer maxPrice;
  25 +
  26 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuUpdateReqVO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
  2 +
  3 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import javax.validation.constraints.NotNull;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - 商品 SPU 更新 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class ProductSpuUpdateReqVO extends ProductSpuBaseVO {
  18 +
  19 + @Schema(description = "商品编号", required = true, example = "1")
  20 + @NotNull(message = "商品编号不能为空")
  21 + private Long id;
  22 +
  23 + /**
  24 + * SKU 数组
  25 + */
  26 + @Valid
  27 + private List<ProductSkuCreateOrUpdateReqVO> skus;
  28 +
  29 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/AppCategoryController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.category;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO;
  5 +import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert;
  6 +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
  7 +import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
  8 +import io.swagger.v3.oas.annotations.Operation;
  9 +import io.swagger.v3.oas.annotations.tags.Tag;
  10 +import org.springframework.validation.annotation.Validated;
  11 +import org.springframework.web.bind.annotation.GetMapping;
  12 +import org.springframework.web.bind.annotation.RequestMapping;
  13 +import org.springframework.web.bind.annotation.RestController;
  14 +
  15 +import javax.annotation.Resource;
  16 +import java.util.Comparator;
  17 +import java.util.List;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +
  21 +@Tag(name = "用户 APP - 商品分类")
  22 +@RestController
  23 +@RequestMapping("/product/category")
  24 +@Validated
  25 +public class AppCategoryController {
  26 +
  27 + @Resource
  28 + private ProductCategoryService categoryService;
  29 +
  30 + @GetMapping("/list")
  31 + @Operation(summary = "获得商品分类列表")
  32 + public CommonResult<List<AppCategoryRespVO>> getProductCategoryList() {
  33 + List<ProductCategoryDO> list = categoryService.getEnableCategoryList();
  34 + list.sort(Comparator.comparing(ProductCategoryDO::getSort));
  35 + return success(ProductCategoryConvert.INSTANCE.convertList03(list));
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/category/vo/AppCategoryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.category.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotBlank;
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@Data
  10 +@Schema(description = "用户 APP - 商品分类 Response VO")
  11 +public class AppCategoryRespVO {
  12 +
  13 + @Schema(description = "分类编号", required = true, example = "2")
  14 + private Long id;
  15 +
  16 + @Schema(description = "父分类编号", required = true, example = "1")
  17 + @NotNull(message = "父分类编号不能为空")
  18 + private Long parentId;
  19 +
  20 + @Schema(description = "分类名称", required = true, example = "办公文具")
  21 + @NotBlank(message = "分类名称不能为空")
  22 + private String name;
  23 +
  24 + @Schema(description = "分类图片", required = true)
  25 + @NotBlank(message = "分类图片不能为空")
  26 + private String picUrl;
  27 +
  28 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/package-info.java 0 → 100644
  1 +/**
  2 + * 占位符,无时间作用,避免 package 缩进
  3 + */
  4 +package cn.iocoder.yudao.module.product.controller.app.property;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/property/package-info.java 0 → 100644
  1 +/**
  2 + * 占位符,无时间作用,避免 package 缩进
  3 + */
  4 +package cn.iocoder.yudao.module.product.controller.app.property.vo.property;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/property/vo/value/AppProductPropertyValueDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.property.vo.value;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户 App - 商品属性值的明细 Response VO")
  7 +@Data
  8 +public class AppProductPropertyValueDetailRespVO {
  9 +
  10 + @Schema(description = "属性的编号", required = true, example = "1")
  11 + private Long propertyId;
  12 +
  13 + @Schema(description = "属性的名称", required = true, example = "颜色")
  14 + private String propertyName;
  15 +
  16 + @Schema(description = "属性值的编号", required = true, example = "1024")
  17 + private Long valueId;
  18 +
  19 + @Schema(description = "属性值的名称", required = true, example = "红色")
  20 + private String valueName;
  21 +
  22 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.http 0 → 100644
  1 +### 获得订单交易的分页 TODO
  2 +GET {{appApi}}/product/spu/page?pageNo=1&pageSize=10
  3 +Authorization: Bearer {{appToken}}
  4 +tenant-id: {{appTenentId}}
  5 +
  6 +### 获得商品 SPU 明细
  7 +GET {{appApi}}/product/spu/get-detail?id=4
  8 +tenant-id: {{appTenentId}}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
  7 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
  8 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
  9 +import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
  10 +import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
  11 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  12 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  13 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
  14 +import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
  15 +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
  16 +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
  17 +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
  18 +import io.swagger.v3.oas.annotations.Operation;
  19 +import io.swagger.v3.oas.annotations.Parameter;
  20 +import io.swagger.v3.oas.annotations.tags.Tag;
  21 +import org.springframework.validation.annotation.Validated;
  22 +import org.springframework.web.bind.annotation.GetMapping;
  23 +import org.springframework.web.bind.annotation.RequestMapping;
  24 +import org.springframework.web.bind.annotation.RequestParam;
  25 +import org.springframework.web.bind.annotation.RestController;
  26 +
  27 +import javax.annotation.Resource;
  28 +import javax.validation.Valid;
  29 +import java.util.List;
  30 +
  31 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  32 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  33 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE;
  34 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
  35 +
  36 +@Tag(name = "用户 APP - 商品 SPU")
  37 +@RestController
  38 +@RequestMapping("/product/spu")
  39 +@Validated
  40 +public class AppProductSpuController {
  41 +
  42 + @Resource
  43 + private ProductSpuService productSpuService;
  44 + @Resource
  45 + private ProductSkuService productSkuService;
  46 + @Resource
  47 + private ProductPropertyValueService productPropertyValueService;
  48 +
  49 + @GetMapping("/page")
  50 + @Operation(summary = "获得商品 SPU 分页")
  51 + public CommonResult<PageResult<AppProductSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
  52 + PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus());
  53 + return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult));
  54 + }
  55 +
  56 + @GetMapping("/get-detail")
  57 + @Operation(summary = "获得商品 SPU 明细")
  58 + @Parameter(name = "id", description = "编号", required = true)
  59 + public CommonResult<AppProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
  60 + // 获得商品 SPU
  61 + ProductSpuDO spu = productSpuService.getSpu(id);
  62 + if (spu == null) {
  63 + throw exception(SPU_NOT_EXISTS);
  64 + }
  65 + if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
  66 + throw exception(SPU_NOT_ENABLE);
  67 + }
  68 +
  69 + // 查询商品 SKU
  70 + List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(),
  71 + CommonStatusEnum.ENABLE.getStatus());
  72 + // 查询商品属性
  73 + List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
  74 + .getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
  75 + // 拼接
  76 + return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues));
  77 + }
  78 +
  79 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.spu.vo;
  2 +
  3 +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +
  9 +@Schema(description = "用户 App - 商品 SPU 明细 Response VO")
  10 +@Data
  11 +public class AppProductSpuDetailRespVO {
  12 +
  13 + @Schema(description = "商品 SPU 编号", required = true, example = "1")
  14 + private Long id;
  15 +
  16 + // ========== 基本信息 =========
  17 +
  18 + @Schema(description = "商品名称", required = true, example = "芋道")
  19 + private String name;
  20 +
  21 + @Schema(description = "促销语", example = "好吃!")
  22 + private String sellPoint;
  23 +
  24 + @Schema(description = "商品详情", required = true, example = "我是商品描述")
  25 + private String description;
  26 +
  27 + @Schema(description = "商品分类编号", required = true, example = "1")
  28 + private Long categoryId;
  29 +
  30 + @Schema(description = "商品图片的数组", required = true)
  31 + private List<String> picUrls;
  32 +
  33 + @Schema(description = "商品视频", required = true)
  34 + private String videoUrl;
  35 +
  36 + // ========== SKU 相关字段 =========
  37 +
  38 + @Schema(description = "规格类型", required = true, example = "1")
  39 + private Integer specType;
  40 +
  41 + @Schema(description = "是否展示库存", required = true, example = "true")
  42 + private Boolean showStock;
  43 +
  44 + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024")
  45 + private Integer minPrice;
  46 +
  47 + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024")
  48 + private Integer maxPrice;
  49 +
  50 + /**
  51 + * SKU 数组
  52 + */
  53 + private List<Sku> skus;
  54 +
  55 + // ========== 统计相关字段 =========
  56 +
  57 + @Schema(description = "商品销量", required = true, example = "1024")
  58 + private Integer salesCount;
  59 +
  60 + @Schema(description = "用户 App - 商品 SPU 明细的 SKU 信息")
  61 + @Data
  62 + public static class Sku {
  63 +
  64 + @Schema(description = "商品 SKU 编号", example = "1")
  65 + private Long id;
  66 +
  67 + /**
  68 + * 商品属性数组
  69 + */
  70 + private List<AppProductPropertyValueDetailRespVO> properties;
  71 +
  72 + @Schema(description = "销售价格,单位:分", required = true, example = "1024")
  73 + private Integer price;
  74 +
  75 + @Schema(description = "市场价", example = "1024")
  76 + private Integer marketPrice;
  77 +
  78 + @Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
  79 + private String picUrl;
  80 +
  81 + @Schema(description = "库存", required = true, example = "1")
  82 + private Integer stock;
  83 +
  84 + @Schema(description = "商品重量", example = "1") // 单位:kg 千克
  85 + private Double weight;
  86 +
  87 + @Schema(description = "商品体积", example = "1024") // 单位:m^3 平米
  88 + private Double volume;
  89 + }
  90 +
  91 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.spu.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotEmpty;
  7 +import javax.validation.constraints.NotNull;
  8 +import java.util.List;
  9 +
  10 +@Schema(description = "用户 App - 商品 SPU 分页项 Response VO")
  11 +@Data
  12 +public class AppProductSpuPageItemRespVO {
  13 +
  14 + @Schema(description = "商品 SPU 编号", required = true, example = "1")
  15 + private Long id;
  16 +
  17 + @Schema(description = "商品名称", required = true, example = "芋道")
  18 + @NotEmpty(message = "商品名称不能为空")
  19 + private String name;
  20 +
  21 + @Schema(description = "分类编号", required = true)
  22 + @NotNull(message = "分类编号不能为空")
  23 + private Long categoryId;
  24 +
  25 + @Schema(description = "商品图片的数组", required = true)
  26 + private List<String> picUrls;
  27 +
  28 + @Schema(description = " 最小价格,单位使用:分", required = true, example = "1024")
  29 + private Integer minPrice;
  30 +
  31 + @Schema(description = "最大价格,单位使用:分", required = true, example = "1024")
  32 + private Integer maxPrice;
  33 +
  34 + // ========== 统计相关字段 =========
  35 +
  36 + @Schema(description = "商品销量", example = "1024")
  37 + private Integer salesCount;
  38 +
  39 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.app.spu.vo;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import com.fasterxml.jackson.annotation.JsonIgnore;
  6 +import io.swagger.v3.oas.annotations.media.Schema;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +import lombok.ToString;
  10 +
  11 +import javax.validation.constraints.AssertTrue;
  12 +
  13 +@Schema(description = "用户 App - 商品 SPU 分页 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class AppProductSpuPageReqVO extends PageParam {
  18 +
  19 + public static final String SORT_FIELD_PRICE = "price";
  20 + public static final String SORT_FIELD_SALES_COUNT = "salesCount";
  21 +
  22 + @Schema(description = "分类编号", example = "1")
  23 + private Long categoryId;
  24 +
  25 + @Schema(description = "关键字", example = "好看")
  26 + private String keyword;
  27 +
  28 + @Schema(description = "排序字段", example = "price") // 参见 AppSpuPageReqVO.SORT_FIELD_XXX 常量
  29 + private String sortField;
  30 +
  31 + @Schema(description = "排序方式", example = "true")
  32 + private Boolean sortAsc;
  33 +
  34 + @AssertTrue(message = "排序字段不合法")
  35 + @JsonIgnore
  36 + public boolean isSortFieldValid() {
  37 + if (StrUtil.isEmpty(sortField)) {
  38 + return true;
  39 + }
  40 + return StrUtil.equalsAny(sortField, SORT_FIELD_PRICE, SORT_FIELD_SALES_COUNT);
  41 + }
  42 +
  43 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/brand/ProductBrandConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.convert.brand;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandRespVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO;
  7 +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
  8 +import org.mapstruct.Mapper;
  9 +import org.mapstruct.factory.Mappers;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 品牌 Convert
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Mapper
  19 +public interface ProductBrandConvert {
  20 +
  21 + ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class);
  22 +
  23 + ProductBrandDO convert(ProductBrandCreateReqVO bean);
  24 +
  25 + ProductBrandDO convert(ProductBrandUpdateReqVO bean);
  26 +
  27 + ProductBrandRespVO convert(ProductBrandDO bean);
  28 +
  29 + List<ProductBrandRespVO> convertList(List<ProductBrandDO> list);
  30 +
  31 + PageResult<ProductBrandRespVO> convertPage(PageResult<ProductBrandDO> page);
  32 +
  33 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/category/ProductCategoryConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.convert.category;
  2 +
  3 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
  4 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO;
  5 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
  6 +import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO;
  7 +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
  8 +import org.mapstruct.Mapper;
  9 +import org.mapstruct.factory.Mappers;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 商品分类 Convert
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@Mapper
  19 +public interface ProductCategoryConvert {
  20 +
  21 + ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
  22 +
  23 + ProductCategoryDO convert(ProductCategoryCreateReqVO bean);
  24 +
  25 + ProductCategoryDO convert(ProductCategoryUpdateReqVO bean);
  26 +
  27 + ProductCategoryRespVO convert(ProductCategoryDO bean);
  28 +
  29 + List<ProductCategoryRespVO> convertList(List<ProductCategoryDO> list);
  30 +
  31 + List<AppCategoryRespVO> convertList03(List<ProductCategoryDO> list);
  32 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.convert.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
  8 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO;
  9 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
  10 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
  11 +import org.mapstruct.Mapper;
  12 +import org.mapstruct.factory.Mappers;
  13 +
  14 +import java.util.List;
  15 +import java.util.Map;
  16 +
  17 +/**
  18 + * 属性项 Convert
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +@Mapper
  23 +public interface ProductPropertyConvert {
  24 +
  25 + ProductPropertyConvert INSTANCE = Mappers.getMapper(ProductPropertyConvert.class);
  26 +
  27 + ProductPropertyDO convert(ProductPropertyCreateReqVO bean);
  28 +
  29 + ProductPropertyDO convert(ProductPropertyUpdateReqVO bean);
  30 +
  31 + ProductPropertyRespVO convert(ProductPropertyDO bean);
  32 +
  33 + List<ProductPropertyRespVO> convertList(List<ProductPropertyDO> list);
  34 +
  35 + PageResult<ProductPropertyRespVO> convertPage(PageResult<ProductPropertyDO> page);
  36 +
  37 + default List<ProductPropertyAndValueRespVO> convertList(List<ProductPropertyDO> keys, List<ProductPropertyValueDO> values) {
  38 + Map<Long, List<ProductPropertyValueDO>> valueMap = CollectionUtils.convertMultiMap(values, ProductPropertyValueDO::getPropertyId);
  39 + return CollectionUtils.convertList(keys, key -> {
  40 + ProductPropertyAndValueRespVO respVO = convert02(key);
  41 + respVO.setValues(convertList02(valueMap.get(key.getId())));
  42 + return respVO;
  43 + });
  44 + }
  45 + ProductPropertyAndValueRespVO convert02(ProductPropertyDO bean);
  46 + List<ProductPropertyAndValueRespVO.Value> convertList02(List<ProductPropertyValueDO> list);
  47 +
  48 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/propertyvalue/ProductPropertyValueConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.convert.propertyvalue;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
  8 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
  9 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
  10 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
  11 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
  12 +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
  13 +import org.mapstruct.Mapper;
  14 +import org.mapstruct.factory.Mappers;
  15 +
  16 +import java.util.List;
  17 +import java.util.Map;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  20 +
  21 +/**
  22 + * 属性值 Convert
  23 + *
  24 + * @author 芋道源码
  25 + */
  26 +@Mapper
  27 +public interface ProductPropertyValueConvert {
  28 +
  29 + ProductPropertyValueConvert INSTANCE = Mappers.getMapper(ProductPropertyValueConvert.class);
  30 +
  31 + ProductPropertyValueDO convert(ProductPropertyValueCreateReqVO bean);
  32 +
  33 + ProductPropertyValueDO convert(ProductPropertyValueUpdateReqVO bean);
  34 +
  35 + ProductPropertyValueRespVO convert(ProductPropertyValueDO bean);
  36 +
  37 + List<ProductPropertyValueRespVO> convertList(List<ProductPropertyValueDO> list);
  38 +
  39 + PageResult<ProductPropertyValueRespVO> convertPage(PageResult<ProductPropertyValueDO> page);
  40 +
  41 + default List<ProductPropertyValueDetailRespBO> convertList(List<ProductPropertyValueDO> values, List<ProductPropertyDO> keys) {
  42 + Map<Long, ProductPropertyDO> keyMap = convertMap(keys, ProductPropertyDO::getId);
  43 + return CollectionUtils.convertList(values, value -> {
  44 + ProductPropertyValueDetailRespBO valueDetail = new ProductPropertyValueDetailRespBO()
  45 + .setValueId(value.getId()).setValueName(value.getName());
  46 + // 设置属性项
  47 + MapUtils.findAndThen(keyMap, value.getPropertyId(),
  48 + key -> valueDetail.setPropertyId(key.getId()).setPropertyName(key.getName()));
  49 + return valueDetail;
  50 + });
  51 + }
  52 +
  53 + List<ProductPropertyValueDetailRespDTO> convertList02(List<ProductPropertyValueDetailRespBO> list);
  54 +
  55 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/sku/ProductSkuConvert.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.convert.sku;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  6 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
  8 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
  9 +import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
  10 +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO;
  11 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  12 +import org.mapstruct.Mapper;
  13 +import org.mapstruct.factory.Mappers;
  14 +
  15 +import java.util.*;
  16 +import java.util.stream.Collectors;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  19 +
  20 +/**
  21 + * 商品 SKU Convert
  22 + *
  23 + * @author 芋道源码
  24 + */
  25 +@Mapper
  26 +public interface ProductSkuConvert {
  27 +
  28 + ProductSkuConvert INSTANCE = Mappers.getMapper(ProductSkuConvert.class);
  29 +
  30 + ProductSkuDO convert(ProductSkuCreateOrUpdateReqVO bean);
  31 +
  32 + ProductSkuRespVO convert(ProductSkuDO bean);
  33 +
  34 + List<ProductSkuRespVO> convertList(List<ProductSkuDO> list);
  35 +
  36 + List<ProductSkuDO> convertList06(List<ProductSkuCreateOrUpdateReqVO> list);
  37 +
  38 + default List<ProductSkuDO> convertList06(List<ProductSkuCreateOrUpdateReqVO> list, Long spuId, String spuName) {
  39 + List<ProductSkuDO> result = convertList06(list);
  40 + result.forEach(item -> item.setSpuId(spuId).setSpuName(spuName));
  41 + return result;
  42 + }
  43 +
  44 + ProductSkuRespDTO convert02(ProductSkuDO bean);
  45 +
  46 + List<ProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> list);
  47 +
  48 + List<ProductSkuRespDTO> convertList04(List<ProductSkuDO> list);
  49 +
  50 + List<ProductSkuOptionRespVO> convertList05(List<ProductSkuDO> skus);
  51 +
  52 + /**
  53 + * 获得 SPU 的库存变化 Map
  54 + *
  55 + * @param items SKU 库存变化
  56 + * @param skus SKU 列表
  57 + * @return SPU 的库存变化 Map
  58 + */
  59 + default Map<Long, Integer> convertSpuStockMap(List<ProductSkuUpdateStockReqDTO.Item> items,
  60 + List<ProductSkuDO> skus) {
  61 + Map<Long, Long> skuIdAndSpuIdMap = convertMap(skus, ProductSkuDO::getId, ProductSkuDO::getSpuId); // SKU 与 SKU 编号的 Map 关系
  62 + Map<Long, Integer> spuIdAndStockMap = new HashMap<>(); // SPU 的库存变化 Map 关系
  63 + items.forEach(item -> {
  64 + Long spuId = skuIdAndSpuIdMap.get(item.getId());
  65 + if (spuId == null) {
  66 + return;
  67 + }
  68 + Integer stock = spuIdAndStockMap.getOrDefault(spuId, 0) + item.getIncrCount();
  69 + spuIdAndStockMap.put(spuId, stock);
  70 + });
  71 + return spuIdAndStockMap;
  72 + }
  73 +
  74 + default Collection<Long> convertPropertyValueIds(List<ProductSkuDO> list) {
  75 + if (CollUtil.isEmpty(list)) {
  76 + return new HashSet<>();
  77 + }
  78 + return list.stream().filter(item -> item.getProperties() != null)
  79 + .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
  80 + .map(ProductSkuDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合
  81 + .collect(Collectors.toSet());
  82 + }
  83 +
  84 + default String buildPropertyKey(ProductSkuDO bean) {
  85 + if (CollUtil.isEmpty(bean.getProperties())) {
  86 + return StrUtil.EMPTY;
  87 + }
  88 + List<ProductSkuDO.Property> properties = new ArrayList<>(bean.getProperties());
  89 + properties.sort(Comparator.comparing(ProductSkuDO.Property::getValueId));
  90 + return properties.stream().map(m -> String.valueOf(m.getValueId())).collect(Collectors.joining());
  91 + }
  92 +
  93 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.convert.spu;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
  8 +import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
  9 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
  10 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
  11 +import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
  12 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  13 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  14 +import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
  15 +import org.mapstruct.Mapper;
  16 +import org.mapstruct.factory.Mappers;
  17 +
  18 +import java.util.ArrayList;
  19 +import java.util.List;
  20 +import java.util.Map;
  21 +
  22 +import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
  23 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  24 +
  25 +/**
  26 + * 商品 SPU Convert
  27 + *
  28 + * @author 芋道源码
  29 + */
  30 +@Mapper
  31 +public interface ProductSpuConvert {
  32 +
  33 + ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
  34 +
  35 + ProductSpuDO convert(ProductSpuCreateReqVO bean);
  36 +
  37 + ProductSpuDO convert(ProductSpuUpdateReqVO bean);
  38 +
  39 + List<ProductSpuDO> convertList(List<ProductSpuDO> list);
  40 +
  41 + PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuDO> page);
  42 +
  43 + ProductSpuPageReqVO convert(AppProductSpuPageReqVO bean);
  44 +
  45 + List<ProductSpuRespDTO> convertList2(List<ProductSpuDO> list);
  46 +
  47 + List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
  48 +
  49 + default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus,
  50 + List<ProductPropertyValueDetailRespBO> propertyValues) {
  51 + AppProductSpuDetailRespVO spuVO = convert02(spu)
  52 + .setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0));
  53 + spuVO.setSkus(convertList03(skus));
  54 + // 处理商品属性
  55 + Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId);
  56 + for (int i = 0; i < skus.size(); i++) {
  57 + List<ProductSkuDO.Property> properties = skus.get(i).getProperties();
  58 + if (CollUtil.isEmpty(properties)) {
  59 + continue;
  60 + }
  61 + AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
  62 + sku.setProperties(new ArrayList<>(properties.size()));
  63 + // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
  64 + properties.forEach(property -> {
  65 + ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId());
  66 + if (propertyValue == null) {
  67 + return;
  68 + }
  69 + sku.getProperties().add(convert03(propertyValue));
  70 + });
  71 + }
  72 + return spuVO;
  73 + }
  74 + AppProductSpuDetailRespVO convert02(ProductSpuDO spu);
  75 + List<AppProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus);
  76 + AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue);
  77 +
  78 + PageResult<AppProductSpuPageItemRespVO> convertPage02(PageResult<ProductSpuDO> page);
  79 +
  80 + default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus,
  81 + List<ProductPropertyValueDetailRespBO> propertyValues) {
  82 + ProductSpuDetailRespVO spuVO = convert03(spu);
  83 + spuVO.setSkus(convertList04(skus));
  84 + // 处理商品属性
  85 + Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId);
  86 + for (int i = 0; i < skus.size(); i++) {
  87 + List<ProductSkuDO.Property> properties = skus.get(i).getProperties();
  88 + if (CollUtil.isEmpty(properties)) {
  89 + continue;
  90 + }
  91 + ProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
  92 + sku.setProperties(new ArrayList<>(properties.size()));
  93 + // 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
  94 + properties.forEach(property -> {
  95 + ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId());
  96 + if (propertyValue == null) {
  97 + return;
  98 + }
  99 + sku.getProperties().add(convert04(propertyValue));
  100 + });
  101 + }
  102 + return spuVO;
  103 + }
  104 + ProductSpuDetailRespVO convert03(ProductSpuDO spu);
  105 + List<ProductSpuDetailRespVO.Sku> convertList04(List<ProductSkuDO> skus);
  106 + ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue);
  107 +
  108 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/brand/ProductBrandDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.brand;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * 商品品牌 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("product_brand")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +@Builder
  19 +@NoArgsConstructor
  20 +@AllArgsConstructor
  21 +public class ProductBrandDO extends BaseDO {
  22 +
  23 + /**
  24 + * 品牌编号
  25 + */
  26 + @TableId
  27 + private Long id;
  28 + /**
  29 + * 品牌名称
  30 + */
  31 + private String name;
  32 + /**
  33 + * 品牌图片
  34 + */
  35 + private String picUrl;
  36 + /**
  37 + * 品牌排序
  38 + */
  39 + private Integer sort;
  40 + /**
  41 + * 品牌描述
  42 + */
  43 + private String description;
  44 + /**
  45 + * 状态
  46 + *
  47 + * 枚举 {@link CommonStatusEnum}
  48 + */
  49 + private Integer status;
  50 +
  51 + // TODO 芋艿:firstLetter 首字母
  52 +
  53 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/category/ProductCategoryDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.category;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * 商品分类 DO
  11 + *
  12 + * 商品分类一共两类:
  13 + * 1)一级分类:{@link #parentId} 等于 0
  14 + * 2)二级 + 三级分类:{@link #parentId} 不等于 0
  15 + *
  16 + * @author 芋道源码
  17 + */
  18 +@TableName("product_category")
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class ProductCategoryDO extends BaseDO {
  26 +
  27 + /**
  28 + * 父分类编号 - 根分类
  29 + */
  30 + public static final Long PARENT_ID_NULL = 0L;
  31 +
  32 + /**
  33 + * 分类编号
  34 + */
  35 + @TableId
  36 + private Long id;
  37 + /**
  38 + * 父分类编号
  39 + */
  40 + private Long parentId;
  41 + /**
  42 + * 分类名称
  43 + */
  44 + private String name;
  45 + /**
  46 + * 分类图片
  47 + *
  48 + * 一级分类:推荐 200 x 100 分辨率
  49 + * 二级 + 三级分类:推荐 100 x 100 分辨率
  50 + */
  51 + private String picUrl;
  52 + /**
  53 + * 分类排序
  54 + */
  55 + private Integer sort;
  56 + /**
  57 + * 分类描述
  58 + */
  59 + private String description;
  60 + /**
  61 + * 开启状态
  62 + *
  63 + * 枚举 {@link CommonStatusEnum}
  64 + */
  65 + private Integer status;
  66 +
  67 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/comment/ProductCommentDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.comment;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  5 +import cn.iocoder.yudao.module.product.enums.comment.ProductCommentAuditStatusEnum;
  6 +import com.baomidou.mybatisplus.annotation.KeySequence;
  7 +import com.baomidou.mybatisplus.annotation.TableField;
  8 +import com.baomidou.mybatisplus.annotation.TableId;
  9 +import com.baomidou.mybatisplus.annotation.TableName;
  10 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  11 +import lombok.*;
  12 +
  13 +import java.time.LocalDateTime;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * 商品评论 DO
  18 + *
  19 + * @author 芋道源码
  20 + */
  21 +@TableName("product_comment")
  22 +@KeySequence("product_comment_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = true)
  25 +@ToString(callSuper = true)
  26 +@Builder
  27 +@NoArgsConstructor
  28 +@AllArgsConstructor
  29 +public class ProductCommentDO extends BaseDO {
  30 +
  31 + /**
  32 + * 评论编号,主键自增
  33 + */
  34 + @TableId
  35 + private Long id;
  36 + /**
  37 + * 商品 SPU 编号
  38 + *
  39 + * 关联 {@link ProductSpuDO#getId()}
  40 + */
  41 + private Long spuId;
  42 + /**
  43 + * 交易订单编号
  44 + *
  45 + * 关联 TradeOrderDO 的 id 编号
  46 + */
  47 + private Long orderId;
  48 + /**
  49 + * 交易订单项编号
  50 + *
  51 + * 关联 TradeOrderItemDO 的 id 编号
  52 + */
  53 + private Long orderItemId;
  54 + /**
  55 + * 审核状态
  56 + *
  57 + * 枚举 {@link ProductCommentAuditStatusEnum}
  58 + */
  59 + private Integer auditStatus;
  60 +
  61 + /**
  62 + * 用户编号
  63 + *
  64 + * 关联 MemberUserDO 的 id 编号
  65 + */
  66 + private Long userId;
  67 + /**
  68 + * 用户 IP
  69 + */
  70 + private String userIp;
  71 + /**
  72 + * 是否匿名
  73 + */
  74 + private Boolean anonymous;
  75 + /**
  76 + * 评论内容
  77 + */
  78 + private String content;
  79 + /**
  80 + * 评论图片地址数组
  81 + */
  82 + @TableField(typeHandler = JacksonTypeHandler.class)
  83 + private List<String> picUrls;
  84 + /**
  85 + * 描述相符星级
  86 + *
  87 + * 1-5 星
  88 + */
  89 + private Integer descriptionScore;
  90 + /**
  91 + * 商品评论星级
  92 + *
  93 + * 1-5 星
  94 + */
  95 + private Integer productScore;
  96 + /**
  97 + * 服务评论星级
  98 + *
  99 + * 1-5 星
  100 + */
  101 + private Integer serviceScore;
  102 + /**
  103 + * 物流评论星级
  104 + *
  105 + * 1-5 星
  106 + */
  107 + private Integer expressComment;
  108 +
  109 + /**
  110 + * 商家是否回复
  111 + */
  112 + private Boolean replied;
  113 + /**
  114 + * 商家回复内容
  115 + */
  116 + private String replyContent;
  117 + /**
  118 + * 商家回复时间
  119 + */
  120 + private LocalDateTime replyTime;
  121 +
  122 + /**
  123 + * 有用的计数
  124 + *
  125 + * 其他用户看到评论时,可点击「有用」按钮
  126 + */
  127 + private Integer usefulCount;
  128 +
  129 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/delivery/DeliveryTemplateDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.delivery;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * 配送模板 SPU DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("delivery_template")
  15 +@KeySequence("delivery_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class DeliveryTemplateDO extends BaseDO {
  23 +
  24 + /**
  25 + * 编号,自增
  26 + */
  27 + @TableId
  28 + private Long id;
  29 +
  30 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/favorite/ProductFavoriteDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.favorite;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +/**
  11 + * 商品收藏 DO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@TableName("product_favorite")
  16 +@KeySequence("product_favorite_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class ProductFavoriteDO extends BaseDO {
  24 +
  25 + /**
  26 + * 编号,主键自增
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 用户编号
  32 + *
  33 + * 关联 MemberUserDO 的 id 编号
  34 + */
  35 + private Long userId;
  36 + /**
  37 + * 商品 SPU 编号
  38 + *
  39 + * 关联 {@link ProductSpuDO#getId()}
  40 + */
  41 + private Long spuId;
  42 +
  43 + // TODO 芋艿:type 1 收藏;2 点赞
  44 +
  45 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupBindDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.group;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.*;
  9 +
  10 +/**
  11 + * 商品分组的绑定 DO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@TableName("product_group_bind")
  16 +@KeySequence("product_group_bind_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class ProductGroupBindDO extends BaseDO {
  24 +
  25 + /**
  26 + * 编号,自增
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 商品分组编号
  32 + *
  33 + * 关联 {@link ProductGroupDO#getId()}
  34 + */
  35 + private Long groupId;
  36 + /**
  37 + * 商品 SPU 编号
  38 + *
  39 + * 关联 {@link ProductSpuDO#getId()}
  40 + */
  41 + private Long spuId;
  42 +
  43 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/group/ProductGroupDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.group;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.yudao.module.product.enums.group.ProductGroupStyleEnum;
  6 +import com.baomidou.mybatisplus.annotation.KeySequence;
  7 +import com.baomidou.mybatisplus.annotation.TableId;
  8 +import com.baomidou.mybatisplus.annotation.TableName;
  9 +import lombok.*;
  10 +
  11 +/**
  12 + * 商品分组 DO
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@TableName("product_group")
  17 +@KeySequence("product_group_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class ProductGroupDO extends BaseDO {
  25 +
  26 + /**
  27 + * 商品分组编号,自增
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + /**
  32 + * 分组名称
  33 + */
  34 + private String name;
  35 + /**
  36 + * 状态
  37 + *
  38 + * 枚举 {@link CommonStatusEnum}
  39 + */
  40 + private Integer status;
  41 + /**
  42 + * 商品数量
  43 + */
  44 + private Integer count;
  45 + /**
  46 + * 排序
  47 + */
  48 + private Integer sort;
  49 + /**
  50 + * 风格,用于 APP 首页展示商品的样式
  51 + *
  52 + * 枚举 {@link ProductGroupStyleEnum}
  53 + */
  54 + private Integer style;
  55 + /**
  56 + * 是否默认
  57 + *
  58 + * true - 系统默认,不允许删除
  59 + * false - 自定义,允许删除
  60 + */
  61 + private Boolean defaulted;
  62 +
  63 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.property;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * 商品属性项 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("product_property")
  15 +@KeySequence("product_property_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class ProductPropertyDO extends BaseDO {
  23 +
  24 + /**
  25 + * 主键
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 名称
  31 + */
  32 + private String name;
  33 + /**
  34 + * 备注
  35 + */
  36 + private String remark;
  37 +
  38 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/property/ProductPropertyValueDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.property;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +
  10 +/**
  11 + * 商品属性值 DO
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@TableName("product_property_value")
  16 +@KeySequence("product_property_value_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  17 +@Data
  18 +@EqualsAndHashCode(callSuper = true)
  19 +@ToString(callSuper = true)
  20 +@Builder
  21 +@NoArgsConstructor
  22 +@AllArgsConstructor
  23 +public class ProductPropertyValueDO extends BaseDO {
  24 +
  25 + /**
  26 + * 主键
  27 + */
  28 + @TableId
  29 + private Long id;
  30 + /**
  31 + * 属性项的编号
  32 + *
  33 + * 关联 {@link ProductPropertyDO#getId()}
  34 + */
  35 + private Long propertyId;
  36 + /**
  37 + * 名称
  38 + */
  39 + private String name;
  40 + /**
  41 + * 备注
  42 + *
  43 + */
  44 + private String remark;
  45 +
  46 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/search/ProductHotSearchDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.search;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +/**
  10 + * 商品热搜关键字 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("product_hot_search")
  15 +@KeySequence("product_hot_search_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class ProductHotSearchDO extends BaseDO {
  23 +
  24 + /**
  25 + * 编号,主键自增
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 关键字
  31 + */
  32 + private String name;
  33 + /**
  34 + * 内容
  35 + */
  36 + private String content;
  37 +
  38 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/shop/ShopDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.shop;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableName;
  6 +import lombok.*;
  7 +
  8 +// TODO 芋艿:待设计
  9 +/**
  10 + * 店铺 DO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@TableName("shop")
  15 +@KeySequence("shop_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class ShopDO extends BaseDO {
  23 +
  24 + private Long id;
  25 +
  26 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.sku;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  5 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  6 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
  7 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  9 +import com.baomidou.mybatisplus.annotation.KeySequence;
  10 +import com.baomidou.mybatisplus.annotation.TableField;
  11 +import com.baomidou.mybatisplus.annotation.TableId;
  12 +import com.baomidou.mybatisplus.annotation.TableName;
  13 +import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
  14 +import lombok.*;
  15 +
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * 商品 SKU DO
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@TableName(value = "product_sku",autoResultMap = true)
  24 +@KeySequence("product_sku_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = true)
  27 +@ToString(callSuper = true)
  28 +@Builder
  29 +@NoArgsConstructor
  30 +@AllArgsConstructor
  31 +public class ProductSkuDO extends BaseDO {
  32 +
  33 + /**
  34 + * 商品 SKU 编号,自增
  35 + */
  36 + @TableId
  37 + private Long id;
  38 + /**
  39 + * SPU 编号
  40 + * <p>
  41 + * 关联 {@link ProductSpuDO#getId()}
  42 + */
  43 + private Long spuId;
  44 + /**
  45 + * SPU 名字
  46 + *
  47 + * 冗余 {@link ProductSkuDO#getSpuName()}
  48 + */
  49 + private String spuName;
  50 + /**
  51 + * 属性数组,JSON 格式
  52 + */
  53 + @TableField(typeHandler = PropertyTypeHandler.class)
  54 + private List<Property> properties;
  55 + /**
  56 + * 销售价格,单位:分
  57 + */
  58 + private Integer price;
  59 + /**
  60 + * 市场价,单位:分
  61 + */
  62 + private Integer marketPrice;
  63 + /**
  64 + * 成本价,单位:分
  65 + */
  66 + private Integer costPrice;
  67 + /**
  68 + * SKU 的条形码
  69 + */
  70 + private String barCode;
  71 + /**
  72 + * 图片地址
  73 + */
  74 + private String picUrl;
  75 + /**
  76 + * SKU 状态
  77 + * <p>
  78 + * 枚举 {@link CommonStatusEnum}
  79 + */
  80 + private Integer status;
  81 + /**
  82 + * 库存
  83 + */
  84 + private Integer stock;
  85 + /**
  86 + * 预警预存
  87 + */
  88 + private Integer warnStock;
  89 + /**
  90 + * 商品重量,单位:kg 千克
  91 + */
  92 + private Double weight;
  93 + /**
  94 + * 商品体积,单位:m^3 平米
  95 + */
  96 + private Double volume;
  97 +
  98 + /**
  99 + * 商品属性
  100 + */
  101 + @Data
  102 + @NoArgsConstructor
  103 + @AllArgsConstructor
  104 + public static class Property {
  105 +
  106 + /**
  107 + * 属性编号
  108 + * <p>
  109 + * 关联 {@link ProductPropertyDO#getId()}
  110 + */
  111 + private Long propertyId;
  112 + /**
  113 + * 属性值编号
  114 + * <p>
  115 + * 关联 {@link ProductPropertyValueDO#getId()}
  116 + */
  117 + private Long valueId;
  118 +
  119 + }
  120 +
  121 + // TODO @芋艿:可以找一些新的思路
  122 + public static class PropertyTypeHandler extends AbstractJsonTypeHandler<Object> {
  123 +
  124 + @Override
  125 + protected Object parse(String json) {
  126 + return JsonUtils.parseArray(json, Property.class);
  127 + }
  128 +
  129 + @Override
  130 + protected String toJson(Object obj) {
  131 + return JsonUtils.toJsonString(obj);
  132 + }
  133 +
  134 + }
  135 +
  136 +}
  137 +
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.dal.dataobject.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
  5 +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
  6 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  7 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
  8 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
  9 +import com.baomidou.mybatisplus.annotation.KeySequence;
  10 +import com.baomidou.mybatisplus.annotation.TableField;
  11 +import com.baomidou.mybatisplus.annotation.TableId;
  12 +import com.baomidou.mybatisplus.annotation.TableName;
  13 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  14 +import lombok.*;
  15 +
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * 商品 SPU DO
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@TableName(value = "product_spu", autoResultMap = true)
  24 +@KeySequence("product_spu_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = true)
  27 +@ToString(callSuper = true)
  28 +@Builder
  29 +@NoArgsConstructor
  30 +@AllArgsConstructor
  31 +public class ProductSpuDO extends BaseDO {
  32 +
  33 + /**
  34 + * 商品 SPU 编号,自增
  35 + */
  36 + @TableId
  37 + private Long id;
  38 +
  39 + // ========== 基本信息 =========
  40 +
  41 + /**
  42 + * 商品名称
  43 + */
  44 + private String name;
  45 + /**
  46 + * 商品编码
  47 + */
  48 + private String code;
  49 + /**
  50 + * 促销语
  51 + */
  52 + private String sellPoint;
  53 + /**
  54 + * 商品详情
  55 + */
  56 + private String description;
  57 + /**
  58 + * 商品分类编号
  59 + *
  60 + * 关联 {@link ProductCategoryDO#getId()}
  61 + */
  62 + private Long categoryId;
  63 + /**
  64 + * 商品品牌编号
  65 + *
  66 + * 关联 {@link ProductBrandDO#getId()}
  67 + */
  68 + private Long brandId;
  69 + /**
  70 + * 商品图片的数组
  71 + *
  72 + * 1. 第一张图片将作为商品主图,支持同时上传多张图;
  73 + * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片;
  74 + * 3. 至少 1 张,最多上传 10 张
  75 + */
  76 + @TableField(typeHandler = JacksonTypeHandler.class)
  77 + private List<String> picUrls;
  78 + /**
  79 + * 商品视频
  80 + */
  81 + private String videoUrl;
  82 +
  83 + /**
  84 + * 排序字段
  85 + */
  86 + private Integer sort;
  87 + /**
  88 + * 商品状态
  89 + *
  90 + * 枚举 {@link ProductSpuStatusEnum}
  91 + */
  92 + private Integer status;
  93 +
  94 + // ========== SKU 相关字段 =========
  95 +
  96 + /**
  97 + * 规格类型
  98 + *
  99 + * 枚举 {@link ProductSpuSpecTypeEnum}
  100 + */
  101 + private Integer specType;
  102 + /**
  103 + * 最小价格,单位使用:分
  104 + *
  105 + * 基于其对应的 {@link ProductSkuDO#getPrice()} 最小值
  106 + */
  107 + private Integer minPrice;
  108 + /**
  109 + * 最大价格,单位使用:分
  110 + *
  111 + * 基于其对应的 {@link ProductSkuDO#getPrice()} 最大值
  112 + */
  113 + private Integer maxPrice;
  114 + /**
  115 + * 市场价,单位使用:分
  116 + *
  117 + * 基于其对应的 {@link ProductSkuDO#getMarketPrice()} 最大值
  118 + */
  119 + private Integer marketPrice;
  120 + /**
  121 + * 总库存
  122 + *
  123 + * 基于其对应的 {@link ProductSkuDO#getStock()} 求和
  124 + */
  125 + private Integer totalStock;
  126 + /**
  127 + * 是否展示库存
  128 + */
  129 + private Boolean showStock;
  130 +
  131 + // ========== 统计相关字段 =========
  132 +
  133 + /**
  134 + * 商品销量
  135 + */
  136 + private Integer salesCount;
  137 + /**
  138 + * 虚拟销量
  139 + */
  140 + private Integer virtualSalesCount;
  141 + /**
  142 + * 商品点击量
  143 + */
  144 + private Integer clickCount;
  145 +
  146 + // ========== 物流相关字段 =========
  147 +
  148 + // TODO 芋艿:稍后完善物流的字段
  149 +// /**
  150 +// * 配送方式
  151 +// *
  152 +// * 枚举 {@link DeliveryModeEnum}
  153 +// */
  154 +// private Integer deliveryMode;
  155 +// /**
  156 +// * 配置模板编号
  157 +// *
  158 +// * 关联 {@link DeliveryTemplateDO#getId()}
  159 +// */
  160 +// private Long deliveryTemplateId;
  161 +
  162 + // TODO ========== 待定字段:yv =========
  163 + // TODO vip_price 会员价格
  164 + // TODO postage 邮费
  165 + // TODO is_postage 是否包邮
  166 + // TODO unit_name 单位
  167 + // TODO is_new 商户是否代理
  168 + // TODO give_integral 获得积分
  169 + // TODO is_integral 是开启积分兑换
  170 + // TODO integral 所需积分
  171 + // TODO is_seckill 秒杀状态
  172 + // TODO is_bargain 砍价状态
  173 + // TODO code_path 产品二维码地址
  174 + // TODO is_sub 是否分佣
  175 +
  176 + // TODO ↓↓ 芋艿 ↓↓ 看起来走分组更合适?
  177 + // TODO is_hot 是否热卖
  178 + // TODO is_benefit 是否优惠
  179 + // TODO is_best 是否精品
  180 + // TODO is_new 是否新品
  181 + // TODO is_good 是否优品推荐
  182 +
  183 + // TODO ========== 待定字段:cf =========
  184 + // TODO source_link 淘宝京东1688类型
  185 + // TODO activity 活动显示排序 0=默认 1=秒 2=砍价 3=拼团
  186 +
  187 + // TODO ========== 待定字段:lf =========
  188 +
  189 + // TODO free_shipping_type:运费类型:1-包邮;2-统一运费;3-运费模板
  190 + // TODO free_shipping:统一运费金额
  191 + // TODO free_shipping_template_id:运费模板
  192 + // TODO is_commission:分销佣金:1-开启;0-不开启;first_ratio second_ratio three_ratio
  193 + // TODO is_share_bouns:区域股东分红:1-开启;0-不开启;region_ratio;shareholder_ratio
  194 +
  195 + // TODO is_new:新品推荐:1-是;0-否
  196 + // TODO is_best:好物优选:1-是;0-否
  197 + // TODO is_like:猜你喜欢:1-是;0-否
  198 +
  199 + // TODO is_team:是否开启拼团[0=否, 1=是]
  200 + // TODO is_integral:积分抵扣:1-开启;0-不开启
  201 + // TODO is_member:会员价:1-开启;0-不开启
  202 + // TODO give_integral_type:赠送积分类型:0-不赠送;1-赠送固定积分;2-按比例赠送积分
  203 + // TODO give_integral:赠送积分;
  204 +
  205 + // TODO poster:商品自定义海报
  206 +
  207 + // TODO ========== 待定字段:laoji =========
  208 + // TODO productType 1 - 普通商品 2 - 预售商品;可能和 type 合并不错
  209 + // TODO productUnit 商品单位
  210 + // TODO extJson 扩展信息;例如说,预售商品的信息
  211 +
  212 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/brand/ProductBrandMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.mysql.brand;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.List;
  12 +
  13 +@Mapper
  14 +public interface ProductBrandMapper extends BaseMapperX<ProductBrandDO> {
  15 +
  16 + default PageResult<ProductBrandDO> selectPage(ProductBrandPageReqVO reqVO) {
  17 + return selectPage(reqVO, new LambdaQueryWrapperX<ProductBrandDO>()
  18 + .likeIfPresent(ProductBrandDO::getName, reqVO.getName())
  19 + .eqIfPresent(ProductBrandDO::getStatus, reqVO.getStatus())
  20 + .betweenIfPresent(ProductBrandDO::getCreateTime, reqVO.getCreateTime())
  21 + .orderByDesc(ProductBrandDO::getId));
  22 + }
  23 +
  24 +
  25 + default List<ProductBrandDO> selectList(ProductBrandListReqVO reqVO) {
  26 + return selectList(new LambdaQueryWrapperX<ProductBrandDO>()
  27 + .likeIfPresent(ProductBrandDO::getName, reqVO.getName()));
  28 + }
  29 +
  30 + default ProductBrandDO selectByName(String name) {
  31 + return selectOne(ProductBrandDO::getName, name);
  32 + }
  33 +
  34 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/category/ProductCategoryMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.mysql.category;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
  6 +import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
  7 +import org.apache.ibatis.annotations.Mapper;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 商品分类 Mapper
  13 + *
  14 + * @author 芋道源码
  15 + */
  16 +@Mapper
  17 +public interface ProductCategoryMapper extends BaseMapperX<ProductCategoryDO> {
  18 +
  19 + default List<ProductCategoryDO> selectList(ProductCategoryListReqVO listReqVO) {
  20 + return selectList(new LambdaQueryWrapperX<ProductCategoryDO>()
  21 + .likeIfPresent(ProductCategoryDO::getName, listReqVO.getName())
  22 + .orderByDesc(ProductCategoryDO::getId));
  23 + }
  24 +
  25 + default Long selectCountByParentId(Long parentId) {
  26 + return selectCount(ProductCategoryDO::getParentId, parentId);
  27 + }
  28 +
  29 + default List<ProductCategoryDO> selectListByStatus(Integer status) {
  30 + return selectList(ProductCategoryDO::getStatus, status);
  31 + }
  32 +
  33 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.mysql.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO;
  7 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO;
  8 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.List;
  12 +
  13 +@Mapper
  14 +public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> {
  15 +
  16 + default PageResult<ProductPropertyDO> selectPage(ProductPropertyPageReqVO reqVO) {
  17 + return selectPage(reqVO, new LambdaQueryWrapperX<ProductPropertyDO>()
  18 + .likeIfPresent(ProductPropertyDO::getName, reqVO.getName())
  19 + .betweenIfPresent(ProductPropertyDO::getCreateTime, reqVO.getCreateTime())
  20 + .orderByDesc(ProductPropertyDO::getId));
  21 + }
  22 +
  23 + default ProductPropertyDO selectByName(String name) {
  24 + return selectOne(ProductPropertyDO::getName, name);
  25 + }
  26 +
  27 + default List<ProductPropertyDO> selectList(ProductPropertyListReqVO listReqVO) {
  28 + return selectList(new LambdaQueryWrapperX<ProductPropertyDO>()
  29 + .eqIfPresent(ProductPropertyDO::getName, listReqVO.getName()));
  30 + }
  31 +
  32 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/property/ProductPropertyValueMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.dal.mysql.property;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
  7 +import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +@Mapper
  14 +public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
  15 +
  16 + default List<ProductPropertyValueDO> selectListByPropertyId(Collection<Long> propertyIds) {
  17 + return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
  18 + .inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
  19 + }
  20 +
  21 + default ProductPropertyValueDO selectByName(Long propertyId, String name) {
  22 + return selectOne(new LambdaQueryWrapperX<ProductPropertyValueDO>()
  23 + .eq(ProductPropertyValueDO::getPropertyId, propertyId)
  24 + .eq(ProductPropertyValueDO::getName, name));
  25 + }
  26 +
  27 + default void deleteByPropertyId(Long propertyId) {
  28 + delete(new LambdaQueryWrapperX<ProductPropertyValueDO>()
  29 + .eq(ProductPropertyValueDO::getPropertyId, propertyId));
  30 + }
  31 +
  32 + default PageResult<ProductPropertyValueDO> selectPage(ProductPropertyValuePageReqVO reqVO) {
  33 + return selectPage(reqVO, new LambdaQueryWrapperX<ProductPropertyValueDO>()
  34 + .eqIfPresent(ProductPropertyValueDO::getPropertyId, reqVO.getPropertyId())
  35 + .likeIfPresent(ProductPropertyValueDO::getName, reqVO.getName())
  36 + .orderByDesc(ProductPropertyValueDO::getId));
  37 + }
  38 +
  39 + default Integer selectCountByPropertyId(Long propertyId) {
  40 + return selectCount(ProductPropertyValueDO::getPropertyId, propertyId).intValue();
  41 + }
  42 +
  43 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/sku/ProductSkuMapper.java 0 → 100755
  1 +package cn.iocoder.yudao.module.product.dal.mysql.sku;
  2 +
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
  7 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  8 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 商品 SKU Mapper
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@Mapper
  20 +public interface ProductSkuMapper extends BaseMapperX<ProductSkuDO> {
  21 +
  22 + default List<ProductSkuDO> selectListBySpuId(Long spuId) {
  23 + return selectList(ProductSkuDO::getSpuId, spuId);
  24 + }
  25 +
  26 + default List<ProductSkuDO> selectListBySpuIdAndStatus(Long spuId,
  27 + Integer status) {
  28 + return selectList(new LambdaQueryWrapperX<ProductSkuDO>()
  29 + .eq(ProductSkuDO::getSpuId, spuId)
  30 + .eqIfPresent(ProductSkuDO::getStatus, status));
  31 + }
  32 +
  33 + default List<ProductSkuDO> selectListBySpuId(Collection<Long> spuIds) {
  34 + return selectList(ProductSkuDO::getSpuId, spuIds);
  35 + }
  36 +
  37 + default void deleteBySpuId(Long spuId) {
  38 + delete(new LambdaQueryWrapperX<ProductSkuDO>().eq(ProductSkuDO::getSpuId, spuId));
  39 + }
  40 +
  41 + /**
  42 + * 更新 SKU 库存(增加)
  43 + *
  44 + * @param id 编号
  45 + * @param incrCount 增加库存(正数)
  46 + */
  47 + default void updateStockIncr(Long id, Integer incrCount) {
  48 + Assert.isTrue(incrCount > 0);
  49 + LambdaUpdateWrapper<ProductSkuDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<ProductSkuDO>()
  50 + .setSql(" stock = stock + " + incrCount)
  51 + .eq(ProductSkuDO::getId, id);
  52 + update(null, lambdaUpdateWrapper);
  53 + }
  54 +
  55 + /**
  56 + * 更新 SKU 库存(减少)
  57 + *
  58 + * @param id 编号
  59 + * @param incrCount 减少库存(负数)
  60 + * @return 更新条数
  61 + */
  62 + default int updateStockDecr(Long id, Integer incrCount) {
  63 + Assert.isTrue(incrCount < 0);
  64 + LambdaUpdateWrapper<ProductSkuDO> updateWrapper = new LambdaUpdateWrapper<ProductSkuDO>()
  65 + .setSql(" stock = stock + " + incrCount) // 负数,所以使用 + 号
  66 + .eq(ProductSkuDO::getId, id)
  67 + .ge(ProductSkuDO::getStock, -incrCount); // cas 逻辑
  68 + return update(null, updateWrapper);
  69 + }
  70 +
  71 + default List<ProductSkuDO> selectListByAlarmStock(){
  72 + return selectList(new QueryWrapper<ProductSkuDO>().apply("stock <= warn_stock"));
  73 + }
  74 +
  75 +}