marge master

This commit is contained in:
xingyu 2023-01-04 10:57:19 +08:00
parent 7b98a3f3f3
commit 854ba3315c
335 changed files with 16 additions and 21122 deletions

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>yudao</artifactId>
<groupId>cn.iocoder.boot</groupId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-mall</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
商城大模块,由 product 商品、promotion 营销、trade 交易等组成
</description>
<modules>
<module>yudao-module-promotion-api</module>
<module>yudao-module-promotion-biz</module>
<module>yudao-module-product-api</module>
<module>yudao-module-product-biz</module>
<module>yudao-module-trade-api</module>
<module>yudao-module-trade-biz</module>
</modules>
</project>

View File

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-mall</artifactId>
<version>${revision}</version>
</parent>
<artifactId>yudao-module-product-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
product 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,4 +0,0 @@
/**
* 占位
*/
package cn.iocoder.yudao.module.product.api;

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.product.api.property;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import java.util.Collection;
import java.util.List;
/**
* 商品属性值 API 接口
*
* @author 芋道源码
*/
public interface ProductPropertyValueApi {
/**
* 根据编号数组获得属性值列表
*
* @param ids 编号数组
* @return 属性值明细列表
*/
List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids);
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.product.api.property.dto;
import lombok.Data;
/**
* 商品属性项的明细 Response DTO
*
* @author 芋道源码
*/
@Data
public class ProductPropertyValueDetailRespDTO {
/**
* 属性的编号
*/
private Long propertyId;
/**
* 属性的名称
*/
private String propertyName;
/**
* 属性值的编号
*/
private Long valueId;
/**
* 属性值的名称
*/
private String valueName;
}

View File

@ -1,40 +0,0 @@
package cn.iocoder.yudao.module.product.api.sku;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import java.util.Collection;
import java.util.List;
/**
* 商品 SKU API 接口
*
* @author LeeYan9
* @since 2022-08-26
*/
public interface ProductSkuApi {
/**
* 查询 SKU 信息
*
* @param id SKU 编号
* @return SKU 信息
*/
ProductSkuRespDTO getSku(Long id);
/**
* 批量查询 SKU 数组
*
* @param ids SKU 编号列表
* @return SKU 数组
*/
List<ProductSkuRespDTO> getSkuList(Collection<Long> ids);
/**
* 更新 SKU 库存
*
* @param updateStockReqDTO 更新请求
*/
void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO);
}

View File

@ -1,95 +0,0 @@
package cn.iocoder.yudao.module.product.api.sku.dto;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import lombok.Data;
import java.util.List;
/**
* 商品 SKU 信息 Response DTO
*
* @author LeeYan9
* @since 2022-08-26
*/
@Data
public class ProductSkuRespDTO {
/**
* 商品 SKU 编号自增
*/
private Long id;
/**
* SPU 编号
*/
private Long spuId;
/**
* SPU 名字
*/
private String spuName;
/**
* 属性数组JSON 格式
*/
private List<Property> properties;
/**
* 销售价格单位
*/
private Integer price;
/**
* 市场价单位
*/
private Integer marketPrice;
/**
* 成本价单位
*/
private Integer costPrice;
/**
* SKU 的条形码
*/
private String barCode;
/**
* 图片地址
*/
private String picUrl;
/**
* SKU 状态
* <p>
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 库存
*/
private Integer stock;
/**
* 预警预存
*/
private Integer warnStock;
/**
* 商品重量单位kg 千克
*/
private Double weight;
/**
* 商品体积单位m^3 平米
*/
private Double volume;
/**
* 商品属性
*/
@Data
public static class Property {
/**
* 属性编号
*/
private Long propertyId;
/**
* 属性值编号
*/
private Long valueId;
}
}

View File

@ -1,47 +0,0 @@
package cn.iocoder.yudao.module.product.api.sku.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SKU 更新库存 Request DTO
*
* @author LeeYan9
* @since 2022-08-26
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProductSkuUpdateStockReqDTO {
/**
* 商品 SKU
*/
@NotNull(message = "商品 SKU 不能为空")
private List<Item> items;
@Data
public static class Item {
/**
* 商品 SKU 编号
*/
@NotNull(message = "商品 SKU 编号不能为空")
private Long id;
/**
* 库存变化数量
*
* 正数增加库存
* 负数扣减库存
*/
@NotNull(message = "库存变化数量不能为空")
private Integer incrCount;
}
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.product.api.spu;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import java.util.Collection;
import java.util.List;
/**
* 商品 SPU API 接口
*
* @author LeeYan9
* @since 2022-08-26
*/
public interface ProductSpuApi {
/**
* 批量查询 SPU 数组
*
* @param ids SPU 编号列表
* @return SPU 数组
*/
List<ProductSpuRespDTO> getSpuList(Collection<Long> ids);
}

View File

@ -1,127 +0,0 @@
package cn.iocoder.yudao.module.product.api.spu.dto;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import lombok.Data;
import java.util.List;
// TODO @LeeYan9: ProductSpuRespDTO
/**
* 商品 SPU 信息 Response DTO
*
* @author LeeYan9
* @since 2022-08-26
*/
@Data
public class ProductSpuRespDTO {
/**
* 商品 SPU 编号自增
*/
private Long id;
// ========== 基本信息 =========
/**
* 商品名称
*/
private String name;
/**
* 商品编码
*/
private String code;
/**
* 促销语
*/
private String sellPoint;
/**
* 商品详情
*/
private String description;
/**
* 商品分类编号
*/
private Long categoryId;
/**
* 商品品牌编号
*/
private Long brandId;
/**
* 商品图片的数组
* <p>
* 1. 第一张图片将作为商品主图支持同时上传多张图
* 2. 建议使用尺寸 800x800 像素以上大小不超过 1M 的正方形图片
* 3. 至少 1 最多上传 10
*/
private List<String> picUrls;
/**
* 商品视频
*/
private String videoUrl;
/**
* 排序字段
*/
private Integer sort;
/**
* 商品状态
* <p>
* 枚举 {@link ProductSpuStatusEnum}
*/
private Integer status;
// ========== SKU 相关字段 =========
/**
* 规格类型
* <p>
* 枚举 {@link ProductSpuSpecTypeEnum}
*/
private Integer specType;
/**
* 最小价格单位使用
* <p>
* 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最小值
*/
private Integer minPrice;
/**
* 最大价格单位使用
* <p>
* 基于其对应的 {@link ProductSkuRespDTO#getPrice()} 最大值
*/
private Integer maxPrice;
/**
* 市场价单位使用
* <p>
* 基于其对应的 {@link ProductSkuRespDTO#getMarketPrice()} 最大值
*/
private Integer marketPrice;
/**
* 总库存
* <p>
* 基于其对应的 {@link ProductSkuRespDTO#getStock()} 求和
*/
private Integer totalStock;
/**
* 是否展示库存
*/
private Boolean showStock;
// ========== 统计相关字段 =========
/**
* 商品销量
*/
private Integer salesCount;
/**
* 虚拟销量
*/
private Integer virtualSalesCount;
/**
* 商品点击量
*/
private Integer clickCount;
}

View File

@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.product.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
/**
* Product 错误码枚举类
*
* product 系统使用 1-008-000-000
*/
public interface ErrorCodeConstants {
// ========== 商品分类相关 1008001000 ============
ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");
ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");
ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
// ========== 商品品牌相关编号 1008002000 ==========
ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在");
ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在");
// ========== 商品属性项 1008003000 ==========
ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "属性项不存在");
ErrorCode PROPERTY_EXISTS = new ErrorCode(1008003001, "属性项的名称已存在");
ErrorCode PROPERTY_DELETE_FAIL_VALUE_EXISTS = new ErrorCode(1008003002, "属性项下存在属性值,无法删除");
// ========== 商品属性值 1008004000 ==========
ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "属性值不存在");
ErrorCode PROPERTY_VALUE_EXISTS = new ErrorCode(1008004001, "属性值的名称已存在");
// ========== 商品 SPU 1008005000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1008005001, "商品分类不正确,原因:必须使用第三级的商品分类下");
ErrorCode SPU_NOT_ENABLE = new ErrorCode(1008005002, "商品 SPU 不处于上架状态");
// ========== 商品 SKU 1008006000 ==========
ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");
ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品 SKU 的属性组合存在重复");
ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 SPU 下的每个 SKU其属性项必须一致");
ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU必须不重复");
ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.enums.comment;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 商品评论的审批状态枚举
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum ProductCommentAuditStatusEnum implements IntArrayValuable {
NONE(1, "待审核"),
APPROVE(2, "审批通过"),
REJECT(2, "审批不通过"),;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentAuditStatusEnum::getStatus).toArray();
/**
* 审批状态
*/
private final Integer status;
/**
* 状态名
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.enums.delivery;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 配送方式枚举
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum DeliveryTypeEnum implements IntArrayValuable {
// TODO 芋艿英文单词需要再想下
EXPRESS(1, "快递发货"),
USER(2, "用户自提"),;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getMode).toArray();
/**
* 配送方式
*/
private final Integer mode;
/**
* 状态名
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.enums.group;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 商品分组的样式枚举
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum ProductGroupStyleEnum implements IntArrayValuable {
ONE(1, "每列一个"),
TWO(2, "每列两个"),
THREE(2, "每列三个"),;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductGroupStyleEnum::getStyle).toArray();
/**
* 列表样式
*/
private final Integer style;
/**
* 状态名
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,37 +0,0 @@
package cn.iocoder.yudao.module.product.enums.spu;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 商品 SPU 规格类型
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum ProductSpuSpecTypeEnum implements IntArrayValuable {
RECYCLE(1, "统一规格"),
DISABLE(2, "多规格");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray();
/**
* 规格类型
*/
private final Integer type;
/**
* 规格名称
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.yudao.module.product.enums.spu;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 商品 SPU 状态
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum ProductSpuStatusEnum implements IntArrayValuable {
RECYCLE(-1, "回收站"),
DISABLE(0, "下架"),
ENABLE(1, "上架"),;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStatus).toArray();
/**
* 状态
*/
private final Integer status;
/**
* 状态名
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
/**
* 判断是否处于上架状态
*
* @param status 状态
* @return 是否处于上架状态
*/
public static boolean isEnable(Integer status) {
return ENABLE.getStatus().equals(status);
}
}

View File

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-mall</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-product-biz</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
product 模块,主要实现商品相关功能
例如品牌、商品分类、spu、sku等功能。
</description>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-product-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-security</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-test</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,31 +0,0 @@
package cn.iocoder.yudao.module.product.api.property;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
/**
* 商品属性值 API 实现类
*
* @author 芋道源码
*/
@Service
@Validated
public class ProductPropertyValueApiImpl implements ProductPropertyValueApi {
@Resource
private ProductPropertyValueService productPropertyValueService;
@Override
public List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids) {
return ProductPropertyValueConvert.INSTANCE.convertList02(
productPropertyValueService.getPropertyValueDetailList(ids));
}
}

View File

@ -1,49 +0,0 @@
package cn.iocoder.yudao.module.product.api.sku;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* TODO LeeYan9: 类注释;
* @author LeeYan9
* @since 2022-09-06
*/
@Service
@Validated
public class ProductSkuApiImpl implements ProductSkuApi {
@Resource
private ProductSkuService productSkuService;
@Override
public ProductSkuRespDTO getSku(Long id) {
// TODO TODO LeeYan9: 需要实现
return null;
}
@Override
public List<ProductSkuRespDTO> getSkuList(Collection<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return Collections.emptyList();
}
List<ProductSkuDO> skus = productSkuService.getSkuList(ids);
return ProductSkuConvert.INSTANCE.convertList04(skus);
}
@Override
public void updateSkuStock(ProductSkuUpdateStockReqDTO updateStockReqDTO) {
productSkuService.updateSkuStock(updateStockReqDTO);
}
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.api.spu;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* TODO LeeYan9: 类注释;
*
* @author LeeYan9
* @since 2022-09-06
*/
@Service
@Validated
public class ProductSpuApiImpl implements ProductSpuApi {
@Resource
private ProductSpuMapper productSpuMapper;
@Override
public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) {
// TODO TODO LeeYan9: AllEmpty?
if (CollectionUtils.isAnyEmpty(spuIds)) {
return Collections.emptyList();
}
List<ProductSpuDO> productSpuDOList = productSpuMapper.selectBatchIds(spuIds);
return ProductSpuConvert.INSTANCE.convertList2(productSpuDOList);
}
}

View File

@ -1,82 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.brand;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*;
import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Comparator;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 商品品牌")
@RestController
@RequestMapping("/product/brand")
@Validated
public class ProductBrandController {
@Resource
private ProductBrandService brandService;
@PostMapping("/create")
@Operation(summary = "创建品牌")
@PreAuthorize("@ss.hasPermission('product:brand:create')")
public CommonResult<Long> createBrand(@Valid @RequestBody ProductBrandCreateReqVO createReqVO) {
return success(brandService.createBrand(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新品牌")
@PreAuthorize("@ss.hasPermission('product:brand:update')")
public CommonResult<Boolean> updateBrand(@Valid @RequestBody ProductBrandUpdateReqVO updateReqVO) {
brandService.updateBrand(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除品牌")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('product:brand:delete')")
public CommonResult<Boolean> deleteBrand(@RequestParam("id") Long id) {
brandService.deleteBrand(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得品牌")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('product:brand:query')")
public CommonResult<ProductBrandRespVO> getBrand(@RequestParam("id") Long id) {
ProductBrandDO brand = brandService.getBrand(id);
return success(ProductBrandConvert.INSTANCE.convert(brand));
}
@GetMapping("/page")
@Operation(summary = "获得品牌分页")
@PreAuthorize("@ss.hasPermission('product:brand:query')")
public CommonResult<PageResult<ProductBrandRespVO>> getBrandPage(@Valid ProductBrandPageReqVO pageVO) {
PageResult<ProductBrandDO> pageResult = brandService.getBrandPage(pageVO);
return success(ProductBrandConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/list")
@Operation(summary = "获得品牌列表")
@PreAuthorize("@ss.hasPermission('product:brand:query')")
public CommonResult<List<ProductBrandRespVO>> getBrandList(@Valid ProductBrandListReqVO listVO) {
List<ProductBrandDO> list = brandService.getBrandList(listVO);
list.sort(Comparator.comparing(ProductBrandDO::getSort));
return success(ProductBrandConvert.INSTANCE.convertList(list));
}
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 商品品牌 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ProductBrandBaseVO {
@Schema(description = "品牌名称", required = true, example = "芋道")
@NotNull(message = "品牌名称不能为空")
private String name;
@Schema(description = "品牌图片", required = true)
@NotNull(message = "品牌图片不能为空")
private String picUrl;
@Schema(description = "品牌排序", required = true, example = "1")
@NotNull(message = "品牌排序不能为空")
private Integer sort;
@Schema(description = "品牌描述", example = "描述")
private String description;
@Schema(description = "状态", required = true, example = "0")
@NotNull(message = "状态不能为空")
private Integer status;
}

View File

@ -1,11 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 商品品牌创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductBrandCreateReqVO extends ProductBrandBaseVO {
}

View File

@ -1,13 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 商品品牌分页 Request VO")
@Data
public class ProductBrandListReqVO {
@Schema(description = "品牌名称", example = "芋道")
private String name;
}

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 商品品牌分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductBrandPageReqVO extends PageParam {
@Schema(description = "品牌名称", example = "芋道")
private String name;
@Schema(description = "状态-参考 CommonStatusEnum 枚举", example = "0")
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 品牌 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductBrandRespVO extends ProductBrandBaseVO {
@Schema(description = "品牌编号", required = true, example = "1")
private Long id;
@Schema(description = "创建时间", required = true)
private LocalDateTime createTime;
}

View File

@ -1,16 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 商品品牌更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductBrandUpdateReqVO extends ProductBrandBaseVO {
@Schema(description = "品牌编号", required = true, example = "1")
@NotNull(message = "品牌编号不能为空")
private Long id;
}

View File

@ -1,76 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.category;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Comparator;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 商品分类")
@RestController
@RequestMapping("/product/category")
@Validated
public class ProductCategoryController {
@Resource
private ProductCategoryService categoryService;
@PostMapping("/create")
@Operation(summary = "创建商品分类")
@PreAuthorize("@ss.hasPermission('product:category:create')")
public CommonResult<Long> createCategory(@Valid @RequestBody ProductCategoryCreateReqVO createReqVO) {
return success(categoryService.createCategory(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新商品分类")
@PreAuthorize("@ss.hasPermission('product:category:update')")
public CommonResult<Boolean> updateCategory(@Valid @RequestBody ProductCategoryUpdateReqVO updateReqVO) {
categoryService.updateCategory(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除商品分类")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('product:category:delete')")
public CommonResult<Boolean> deleteCategory(@RequestParam("id") Long id) {
categoryService.deleteCategory(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得商品分类")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('product:category:query')")
public CommonResult<ProductCategoryRespVO> getCategory(@RequestParam("id") Long id) {
ProductCategoryDO category = categoryService.getCategory(id);
return success(ProductCategoryConvert.INSTANCE.convert(category));
}
@GetMapping("/list")
@Operation(summary = "获得商品分类列表")
@PreAuthorize("@ss.hasPermission('product:category:query')")
public CommonResult<List<ProductCategoryRespVO>> getCategoryList(@Valid ProductCategoryListReqVO treeListReqVO) {
List<ProductCategoryDO> list = categoryService.getEnableCategoryList(treeListReqVO);
list.sort(Comparator.comparing(ProductCategoryDO::getSort));
return success(ProductCategoryConvert.INSTANCE.convertList(list));
}
}

View File

@ -1,37 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 商品分类 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ProductCategoryBaseVO {
@Schema(description = "父分类编号", required = true, example = "1")
@NotNull(message = "父分类编号不能为空")
private Long parentId;
@Schema(description = "分类名称", required = true, example = "办公文具")
@NotBlank(message = "分类名称不能为空")
private String name;
@Schema(description = "分类图片", required = true)
@NotBlank(message = "分类图片不能为空")
private String picUrl;
@Schema(description = "分类排序", required = true, example = "1")
private Integer sort;
@Schema(description = "分类描述", required = true, example = "描述")
private String description;
@Schema(description = "开启状态", required = true, example = "0")
@NotNull(message = "开启状态不能为空")
private Integer status;
}

View File

@ -1,11 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 商品分类创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductCategoryCreateReqVO extends ProductCategoryBaseVO {
}

View File

@ -1,13 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 商品分类列表查询 Request VO")
@Data
public class ProductCategoryListReqVO {
@Schema(description = "分类名称", example = "办公文具")
private String name;
}

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 商品分类 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductCategoryRespVO extends ProductCategoryBaseVO {
@Schema(description = "分类编号", required = true, example = "2")
private Long id;
@Schema(description = "创建时间", required = true)
private LocalDateTime createTime;
}

View File

@ -1,16 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.category.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 商品分类更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductCategoryUpdateReqVO extends ProductCategoryBaseVO {
@Schema(description = "分类编号", required = true, example = "2")
@NotNull(message = "分类编号不能为空")
private Long id;
}

View File

@ -1,99 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.*;
import cn.iocoder.yudao.module.product.convert.property.ProductPropertyConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 商品属性项")
@RestController
@RequestMapping("/product/property")
@Validated
public class ProductPropertyController {
@Resource
private ProductPropertyService productPropertyService;
@Resource
private ProductPropertyValueService productPropertyValueService;
@PostMapping("/create")
@Operation(summary = "创建属性项")
@PreAuthorize("@ss.hasPermission('product:property:create')")
public CommonResult<Long> createProperty(@Valid @RequestBody ProductPropertyCreateReqVO createReqVO) {
return success(productPropertyService.createProperty(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新属性项")
@PreAuthorize("@ss.hasPermission('product:property:update')")
public CommonResult<Boolean> updateProperty(@Valid @RequestBody ProductPropertyUpdateReqVO updateReqVO) {
productPropertyService.updateProperty(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除属性项")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('product:property:delete')")
public CommonResult<Boolean> deleteProperty(@RequestParam("id") Long id) {
productPropertyService.deleteProperty(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得属性项")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<ProductPropertyRespVO> getProperty(@RequestParam("id") Long id) {
return success(ProductPropertyConvert.INSTANCE.convert(productPropertyService.getProperty(id)));
}
@GetMapping("/list")
@Operation(summary = "获得属性项列表")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<List<ProductPropertyRespVO>> getPropertyList(@Valid ProductPropertyListReqVO listReqVO) {
return success(ProductPropertyConvert.INSTANCE.convertList(productPropertyService.getPropertyList(listReqVO)));
}
@GetMapping("/page")
@Operation(summary = "获得属性项分页")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<PageResult<ProductPropertyRespVO>> getPropertyPage(@Valid ProductPropertyPageReqVO pageVO) {
return success(ProductPropertyConvert.INSTANCE.convertPage(productPropertyService.getPropertyPage(pageVO)));
}
@GetMapping("/get-value-list")
@Operation(summary = "获得属性项列表")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<List<ProductPropertyAndValueRespVO>> getPropertyAndValueList(@Valid ProductPropertyListReqVO listReqVO) {
// 查询属性项
List<ProductPropertyDO> keys = productPropertyService.getPropertyList(listReqVO);
if (CollUtil.isEmpty(keys)) {
return success(Collections.emptyList());
}
// 查询属性值
List<ProductPropertyValueDO> values = productPropertyValueService.getPropertyValueListByPropertyId(
convertSet(keys, ProductPropertyDO::getId));
return success(ProductPropertyConvert.INSTANCE.convertList(keys, values));
}
}

View File

@ -1,70 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
import cn.iocoder.yudao.module.product.convert.propertyvalue.ProductPropertyValueConvert;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 商品属性值")
@RestController
@RequestMapping("/product/property/value")
@Validated
public class ProductPropertyValueController {
@Resource
private ProductPropertyValueService productPropertyValueService;
@PostMapping("/create")
@Operation(summary = "创建属性值")
@PreAuthorize("@ss.hasPermission('product:property:create')")
public CommonResult<Long> createProperty(@Valid @RequestBody ProductPropertyValueCreateReqVO createReqVO) {
return success(productPropertyValueService.createPropertyValue(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新属性值")
@PreAuthorize("@ss.hasPermission('product:property:update')")
public CommonResult<Boolean> updateProperty(@Valid @RequestBody ProductPropertyValueUpdateReqVO updateReqVO) {
productPropertyValueService.updatePropertyValue(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除属性值")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('product:property:delete')")
public CommonResult<Boolean> deleteProperty(@RequestParam("id") Long id) {
productPropertyValueService.deletePropertyValue(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得属性值")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<ProductPropertyValueRespVO> getProperty(@RequestParam("id") Long id) {
return success(ProductPropertyValueConvert.INSTANCE.convert(productPropertyValueService.getPropertyValue(id)));
}
@GetMapping("/page")
@Operation(summary = "获得属性值分页")
@PreAuthorize("@ss.hasPermission('product:property:query')")
public CommonResult<PageResult<ProductPropertyValueRespVO>> getPropertyValuePage(@Valid ProductPropertyValuePageReqVO pageVO) {
return success(ProductPropertyValueConvert.INSTANCE.convertPage(productPropertyValueService.getPropertyValuePage(pageVO)));
}
}

View File

@ -1,35 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - 商品属性项 + 属性值 Response VO")
@Data
public class ProductPropertyAndValueRespVO {
@ApiModelProperty(value = "属性项的编号", required = true, example = "1024")
private Long id;
@ApiModelProperty(value = "属性项的名称", required = true, example = "颜色")
private String name;
/**
* 属性值的集合
*/
private List<Value> values;
@ApiModel("管理后台 - 属性值的简单 Response VO")
@Data
public static class Value {
@Schema(description = "属性值的编号", required = true, example = "2048")
private Long id;
@Schema(description = "属性值的名称", required = true, example = "红色")
private String name;
}
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 商品属性项 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ProductPropertyBaseVO {
@Schema(description = "名称", required = true, example = "颜色")
@NotBlank(message = "名称不能为空")
private String name;
@Schema(description = "备注", example = "颜色")
private String remark;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 属性项创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyCreateReqVO extends ProductPropertyBaseVO {
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 属性项 List Request VO")
@Data
@ToString(callSuper = true)
public class ProductPropertyListReqVO {
@Schema(description = "名称", example = "颜色")
private String name;
}

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 属性项 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyPageReqVO extends PageParam {
@Schema(description = "名称", example = "颜色")
private String name;
@Schema(description = "状态-参见 CommonStatusEnum 枚举", required = true, example = "1")
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 属性项 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyRespVO extends ProductPropertyBaseVO {
@Schema(description = "编号", required = true, example = "1024")
private Long id;
@Schema(description = "创建时间", required = true)
private LocalDateTime createTime;
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.property;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 属性项更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyUpdateReqVO extends ProductPropertyBaseVO {
@Schema(description = "主键", required = true, example = "1")
@NotNull(message = "主键不能为空")
private Long id;
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 属性值 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ProductPropertyValueBaseVO {
@Schema(description = "属性项的编号", required = true, example = "1024")
@NotNull(message = "属性项的编号不能为空")
private Long propertyId;
@Schema(description = "名称", required = true, example = "红色")
@NotEmpty(message = "名称名字不能为空")
private String name;
@Schema(description = "备注", example = "颜色")
private String remark;
}

View File

@ -1,12 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 商品属性值创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyValueCreateReqVO extends ProductPropertyValueBaseVO {
}

View File

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

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 商品属性值分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyValuePageReqVO extends PageParam {
@Schema(description = "属性项的编号", example = "1024")
private String propertyId;
@Schema(description = "名称", example = "红色")
private String name;
@Schema(description = "状态 - 参见 CommonStatusEnum 枚举", required = true, example = "1")
private Integer status;
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 商品属性值 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyValueRespVO extends ProductPropertyValueBaseVO {
@Schema(description = "编号", required = true, example = "10")
private Long id;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 商品属性值更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductPropertyValueUpdateReqVO extends ProductPropertyValueBaseVO {
@Schema(description = "主键", required = true, example = "1024")
@NotNull(message = "主键不能为空")
private Long id;
}

View File

@ -1,57 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 商品 sku")
@RestController
@RequestMapping("/product/sku")
@Validated
public class ProductSkuController {
@Resource
private ProductSkuService productSkuService;
@Resource
private ProductSpuService productSpuService;
@GetMapping("/get-option-list")
@Operation(summary = "获得商品 SKU 选项的列表")
// @PreAuthorize("@ss.hasPermission('product:sku:query')")
public CommonResult<List<ProductSkuOptionRespVO>> getSkuOptionList() {
// 获得 SKU 列表
List<ProductSkuDO> skus = productSkuService.getSkuList();
if (CollUtil.isEmpty(skus)) {
return success(Collections.emptyList());
}
// 获得对应的 SPU 映射
Map<Long, ProductSpuDO> spuMap = productSpuService.getSpuMap(convertSet(skus, ProductSkuDO::getSpuId));
// 转换为返回结果
List<ProductSkuOptionRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList05(skus);
skuVOs.forEach(sku -> MapUtils.findAndThen(spuMap, sku.getSpuId(),
spu -> sku.setSpuId(spu.getId()).setSpuName(spu.getName())));
return success(skuVOs);
}
}

View File

@ -1,75 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 商品 SKU Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ProductSkuBaseVO {
@Schema(description = "商品 SKU 名字", required = true, example = "芋道")
@NotEmpty(message = "商品 SKU 名字不能为空")
private String name;
@Schema(description = "销售价格,单位:分", required = true, example = "1024", notes = "单位:分")
@NotNull(message = "销售价格,单位:分不能为空")
private Integer price;
@Schema(description = "市场价", example = "1024", notes = "单位:分")
private Integer marketPrice;
@Schema(description = "成本价", example = "1024", notes = "单位:分")
private Integer costPrice;
@Schema(description = "条形码", example = "haha")
private String barCode;
@Schema(description = "图片地址", required = true, example = "https://www.iocoder.cn/xx.png")
@NotNull(message = "图片地址不能为空")
private String picUrl;
@Schema(description = "SKU 状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
@NotNull(message = "SKU 状态不能为空")
@InEnum(CommonStatusEnum.class)
private Integer status;
@Schema(description = "库存", required = true, example = "1")
@NotNull(message = "库存不能为空")
private Integer stock;
@Schema(description = "预警预存", example = "1")
private Integer warnStock;
@Schema(description = "商品重量 - 单位kg 千克", example = "1")
private Double weight;
@Schema(description = "商品体积 - 单位m^3 平米", example = "1024")
private Double volume;
@ApiModel("商品属性")
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Property {
@Schema(description = "属性编号", required = true, example = "1")
@NotNull(message = "属性编号不能为空")
private Long propertyId;
@Schema(description = "属性值编号", required = true, example = "1024")
@NotNull(message = "属性值编号不能为空")
private Long valueId;
}
}

View File

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

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 商品 SKU 选项 Response VO,用于前端 SELECT 选项")
@Data
public class ProductSkuOptionRespVO {
@Schema(description = "主键", required = true, example = "1024")
private Long id;
@Schema(description = "商品 SKU 名字", example = "红色")
private String name;
@Schema(description = "销售价格,单位:分", required = true, example = "100")
private String price;
@Schema(description = "库存", required = true, example = "100")
private Integer stock;
// ========== 商品 SPU 信息 ==========
@Schema(description = "商品 SPU 编号", required = true, example = "1")
private Long spuId;
@Schema(description = "商品 SPU 名字", required = true, example = "iPhone 11")
private String spuName;
}

View File

@ -1,28 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 商品 SKU Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSkuRespVO extends ProductSkuBaseVO {
@Schema(description = "主键", required = true, example = "1024")
private Long id;
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 属性数组
*/
private List<Property> properties;
}

View File

@ -1,4 +0,0 @@
### 获得商品 SPU 明细
GET {{baseUrl}}/product/spu/get-detail?id=4
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}

View File

@ -1,101 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
@Tag(name = "管理后台 - 商品 SPU")
@RestController
@RequestMapping("/product/spu")
@Validated
public class ProductSpuController {
@Resource
private ProductSpuService productSpuService;
@Resource
private ProductSkuService productSkuService;
@Resource
private ProductPropertyValueService productPropertyValueService;
@PostMapping("/create")
@Operation(summary = "创建商品 SPU")
@PreAuthorize("@ss.hasPermission('product:spu:create')")
public CommonResult<Long> createProductSpu(@Valid @RequestBody ProductSpuCreateReqVO createReqVO) {
return success(productSpuService.createSpu(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新商品 SPU")
@PreAuthorize("@ss.hasPermission('product:spu:update')")
public CommonResult<Boolean> updateSpu(@Valid @RequestBody ProductSpuUpdateReqVO updateReqVO) {
productSpuService.updateSpu(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除商品 SPU")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
@PreAuthorize("@ss.hasPermission('product:spu:delete')")
public CommonResult<Boolean> deleteSpu(@RequestParam("id") Long id) {
productSpuService.deleteSpu(id);
return success(true);
}
@GetMapping("/get-detail")
@Operation(summary = "获得商品 SPU 明细")
@Parameter(name = "id", value = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('product:spu:query')")
public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
// 获得商品 SPU
ProductSpuDO spu = productSpuService.getSpu(id);
if (spu == null) {
throw exception(SPU_NOT_EXISTS);
}
// 查询商品 SKU
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), null);
// 查询商品属性
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
// 拼接
return success(ProductSpuConvert.INSTANCE.convert03(spu, skus, propertyValues));
}
@GetMapping("/get-simple-list")
@Operation(summary = "获得商品 SPU 精简列表")
@PreAuthorize("@ss.hasPermission('product:spu:query')")
public CommonResult<List<ProductSpuSimpleRespVO>> getSpuSimpleList() {
List<ProductSpuDO> list = productSpuService.getSpuList();
return success(ProductSpuConvert.INSTANCE.convertList02(list));
}
@GetMapping("/page")
@Operation(summary = "获得商品 SPU 分页")
@PreAuthorize("@ss.hasPermission('product:spu:query')")
public CommonResult<PageResult<ProductSpuRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) {
return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO)));
}
}

View File

@ -1,76 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ProductSpuBaseVO {
@Schema(description = = "商品名称", required = true, example = "芋道")
@NotEmpty(message = "商品名称不能为空")
private String name;
@Schema(description = = "商品编码", example = "yudaoyuanma")
private String code;
@Schema(description = = "促销语", example = "好吃!")
private String sellPoint;
@Schema(description = = "商品详情", required = true, example = "我是商品描述")
@NotNull(message = "商品详情不能为空")
private String description;
@Schema(description = = "商品分类编号", required = true, example = "1")
@NotNull(message = "商品分类编号不能为空")
private Long categoryId;
@Schema(description = = "商品品牌编号", example = "1")
private Long brandId;
@Schema(description = = "商品图片的数组", required = true)
@NotNull(message = "商品图片的数组不能为空")
private List<String> picUrls;
@Schema(description = = "商品视频", required = true)
private String videoUrl;
@Schema(description = = "排序字段", required = true, example = "1")
private Integer sort;
@Schema(description = = "商品状态 参见 ProductSpuStatusEnum 枚举类", required = true, example = "1")
@NotNull(message = "商品状态不能为空")
@InEnum(ProductSpuStatusEnum.class)
private Integer status;
// ========== SKU 相关字段 =========
@Schema(description = = "规格类型 参见 ProductSpuSpecTypeEnum 枚举类", required = true, example = "1")
@NotNull(message = "规格类型不能为空")
@InEnum(ProductSpuSpecTypeEnum.class)
private Integer specType;
@Schema(description = = "是否展示库存", required = true, example = "true")
@NotNull(message = "是否展示库存不能为空")
private Boolean showStock;
@Schema(description = = "市场价", example = "1024")
private Integer marketPrice;
// ========== 统计相关字段 =========
@Schema(description = = "虚拟销量", required = true, example = "1024")
@NotNull(message = "虚拟销量不能为空")
private Integer virtualSalesCount;
}

View File

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

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.List;
@Schema(description = "管理后台 - 商品 SPU 详细 Response VO 包括关联的 SKU 等信息")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuDetailRespVO extends ProductSpuRespVO {
// ========== SKU 相关字段 =========
/**
* SKU 数组
*/
private List<Sku> skus;
@Schema(description = "管理后台 - 商品 SKU 详细 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public static class Sku extends ProductSkuBaseVO {
/**
* 属性数组
*/
private List<ProductPropertyValueDetailRespVO> properties;
}
}

View File

@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 商品 SPU 分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuPageReqVO extends PageParam {
@Schema(description = "商品名称", example = "yutou")
private String name;
@Schema(description = "商品编码", example = "yudaoyuanma")
private String code;
@Schema(description = "分类编号", example = "1")
private Long categoryId;
@Schema(description = "商品品牌编号", example = "1")
private Long brandId;
@Schema(description = "上下架状态 参见 ProductSpuStatusEnum 枚举值", example = "1")
private Integer status;
@Schema(description = "销量最小值", example = "1")
private Integer salesCountMin;
@Schema(description = "销量最大值", example = "1024")
private Integer salesCountMax;
@Schema(description = "市场价最小值", example = "1")
private Integer marketPriceMin;
@Schema(description = "市场价最大值", example = "1024")
private Integer marketPriceMax;
@Schema(description = "是否库存告警", example = "true")
private Boolean alarmStock;
}

View File

@ -1,40 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 商品 SPU Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuRespVO extends ProductSpuBaseVO {
@Schema(description = "主键", required = true, example = "1")
private Long id;
@Schema(description = "创建时间")
private LocalDateTime createTime;
// ========== SKU 相关字段 =========
@ApiModelProperty(value = "库存", required = true, example = "true")
private Integer totalStock;
@ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
private Integer minPrice;
@ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024")
private Integer maxPrice;
@ApiModelProperty(value = "商品销量", example = "1024")
private Integer salesCount;
// ========== 统计相关字段 =========
@ApiModelProperty(value = "点击量", example = "1024")
private Integer clickCount;
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - 商品 SPU 精简 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuSimpleRespVO extends ProductSpuBaseVO {
@Schema(description = "主键", required = true, example = "1")
private Long id;
@Schema(description = "商品名称", required = true, example = "芋道")
private String name;
@Schema(description = " 最小价格,单位使用:分", required = true, example = "1024")
private Integer minPrice;
@Schema(description = "最大价格,单位使用:分", required = true, example = "1024")
private Integer maxPrice;
}

View File

@ -1,29 +0,0 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 商品 SPU 更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductSpuUpdateReqVO extends ProductSpuBaseVO {
@Schema(description = "商品编号", required = true, example = "1")
@NotNull(message = "商品编号不能为空")
private Long id;
/**
* SKU 数组
*/
@Valid
private List<ProductSkuCreateOrUpdateReqVO> skus;
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.controller.app.category;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO;
import cn.iocoder.yudao.module.product.convert.category.ProductCategoryConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "用户 APP - 商品分类")
@RestController
@RequestMapping("/product/category")
@Validated
public class AppCategoryController {
@Resource
private ProductCategoryService categoryService;
@GetMapping("/list")
@Operation(summary = "获得商品分类列表")
public CommonResult<List<AppCategoryRespVO>> getProductCategoryList() {
List<ProductCategoryDO> list = categoryService.getEnableCategoryList();
list.sort(Comparator.comparing(ProductCategoryDO::getSort));
return success(ProductCategoryConvert.INSTANCE.convertList03(list));
}
}

View File

@ -1,28 +0,0 @@
package cn.iocoder.yudao.module.product.controller.app.category.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
@Schema(description = "用户 APP - 商品分类 Response VO")
public class AppCategoryRespVO {
@Schema(description = "分类编号", required = true, example = "2")
private Long id;
@Schema(description = "父分类编号", required = true, example = "1")
@NotNull(message = "父分类编号不能为空")
private Long parentId;
@Schema(description = "分类名称", required = true, example = "办公文具")
@NotBlank(message = "分类名称不能为空")
private String name;
@Schema(description = "分类图片", required = true)
@NotBlank(message = "分类图片不能为空")
private String picUrl;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,78 +0,0 @@
package cn.iocoder.yudao.module.product.controller.app.spu;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_ENABLE;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
@Tag(name = "用户 APP - 商品spu")
@RestController
@RequestMapping("/product/spu")
@Validated
public class AppProductSpuController {
@Resource
private ProductSpuService productSpuService;
@Resource
private ProductSkuService productSkuService;
@Resource
private ProductPropertyValueService productPropertyValueService;
@GetMapping("/page")
@Operation(summary = "获得商品 SPU 分页")
public CommonResult<PageResult<AppProductSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus());
return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult));
}
@GetMapping("/get-detail")
@Operation(summary = "获得商品 SPU 明细")
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
public CommonResult<AppProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
// 获得商品 SPU
ProductSpuDO spu = productSpuService.getSpu(id);
if (spu == null) {
throw exception(SPU_NOT_EXISTS);
}
if (!ProductSpuStatusEnum.isEnable(spu.getStatus())) {
throw exception(SPU_NOT_ENABLE);
}
// 查询商品 SKU
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(),
CommonStatusEnum.ENABLE.getStatus());
// 查询商品属性
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
// 拼接
return success(ProductSpuConvert.INSTANCE.convert(spu, skus, propertyValues));
}
}

View File

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

View File

@ -1,40 +0,0 @@
package cn.iocoder.yudao.module.product.controller.app.spu.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
@ApiModel("用户 App - 商品 SPU 分页项 Response VO")
@Data
public class AppProductSpuPageItemRespVO {
@ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
private Long id;
@ApiModelProperty(value = "商品名称", required = true, example = "芋道")
@NotEmpty(message = "商品名称不能为空")
private String name;
@ApiModelProperty(value = "分类编号", required = true)
@NotNull(message = "分类编号不能为空")
private Long categoryId;
@ApiModelProperty(value = "商品图片的数组", required = true)
private List<String> picUrls;
@ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
private Integer minPrice;
@ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024")
private Integer maxPrice;
// ========== 统计相关字段 =========
@ApiModelProperty(value = "商品销量", example = "1024")
private Integer salesCount;
}

View File

@ -1,44 +0,0 @@
package cn.iocoder.yudao.module.product.controller.app.spu.vo;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.AssertTrue;
@ApiModel("用户 App - 商品 SPU 分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AppProductSpuPageReqVO extends PageParam {
public static final String SORT_FIELD_PRICE = "price";
public static final String SORT_FIELD_SALES_COUNT = "salesCount";
@ApiModelProperty(value = "分类编号", example = "1")
private Long categoryId;
@ApiModelProperty(value = "关键字", example = "好看")
private String keyword;
@ApiModelProperty(value = "排序字段", example = "price", notes = "参见 AppSpuPageReqVO.SORT_FIELD_XXX 常量")
private String sortField;
@ApiModelProperty(value = "排序方式", example = "true", notes = "true - 升序false - 降序")
private Boolean sortAsc;
@AssertTrue(message = "排序字段不合法")
@JsonIgnore
public boolean isSortFieldValid() {
if (StrUtil.isEmpty(sortField)) {
return true;
}
return StrUtil.equalsAny(sortField, SORT_FIELD_PRICE, SORT_FIELD_SALES_COUNT);
}
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.product.convert.brand;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandRespVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandUpdateReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 品牌 Convert
*
* @author 芋道源码
*/
@Mapper
public interface ProductBrandConvert {
ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class);
ProductBrandDO convert(ProductBrandCreateReqVO bean);
ProductBrandDO convert(ProductBrandUpdateReqVO bean);
ProductBrandRespVO convert(ProductBrandDO bean);
List<ProductBrandRespVO> convertList(List<ProductBrandDO> list);
PageResult<ProductBrandRespVO> convertPage(PageResult<ProductBrandDO> page);
}

View File

@ -1,32 +0,0 @@
package cn.iocoder.yudao.module.product.convert.category;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryRespVO;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.app.category.vo.AppCategoryRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 商品分类 Convert
*
* @author 芋道源码
*/
@Mapper
public interface ProductCategoryConvert {
ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
ProductCategoryDO convert(ProductCategoryCreateReqVO bean);
ProductCategoryDO convert(ProductCategoryUpdateReqVO bean);
ProductCategoryRespVO convert(ProductCategoryDO bean);
List<ProductCategoryRespVO> convertList(List<ProductCategoryDO> list);
List<AppCategoryRespVO> convertList03(List<ProductCategoryDO> list);
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.yudao.module.product.convert.property;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyAndValueRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyUpdateReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
/**
* 属性项 Convert
*
* @author 芋道源码
*/
@Mapper
public interface ProductPropertyConvert {
ProductPropertyConvert INSTANCE = Mappers.getMapper(ProductPropertyConvert.class);
ProductPropertyDO convert(ProductPropertyCreateReqVO bean);
ProductPropertyDO convert(ProductPropertyUpdateReqVO bean);
ProductPropertyRespVO convert(ProductPropertyDO bean);
List<ProductPropertyRespVO> convertList(List<ProductPropertyDO> list);
PageResult<ProductPropertyRespVO> convertPage(PageResult<ProductPropertyDO> page);
default List<ProductPropertyAndValueRespVO> convertList(List<ProductPropertyDO> keys, List<ProductPropertyValueDO> values) {
Map<Long, List<ProductPropertyValueDO>> valueMap = CollectionUtils.convertMultiMap(values, ProductPropertyValueDO::getPropertyId);
return CollectionUtils.convertList(keys, key -> {
ProductPropertyAndValueRespVO respVO = convert02(key);
respVO.setValues(convertList02(valueMap.get(key.getId())));
return respVO;
});
}
ProductPropertyAndValueRespVO convert02(ProductPropertyDO bean);
List<ProductPropertyAndValueRespVO.Value> convertList02(List<ProductPropertyValueDO> list);
}

View File

@ -1,55 +0,0 @@
package cn.iocoder.yudao.module.product.convert.propertyvalue;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 属性值 Convert
*
* @author 芋道源码
*/
@Mapper
public interface ProductPropertyValueConvert {
ProductPropertyValueConvert INSTANCE = Mappers.getMapper(ProductPropertyValueConvert.class);
ProductPropertyValueDO convert(ProductPropertyValueCreateReqVO bean);
ProductPropertyValueDO convert(ProductPropertyValueUpdateReqVO bean);
ProductPropertyValueRespVO convert(ProductPropertyValueDO bean);
List<ProductPropertyValueRespVO> convertList(List<ProductPropertyValueDO> list);
PageResult<ProductPropertyValueRespVO> convertPage(PageResult<ProductPropertyValueDO> page);
default List<ProductPropertyValueDetailRespBO> convertList(List<ProductPropertyValueDO> values, List<ProductPropertyDO> keys) {
Map<Long, ProductPropertyDO> keyMap = convertMap(keys, ProductPropertyDO::getId);
return CollectionUtils.convertList(values, value -> {
ProductPropertyValueDetailRespBO valueDetail = new ProductPropertyValueDetailRespBO()
.setValueId(value.getId()).setValueName(value.getName());
// 设置属性项
MapUtils.findAndThen(keyMap, value.getPropertyId(),
key -> valueDetail.setPropertyId(key.getId()).setPropertyName(key.getName()));
return valueDetail;
});
}
List<ProductPropertyValueDetailRespDTO> convertList02(List<ProductPropertyValueDetailRespBO> list);
}

View File

@ -1,93 +0,0 @@
package cn.iocoder.yudao.module.product.convert.sku;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuOptionRespVO;
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuDetailRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 商品 SKU Convert
*
* @author 芋道源码
*/
@Mapper
public interface ProductSkuConvert {
ProductSkuConvert INSTANCE = Mappers.getMapper(ProductSkuConvert.class);
ProductSkuDO convert(ProductSkuCreateOrUpdateReqVO bean);
ProductSkuRespVO convert(ProductSkuDO bean);
List<ProductSkuRespVO> convertList(List<ProductSkuDO> list);
List<ProductSkuDO> convertList06(List<ProductSkuCreateOrUpdateReqVO> list);
default List<ProductSkuDO> convertList06(List<ProductSkuCreateOrUpdateReqVO> list, Long spuId, String spuName) {
List<ProductSkuDO> result = convertList06(list);
result.forEach(item -> item.setSpuId(spuId).setSpuName(spuName));
return result;
}
ProductSkuRespDTO convert02(ProductSkuDO bean);
List<ProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> list);
List<ProductSkuRespDTO> convertList04(List<ProductSkuDO> list);
List<ProductSkuOptionRespVO> convertList05(List<ProductSkuDO> skus);
/**
* 获得 SPU 的库存变化 Map
*
* @param items SKU 库存变化
* @param skus SKU 列表
* @return SPU 的库存变化 Map
*/
default Map<Long, Integer> convertSpuStockMap(List<ProductSkuUpdateStockReqDTO.Item> items,
List<ProductSkuDO> skus) {
Map<Long, Long> skuIdAndSpuIdMap = convertMap(skus, ProductSkuDO::getId, ProductSkuDO::getSpuId); // SKU SKU 编号的 Map 关系
Map<Long, Integer> spuIdAndStockMap = new HashMap<>(); // SPU 的库存变化 Map 关系
items.forEach(item -> {
Long spuId = skuIdAndSpuIdMap.get(item.getId());
if (spuId == null) {
return;
}
Integer stock = spuIdAndStockMap.getOrDefault(spuId, 0) + item.getIncrCount();
spuIdAndStockMap.put(spuId, stock);
});
return spuIdAndStockMap;
}
default Collection<Long> convertPropertyValueIds(List<ProductSkuDO> list) {
if (CollUtil.isEmpty(list)) {
return new HashSet<>();
}
return list.stream().filter(item -> item.getProperties() != null)
.flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性
.map(ProductSkuDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId最后形成集合
.collect(Collectors.toSet());
}
default String buildPropertyKey(ProductSkuDO bean) {
if (CollUtil.isEmpty(bean.getProperties())) {
return StrUtil.EMPTY;
}
List<ProductSkuDO.Property> properties = new ArrayList<>(bean.getProperties());
properties.sort(Comparator.comparing(ProductSkuDO.Property::getValueId));
return properties.stream().map(m -> String.valueOf(m.getValueId())).collect(Collectors.joining());
}
}

View File

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

View File

@ -1,53 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.brand;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品品牌 DO
*
* @author 芋道源码
*/
@TableName("product_brand")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductBrandDO extends BaseDO {
/**
* 品牌编号
*/
@TableId
private Long id;
/**
* 品牌名称
*/
private String name;
/**
* 品牌图片
*/
private String picUrl;
/**
* 品牌排序
*/
private Integer sort;
/**
* 品牌描述
*/
private String description;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
// TODO 芋艿firstLetter 首字母
}

View File

@ -1,67 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.category;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品分类 DO
*
* 商品分类一共两类
* 1一级分类{@link #parentId} 等于 0
* 2二级 + 三级分类{@link #parentId} 不等于 0
*
* @author 芋道源码
*/
@TableName("product_category")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductCategoryDO extends BaseDO {
/**
* 父分类编号 - 根分类
*/
public static final Long PARENT_ID_NULL = 0L;
/**
* 分类编号
*/
@TableId
private Long id;
/**
* 父分类编号
*/
private Long parentId;
/**
* 分类名称
*/
private String name;
/**
* 分类图片
*
* 一级分类推荐 200 x 100 分辨率
* 二级 + 三级分类推荐 100 x 100 分辨率
*/
private String picUrl;
/**
* 分类排序
*/
private Integer sort;
/**
* 分类描述
*/
private String description;
/**
* 开启状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
}

View File

@ -1,129 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.comment;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.comment.ProductCommentAuditStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.time.LocalDateTime;
import java.util.List;
/**
* 商品评论 DO
*
* @author 芋道源码
*/
@TableName("product_comment")
@KeySequence("product_comment_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductCommentDO extends BaseDO {
/**
* 评论编号主键自增
*/
@TableId
private Long id;
/**
* 商品 SPU 编号
*
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
/**
* 交易订单编号
*
* 关联 TradeOrderDO id 编号
*/
private Long orderId;
/**
* 交易订单项编号
*
* 关联 TradeOrderItemDO id 编号
*/
private Long orderItemId;
/**
* 审核状态
*
* 枚举 {@link ProductCommentAuditStatusEnum}
*/
private Integer auditStatus;
/**
* 用户编号
*
* 关联 MemberUserDO id 编号
*/
private Long userId;
/**
* 用户 IP
*/
private String userIp;
/**
* 是否匿名
*/
private Boolean anonymous;
/**
* 评论内容
*/
private String content;
/**
* 评论图片地址数组
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> picUrls;
/**
* 描述相符星级
*
* 1-5
*/
private Integer descriptionScore;
/**
* 商品评论星级
*
* 1-5
*/
private Integer productScore;
/**
* 服务评论星级
*
* 1-5
*/
private Integer serviceScore;
/**
* 物流评论星级
*
* 1-5
*/
private Integer expressComment;
/**
* 商家是否回复
*/
private Boolean replied;
/**
* 商家回复内容
*/
private String replyContent;
/**
* 商家回复时间
*/
private LocalDateTime replyTime;
/**
* 有用的计数
*
* 其他用户看到评论时可点击有用按钮
*/
private Integer usefulCount;
}

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.delivery;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 配送模板 SPU DO
*
* @author 芋道源码
*/
@TableName("delivery_template")
@KeySequence("delivery_template_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DeliveryTemplateDO extends BaseDO {
/**
* 编号自增
*/
@TableId
private Long id;
}

View File

@ -1,45 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.favorite;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品收藏 DO
*
* @author 芋道源码
*/
@TableName("product_favorite")
@KeySequence("product_favorite_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductFavoriteDO extends BaseDO {
/**
* 编号主键自增
*/
@TableId
private Long id;
/**
* 用户编号
*
* 关联 MemberUserDO id 编号
*/
private Long userId;
/**
* 商品 SPU 编号
*
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
// TODO 芋艿type 1 收藏2 点赞
}

View File

@ -1,43 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.group;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品分组的绑定 DO
*
* @author 芋道源码
*/
@TableName("product_group_bind")
@KeySequence("product_group_bind_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductGroupBindDO extends BaseDO {
/**
* 编号自增
*/
@TableId
private Long id;
/**
* 商品分组编号
*
* 关联 {@link ProductGroupDO#getId()}
*/
private Long groupId;
/**
* 商品 SPU 编号
*
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
}

View File

@ -1,63 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.group;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.enums.group.ProductGroupStyleEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品分组 DO
*
* @author 芋道源码
*/
@TableName("product_group")
@KeySequence("product_group_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductGroupDO extends BaseDO {
/**
* 商品分组编号自增
*/
@TableId
private Long id;
/**
* 分组名称
*/
private String name;
/**
* 状态
*
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 商品数量
*/
private Integer count;
/**
* 排序
*/
private Integer sort;
/**
* 风格用于 APP 首页展示商品的样式
*
* 枚举 {@link ProductGroupStyleEnum}
*/
private Integer style;
/**
* 是否默认
*
* true - 系统默认不允许删除
* false - 自定义允许删除
*/
private Boolean defaulted;
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.property;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品属性项 DO
*
* @author 芋道源码
*/
@TableName("product_property")
@KeySequence("product_property_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductPropertyDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 名称
*/
private String name;
/**
* 备注
*/
private String remark;
}

View File

@ -1,46 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.property;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品属性值 DO
*
* @author 芋道源码
*/
@TableName("product_property_value")
@KeySequence("product_property_value_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductPropertyValueDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 属性项的编号
*
* 关联 {@link ProductPropertyDO#getId()}
*/
private Long propertyId;
/**
* 名称
*/
private String name;
/**
* 备注
*
*/
private String remark;
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.search;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品热搜关键字 DO
*
* @author 芋道源码
*/
@TableName("product_hot_search")
@KeySequence("product_hot_search_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductHotSearchDO extends BaseDO {
/**
* 编号主键自增
*/
@TableId
private Long id;
/**
* 关键字
*/
private String name;
/**
* 内容
*/
private String content;
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.shop;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
// TODO 芋艿待设计
/**
* 店铺 DO
*
* @author 芋道源码
*/
@TableName("shop")
@KeySequence("shop_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ShopDO extends BaseDO {
private Long id;
}

View File

@ -1,137 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.sku;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import lombok.*;
import java.util.List;
/**
* 商品 SKU DO
*
* @author 芋道源码
*/
@TableName(value = "product_sku",autoResultMap = true)
@KeySequence("product_sku_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductSkuDO extends BaseDO {
/**
* 商品 SKU 编号自增
*/
@TableId
private Long id;
/**
* SPU 编号
* <p>
* 关联 {@link ProductSpuDO#getId()}
*/
private Long spuId;
/**
* SPU 名字
*
* 冗余 {@link ProductSkuDO#getSpuName()}
*/
private String spuName;
/**
* 属性数组JSON 格式
*/
@TableField(typeHandler = PropertyTypeHandler.class)
private List<Property> properties;
/**
* 销售价格单位
*/
private Integer price;
/**
* 市场价单位
*/
private Integer marketPrice;
/**
* 成本价单位
*/
private Integer costPrice;
/**
* SKU 的条形码
*/
private String barCode;
/**
* 图片地址
*/
private String picUrl;
/**
* SKU 状态
* <p>
* 枚举 {@link CommonStatusEnum}
*/
private Integer status;
/**
* 库存
*/
private Integer stock;
/**
* 预警预存
*/
private Integer warnStock;
/**
* 商品重量单位kg 千克
*/
private Double weight;
/**
* 商品体积单位m^3 平米
*/
private Double volume;
/**
* 商品属性
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Property {
/**
* 属性编号
* <p>
* 关联 {@link ProductPropertyDO#getId()}
*/
private Long propertyId;
/**
* 属性值编号
* <p>
* 关联 {@link ProductPropertyValueDO#getId()}
*/
private Long valueId;
}
// TODO @芋艿可以找一些新的思路
public static class PropertyTypeHandler extends AbstractJsonTypeHandler<Object> {
@Override
protected Object parse(String json) {
return JsonUtils.parseArray(json, Property.class);
}
@Override
protected String toJson(Object obj) {
return JsonUtils.toJsonString(obj);
}
}
}

View File

@ -1,212 +0,0 @@
package cn.iocoder.yudao.module.product.dal.dataobject.spu;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.*;
import java.util.List;
/**
* 商品 SPU DO
*
* @author 芋道源码
*/
@TableName(value = "product_spu", autoResultMap = true)
@KeySequence("product_spu_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductSpuDO extends BaseDO {
/**
* 商品 SPU 编号自增
*/
@TableId
private Long id;
// ========== 基本信息 =========
/**
* 商品名称
*/
private String name;
/**
* 商品编码
*/
private String code;
/**
* 促销语
*/
private String sellPoint;
/**
* 商品详情
*/
private String description;
/**
* 商品分类编号
*
* 关联 {@link ProductCategoryDO#getId()}
*/
private Long categoryId;
/**
* 商品品牌编号
*
* 关联 {@link ProductBrandDO#getId()}
*/
private Long brandId;
/**
* 商品图片的数组
*
* 1. 第一张图片将作为商品主图支持同时上传多张图
* 2. 建议使用尺寸 800x800 像素以上大小不超过 1M 的正方形图片
* 3. 至少 1 最多上传 10
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> picUrls;
/**
* 商品视频
*/
private String videoUrl;
/**
* 排序字段
*/
private Integer sort;
/**
* 商品状态
*
* 枚举 {@link ProductSpuStatusEnum}
*/
private Integer status;
// ========== SKU 相关字段 =========
/**
* 规格类型
*
* 枚举 {@link ProductSpuSpecTypeEnum}
*/
private Integer specType;
/**
* 最小价格单位使用
*
* 基于其对应的 {@link ProductSkuDO#getPrice()} 最小值
*/
private Integer minPrice;
/**
* 最大价格单位使用
*
* 基于其对应的 {@link ProductSkuDO#getPrice()} 最大值
*/
private Integer maxPrice;
/**
* 市场价单位使用
*
* 基于其对应的 {@link ProductSkuDO#getMarketPrice()} 最大值
*/
private Integer marketPrice;
/**
* 总库存
*
* 基于其对应的 {@link ProductSkuDO#getStock()} 求和
*/
private Integer totalStock;
/**
* 是否展示库存
*/
private Boolean showStock;
// ========== 统计相关字段 =========
/**
* 商品销量
*/
private Integer salesCount;
/**
* 虚拟销量
*/
private Integer virtualSalesCount;
/**
* 商品点击量
*/
private Integer clickCount;
// ========== 物流相关字段 =========
// TODO 芋艿稍后完善物流的字段
// /**
// * 配送方式
// *
// * 枚举 {@link DeliveryModeEnum}
// */
// private Integer deliveryMode;
// /**
// * 配置模板编号
// *
// * 关联 {@link DeliveryTemplateDO#getId()}
// */
// private Long deliveryTemplateId;
// TODO ========== 待定字段yv =========
// TODO vip_price 会员价格
// TODO postage 邮费
// TODO is_postage 是否包邮
// TODO unit_name 单位
// TODO is_new 商户是否代理
// TODO give_integral 获得积分
// TODO is_integral 是开启积分兑换
// TODO integral 所需积分
// TODO is_seckill 秒杀状态
// TODO is_bargain 砍价状态
// TODO code_path 产品二维码地址
// TODO is_sub 是否分佣
// TODO 芋艿 看起来走分组更合适
// TODO is_hot 是否热卖
// TODO is_benefit 是否优惠
// TODO is_best 是否精品
// TODO is_new 是否新品
// TODO is_good 是否优品推荐
// TODO ========== 待定字段cf =========
// TODO source_link 淘宝京东1688类型
// TODO activity 活动显示排序 0=默认 1= 2=砍价 3=拼团
// TODO ========== 待定字段lf =========
// TODO free_shipping_type运费类型1-包邮2-统一运费3-运费模板
// TODO free_shipping统一运费金额
// TODO free_shipping_template_id运费模板
// TODO is_commission分销佣金1-开启0-不开启first_ratio second_ratio three_ratio
// TODO is_share_bouns区域股东分红1-开启0-不开启region_ratioshareholder_ratio
// TODO is_new新品推荐1-0-
// TODO is_best好物优选1-0-
// TODO is_like猜你喜欢1-0-
// TODO is_team是否开启拼团[0= 1=]
// TODO is_integral积分抵扣1-开启0-不开启
// TODO is_member会员价1-开启0-不开启
// TODO give_integral_type赠送积分类型0-不赠送1-赠送固定积分2-按比例赠送积分
// TODO give_integral赠送积分
// TODO poster商品自定义海报
// TODO ========== 待定字段laoji =========
// TODO productType 1 - 普通商品 2 - 预售商品可能和 type 合并不错
// TODO productUnit 商品单位
// TODO extJson 扩展信息例如说预售商品的信息
}

View File

@ -1,34 +0,0 @@
package cn.iocoder.yudao.module.product.dal.mysql.brand;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandListReqVO;
import cn.iocoder.yudao.module.product.controller.admin.brand.vo.ProductBrandPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ProductBrandMapper extends BaseMapperX<ProductBrandDO> {
default PageResult<ProductBrandDO> selectPage(ProductBrandPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductBrandDO>()
.likeIfPresent(ProductBrandDO::getName, reqVO.getName())
.eqIfPresent(ProductBrandDO::getStatus, reqVO.getStatus())
.betweenIfPresent(ProductBrandDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductBrandDO::getId));
}
default List<ProductBrandDO> selectList(ProductBrandListReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<ProductBrandDO>()
.likeIfPresent(ProductBrandDO::getName, reqVO.getName()));
}
default ProductBrandDO selectByName(String name) {
return selectOne(ProductBrandDO::getName, name);
}
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.product.dal.mysql.category;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 商品分类 Mapper
*
* @author 芋道源码
*/
@Mapper
public interface ProductCategoryMapper extends BaseMapperX<ProductCategoryDO> {
default List<ProductCategoryDO> selectList(ProductCategoryListReqVO listReqVO) {
return selectList(new LambdaQueryWrapperX<ProductCategoryDO>()
.likeIfPresent(ProductCategoryDO::getName, listReqVO.getName())
.orderByDesc(ProductCategoryDO::getId));
}
default Long selectCountByParentId(Long parentId) {
return selectCount(ProductCategoryDO::getParentId, parentId);
}
default List<ProductCategoryDO> selectListByStatus(Integer status) {
return selectList(ProductCategoryDO::getStatus, status);
}
}

View File

@ -1,32 +0,0 @@
package cn.iocoder.yudao.module.product.dal.mysql.property;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyListReqVO;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> {
default PageResult<ProductPropertyDO> selectPage(ProductPropertyPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductPropertyDO>()
.likeIfPresent(ProductPropertyDO::getName, reqVO.getName())
.betweenIfPresent(ProductPropertyDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductPropertyDO::getId));
}
default ProductPropertyDO selectByName(String name) {
return selectOne(ProductPropertyDO::getName, name);
}
default List<ProductPropertyDO> selectList(ProductPropertyListReqVO listReqVO) {
return selectList(new LambdaQueryWrapperX<ProductPropertyDO>()
.eqIfPresent(ProductPropertyDO::getName, listReqVO.getName()));
}
}

View File

@ -1,43 +0,0 @@
package cn.iocoder.yudao.module.product.dal.mysql.property;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
import java.util.List;
@Mapper
public interface ProductPropertyValueMapper extends BaseMapperX<ProductPropertyValueDO> {
default List<ProductPropertyValueDO> selectListByPropertyId(Collection<Long> propertyIds) {
return selectList(new LambdaQueryWrapperX<ProductPropertyValueDO>()
.inIfPresent(ProductPropertyValueDO::getPropertyId, propertyIds));
}
default ProductPropertyValueDO selectByName(Long propertyId, String name) {
return selectOne(new LambdaQueryWrapperX<ProductPropertyValueDO>()
.eq(ProductPropertyValueDO::getPropertyId, propertyId)
.eq(ProductPropertyValueDO::getName, name));
}
default void deleteByPropertyId(Long propertyId) {
delete(new LambdaQueryWrapperX<ProductPropertyValueDO>()
.eq(ProductPropertyValueDO::getPropertyId, propertyId));
}
default PageResult<ProductPropertyValueDO> selectPage(ProductPropertyValuePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductPropertyValueDO>()
.eqIfPresent(ProductPropertyValueDO::getPropertyId, reqVO.getPropertyId())
.likeIfPresent(ProductPropertyValueDO::getName, reqVO.getName())
.orderByDesc(ProductPropertyValueDO::getId));
}
default Integer selectCountByPropertyId(Long propertyId) {
return selectCount(ProductPropertyValueDO::getPropertyId, propertyId).intValue();
}
}

Some files were not shown because too many files have changed in this diff Show More