调整product服务项目结构,商品规格列表接口

This commit is contained in:
q2118cs
2020-05-06 17:04:38 +08:00
parent 9f3dc3c087
commit 4669e81645
139 changed files with 3915 additions and 111 deletions

View File

@@ -0,0 +1,33 @@
package cn.iocoder.mall.product.biz.bo.attr;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
@Data
@Accessors(chain = true)
public class ProductAttrBO {
/**
* 规格编号
*/
private Integer id;
/**
* 规格名
*/
private String name;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
/**
* 规格值数组
*/
private List<ProductAttrValueBO> values;
}

View File

@@ -0,0 +1,33 @@
package cn.iocoder.mall.product.biz.bo.attr;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品规格值 VO
*/
@Data
@Accessors(chain = true)
public class ProductAttrValueBO implements Serializable {
/**
* 规格值编号
*/
private Integer id;
/**
* 规格值名
*/
private String name;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}

View File

@@ -0,0 +1,5 @@
/**
* author: sin
* time: 2020/5/3 8:31 下午
*/
package cn.iocoder.mall.product.biz.bo;

View File

@@ -0,0 +1,32 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 商品规格明细 BO
*/
@Data
@Accessors(chain = true)
public class ProductAttrAndValuePairBO implements Serializable {
/**
* 规格编号
*/
private Integer attrId;
/**
* 规格名
*/
private String attrName;
/**
* 规格值
*/
private Integer attrValueId;
/**
* 规格值名
*/
private String attrValueName;
}

View File

@@ -0,0 +1,33 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品规格 VO
*/
@Data
@Accessors(chain = true)
public class ProductAttrBO2 implements Serializable {
/**
* 规格编号
*/
private Integer id;
/**
* 规格名
*/
private String name;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}

View File

@@ -0,0 +1,38 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 商品规格明细 VO
*/
@Data
@Accessors(chain = true)
public class ProductAttrDetailBO implements Serializable {
/**
* 规格编号
*/
private Integer id;
/**
* 规格名
*/
private String name;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
/**
* 规格值数组
*/
private List<ProductAttrValueDetailBO> values;
}

View File

@@ -0,0 +1,25 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品规格明细分页 BO
*/
@Data
@Accessors(chain = true)
public class ProductAttrPageBO implements Serializable {
/**
* 规格数组
*/
private List<ProductAttrDetailBO> attrs;
/**
* 总数
*/
private Integer count;
}

View File

@@ -0,0 +1,29 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品规格精简 VO
*/
@Data
@Accessors(chain = true)
public class ProductAttrSimpleBO implements Serializable {
/**
* 规格编号
*/
private Integer id;
/**
* 规格名
*/
private String name;
/**
* 规格值数组
*/
private List<ProductAttrValueSimpleBO> values;
}

View File

@@ -0,0 +1,37 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品规格值 VO
*/
@Data
@Accessors(chain = true)
public class ProductAttrValueBO implements Serializable {
/**
* 规格值编号
*/
private Integer id;
/**
* 规格编号
*/
private Integer attrId;
/**
* 规格值名
*/
private String name;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}

View File

@@ -0,0 +1,33 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品规格值 VO
*/
@Data
@Accessors(chain = true)
public class ProductAttrValueDetailBO implements Serializable {
/**
* 规格值编号
*/
private Integer id;
/**
* 规格值名
*/
private String name;
/**
* 状态
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}

View File

@@ -0,0 +1,24 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 商品规格值 VO
*/
@Data
@Accessors(chain = true)
public class ProductAttrValueSimpleBO implements Serializable {
/**
* 规格值编号
*/
private Integer id;
/**
* 规格值名
*/
private String name;
}

View File

@@ -0,0 +1,42 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 商品品牌 VO
*/
@Data
@Accessors(chain = true)
public class ProductBrandBO implements Serializable {
/**
* 规格编号
*/
private Integer id;
/**
* 名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 图片地址
*/
private String picUrl;
/**
* 状态
*
* 1-开启
* 2-禁用
*/
private Integer status;
}

View File

@@ -0,0 +1,25 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品品牌分页 BO
*/
@Data
@Accessors(chain = true)
public class ProductBrangPageBO implements Serializable {
/**
* 品牌数组
*/
private List<ProductBrandBO> brands;
/**
* 总数
*/
private Integer count;
}

View File

@@ -0,0 +1,54 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品分类 BO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryBO implements Serializable {
/**
* 分类编号
*/
private Integer id;
/**
* 父分类编号
*
* 如果不存在父级,则 pid = 0 。
*/
private Integer pid;
/**
* 名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 排序值
*/
private Integer sort;
/**
* 状态
*
* 1-开启
* 2-关闭
*/
private Integer status;
/**
* 创建时间
*/
private Date createTime;
}

View File

@@ -0,0 +1,45 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 商品 SKU BO
*/
@Data
@Accessors(chain = true)
public class ProductSkuBO implements Serializable {
/**
* sku 编号
*/
private Integer id;
/**
* 商品编号
*/
private Integer spuId;
/**
* 状态
*/
private Integer status;
/**
* 图片地址
*/
private String picURL;
// /**
// * 规格值数组
// */
// // TODO 芋艿,这个属性目前未进行设置
// private List<ProductAttrAndValuePairBO> attrs;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
}

View File

@@ -0,0 +1,91 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品 Sku 明细 BO包括 Spu 明细)
*/
@Data
@Accessors(chain = true)
public class ProductSkuDetailBO implements Serializable {
/**
* sku 编号
*/
private Integer id;
/**
* SPU 信息
*/
private Spu spu;
/**
* 图片地址
*/
private String picURL;
/**
* 规格值数组
*/
private List<ProductAttrAndValuePairBO> attrs;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
@Data
@Accessors(chain = true)
public static class Spu implements Serializable {
/**
* SPU 编号
*/
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
private String name;
/**
* 卖点
*/
private String sellPoint;
/**
* 描述
*/
private String description;
/**
* 分类编号
*/
private Integer cid;
/**
* 商品主图地址
*
* 数组,以逗号分隔
*
* 建议尺寸800*800像素你可以拖拽图片调整顺序最多上传15张
*/
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
private Boolean visible;
/**
* 排序字段
*/
private Integer sort;
}
}

View File

@@ -0,0 +1,74 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品 SPU BO
*/
@Data
@Accessors(chain = true)
public class ProductSpuBO implements Serializable {
/**
* SPU 编号
*/
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
private String name;
/**
* 卖点
*/
private String sellPoint;
/**
* 描述
*/
private String description;
/**
* 分类编号
*/
private Integer cid;
/**
* 商品主图地址
*
* 数组,以逗号分隔
*
* 建议尺寸800*800像素你可以拖拽图片调整顺序最多上传15张
*/
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
private Boolean visible;
/**
* 排序字段
*/
private Integer sort;
// ========== Sku 相关字段 =========
/**
* 价格
*
* 目前的计算方式是,以 Sku 最小价格为准
*/
private Integer price;
/**
* 库存数量
*
* 目前的计算方式是,以 Sku 库存累加为准
*/
private Integer quantity;
}

View File

@@ -0,0 +1,105 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品 Spu 明细 BO包括 Sku 明细)
*/
@Data
@Accessors(chain = true)
public class ProductSpuDetailBO implements Serializable {
/**
* SPU 编号
*/
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
private String name;
/**
* 卖点
*/
private String sellPoint;
/**
* 描述
*/
private String description;
/**
* 分类编号
*/
private Integer cid;
/**
* 分类名
*/
private String categoryName;
/**
* 商品主图地址
*
* 数组,以逗号分隔
*
* 建议尺寸800*800像素你可以拖拽图片调整顺序最多上传15张
*/
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
private Boolean visible;
/**
* 排序字段
*/
private Integer sort;
// ========== SKU =========
/**
* SKU 数组
*/
private List<Sku> skus;
/**
* 商品 Sku 明细 BO
*/
@Data
@Accessors(chain = true)
public static class Sku implements Serializable {
/**
* sku 编号
*/
private Integer id;
/**
* 商品编号
*/
private Integer spuId;
/**
* 图片地址
*/
private String picURL;
/**
* 规格值数组
*/
private List<ProductAttrAndValuePairBO> attrs;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
}
}

View File

@@ -0,0 +1,25 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品 SPU 分页 BO
*/
@Data
@Accessors(chain = true)
public class ProductSpuPageBO implements Serializable {
/**
* Spu 数组
*/
private List<ProductSpuBO> list;
/**
* 总量
*/
private Integer total;
}

View File

@@ -0,0 +1,74 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 用户_商品_收藏记录表
* @author xiaofeng
* @date 2019-07-01 20:23:30
*/
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsBO implements Serializable {
/**
* id自增长
*/
private Integer id;
/**
* 用户id
*/
private Integer userId;
/**
* 用户名称
*/
private String nickname;
/**
* 商品id
*/
private Integer spuId;
/**
* 商品名字
*/
private String spuName;
/**
* 图片名字
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 删除状态
*/
private Integer deleted;
}

View File

@@ -0,0 +1,30 @@
package cn.iocoder.mall.product.biz.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;
/**
* 商品收藏分页
* @author xiaofeng
* @date 2019/07/06 18:37
* @version 1.0
*/
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsPageBO implements Serializable {
/**
* 返回的数据列表
*/
private List<UserProductSpuCollectionsBO> list;
/**
* 总量
*/
private Integer total;
}

View File

@@ -0,0 +1,26 @@
package cn.iocoder.mall.product.biz.config;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("cn.iocoder.mall.product.biz.dao") // 扫描对应的 Mapper 接口
@EnableTransactionManagement(proxyTargetClass = true)
// 启动事务管理。为什么使用 proxyTargetClass 参数,参见 https://blog.csdn.net/huang_550/article/details/76492600
public class DatabaseConfiguration {
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor(); // MyBatis Plus 分页插件
}
}

View File

@@ -0,0 +1,10 @@
package cn.iocoder.mall.product.biz.config;
import cn.iocoder.mall.product.biz.message.MQStreamProducer;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBinding(MQStreamProducer.class)
public class MQStreamConfiguration {
}

View File

@@ -0,0 +1,26 @@
package cn.iocoder.mall.product.biz.convert.attr;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrBO;
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrValueBO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrDO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrValueDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductAttrConvert {
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
@Mapping(source = "records", target = "list")
PageResult<ProductAttrBO> convertPage(IPage<ProductAttrDO> bean);
@Mappings({})
List<ProductAttrValueBO> convertAttrValue(List<ProductAttrValueDO> values);
}

View File

@@ -0,0 +1,5 @@
/**
* author: sin
* time: 2020/5/3 8:31 下午
*/
package cn.iocoder.mall.product.biz.convert;

View File

@@ -0,0 +1,58 @@
package cn.iocoder.mall.product.biz.convert.product;
import cn.iocoder.mall.product.biz.bo.product.*;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrDO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrValueDO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrUpdateDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrValueAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrValueUpdateDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductAttrConvert2 {
ProductAttrConvert2 INSTANCE = Mappers.getMapper(ProductAttrConvert2.class);
@Mappings({})
List<ProductAttrDetailBO> convert(List<ProductAttrDO> attrs);
@Mappings({})
ProductAttrValueDetailBO convert(ProductAttrValueDO value);
@Mappings({})
List<ProductAttrValueDetailBO> convert2(List<ProductAttrValueDO> values);
@Mappings({})
List<ProductAttrSimpleBO> convert3(List<ProductAttrDO> attrs);
@Mappings({})
ProductAttrValueSimpleBO convert3(ProductAttrValueDO value); // 保证 convert4 能够映射到这个方法
@Mappings({})
List<ProductAttrValueSimpleBO> convert4(List<ProductAttrValueDO> values);
@Mappings({})
ProductAttrDO convert(ProductAttrAddDTO productAttrAddDTO);
@Mappings({})
ProductAttrDO convert(ProductAttrUpdateDTO productAttrUpdateDTO);
@Mappings({})
ProductAttrValueDO convert(ProductAttrValueAddDTO productAttrValueAddDTO);
@Mappings({})
ProductAttrValueDO convert(ProductAttrValueUpdateDTO productAttrValueUpdateDTO);
@Mappings({})
ProductAttrBO2 convert(ProductAttrDO productAttrDO);
@Mappings({})
ProductAttrValueBO convert2(ProductAttrValueDO productAttrValueDO);
}

View File

@@ -0,0 +1,30 @@
package cn.iocoder.mall.product.biz.convert.product;
import cn.iocoder.mall.product.biz.bo.product.ProductBrandBO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductBrandDO;
import cn.iocoder.mall.product.biz.dto.product.ProductBrandAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductBrandUpdateDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductBrandConvert {
ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class);
@Mappings({})
List<ProductBrandBO> convert(List<ProductBrandDO> brands);
@Mappings({})
ProductBrandBO convert(ProductBrandDO brand);
@Mappings({})
ProductBrandDO convert(ProductBrandUpdateDTO brand);
@Mappings({})
ProductBrandDO convert(ProductBrandAddDTO brand);
}

View File

@@ -0,0 +1,30 @@
package cn.iocoder.mall.product.biz.convert.product;
import cn.iocoder.mall.product.biz.bo.product.ProductCategoryBO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductCategoryDO;
import cn.iocoder.mall.product.biz.dto.product.ProductCategoryAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductCategoryUpdateDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductCategoryConvert {
ProductCategoryConvert INSTANCE = Mappers.getMapper(ProductCategoryConvert.class);
@Mappings({})
ProductCategoryBO convertToBO(ProductCategoryDO category);
@Mappings({})
List<ProductCategoryBO> convertToBO(List<ProductCategoryDO> categoryList);
@Mappings({})
ProductCategoryDO convert(ProductCategoryAddDTO productCategoryAddDTO);
@Mappings({})
ProductCategoryDO convert(ProductCategoryUpdateDTO productCategoryUpdateDTO);
}

View File

@@ -0,0 +1,135 @@
package cn.iocoder.mall.product.biz.convert.product;
import cn.iocoder.common.framework.util.StringUtil;
import cn.iocoder.mall.product.biz.bo.product.*;
import cn.iocoder.mall.product.biz.dataobject.product.ProductCategoryDO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductSkuDO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductSpuDO;
import cn.iocoder.mall.product.biz.dto.product.ProductSkuAddOrUpdateDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductSpuAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductSpuUpdateDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Mapper
public interface ProductSpuConvert {
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
@Mappings({
@Mapping(source = "picUrls", target = "picUrls", qualifiedByName = "translatePicUrlsFromString")
})
ProductSpuBO convert(ProductSpuDO spu);
@Named("translatePicUrlsFromString")
default List<String> translatePicUrlsFromString(String picUrls) {
return StringUtil.split(picUrls, ",");
}
@Mappings({})
List<ProductSpuBO> convert(List<ProductSpuDO> spus);
@Mappings({
@Mapping(source = "picUrls", target = "picUrls", ignore = true)
})
ProductSpuDO convert(ProductSpuAddDTO productSpuAddDTO);
@Mappings({
@Mapping(source = "attrs", target = "attrs", ignore = true)
})
ProductSkuDO convert(ProductSkuAddOrUpdateDTO productSkuAddDTO);
@Mappings({
@Mapping(source = "picUrls", target = "picUrls", ignore = true)
})
ProductSpuDO convert(ProductSpuUpdateDTO productSpuUpdateDTO);
@Mappings({})
ProductSpuDetailBO convert(ProductSpuBO spu);
@Mappings({
@Mapping(source = "picUrls", target = "picUrls", ignore = true)
})
ProductSpuDetailBO convert2(ProductSpuDO spu);
@Mappings({
@Mapping(source = "picUrls", target = "picUrls", ignore = true)
})
ProductSkuDetailBO.Spu convert3(ProductSpuDO spu);
@Mappings({
@Mapping(source = "attrs", target = "attrs", ignore = true)
})
ProductSpuDetailBO.Sku convert2(ProductSkuDO sku);
@Mappings({
@Mapping(source = "attrs", target = "attrs", ignore = true)
})
ProductSkuDetailBO convert3(ProductSkuDO sku);
@Mappings({
// @Mapping(source = "attrs", target = "attrs", ignore = true) // TODO 芋艿 后续补充
})
ProductSkuBO convert4(ProductSkuDO sku);
@Mappings({}) // TODO 芋艿,后续细看下 mapstruct 的 API ,优化这块
default ProductSpuDetailBO convert2(ProductSpuDO spu, List<ProductSkuDO> skus, List<ProductAttrAndValuePairBO> productAttrDetailBOs,
ProductCategoryDO category) {
// 创建并转换 ProductSpuDetailBO 对象
ProductSpuDetailBO spuDetail = this.convert2(spu).setPicUrls(StringUtil.split(spu.getPicUrls(), ","));
// 创建 ProductAttrDetailBO 的映射。其中KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
Map<Integer, ProductAttrAndValuePairBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
Collectors.toMap(ProductAttrAndValuePairBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
// 创建并转换 ProductSpuDetailBO 数组
spuDetail.setSkus(new ArrayList<>());
skus.forEach(sku -> {
// 创建 ProductSpuDetailBO 对象
ProductSpuDetailBO.Sku skuDetail = ProductSpuConvert.this.convert2(sku)
.setAttrs(new ArrayList<>());
spuDetail.getSkus().add(skuDetail);
// 设置 ProductSpuDetailBO 的 attrs 规格属性
List<String> attrs = StringUtil.split(sku.getAttrs(), ",");
attrs.forEach(attr -> skuDetail.getAttrs().add(productAttrDetailBOMap.get(Integer.valueOf(attr))));
});
// 设置分类名
spuDetail.setCategoryName(category.getName());
// 返回
return spuDetail;
}
@Mappings({}) // TODO 芋艿,后续细看下 mapstruct 的 API ,优化这块
default List<ProductSkuDetailBO> convert3(List<ProductSkuDO> skus, List<ProductSpuDO> spus, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
// 创建 ProductAttrDetailBO 的映射。其中KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
Map<Integer, ProductAttrAndValuePairBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
Collectors.toMap(ProductAttrAndValuePairBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
// 创建 ProductSpuDO 的映射
Map<Integer, ProductSkuDetailBO.Spu> spuMap = spus.stream().collect(
Collectors.toMap(ProductSpuDO::getId, spu -> ProductSpuConvert.this.convert3(spu).setPicUrls(StringUtil.split(spu.getPicUrls(), ","))));
// 拼装结果
List<ProductSkuDetailBO> spuDetailList = new ArrayList<>(skus.size());
for (ProductSkuDO sku : skus) {
// 创建 ProductSkuDetailBO 对象
ProductSkuDetailBO skuDetail = ProductSpuConvert.this.convert3(sku)
.setAttrs(new ArrayList<>())
.setSpu(spuMap.get(sku.getSpuId()));
spuDetailList.add(skuDetail);
// 设置 ProductSpuDetailBO 的 attrs 规格属性
List<String> attrs = StringUtil.split(sku.getAttrs(), ",");
attrs.forEach(attr -> skuDetail.getAttrs().add(productAttrDetailBOMap.get(Integer.valueOf(attr))));
}
// 返回
return spuDetailList;
}
}

View File

@@ -0,0 +1,65 @@
package cn.iocoder.mall.product.biz.convert.product;
import cn.iocoder.mall.product.biz.bo.product.UserProductSpuCollectionsBO;
import cn.iocoder.mall.product.biz.dataobject.product.UserProductSpuCollectionsDO;
import cn.iocoder.mall.product.biz.dto.product.UserProductSpuCollectionsAddDTO;
import cn.iocoder.mall.product.biz.dto.product.UserProductSpuCollectionsUpdateDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 用户_商品_收藏记录表
*
* @author xiaofeng
* @date 2019-07-01 20:23:30
*/
@Mapper
public interface UserProductSpuCollectionsConvert {
UserProductSpuCollectionsConvert INSTANCE = Mappers.getMapper(UserProductSpuCollectionsConvert.class);
/**
* DTO convert DO
* @param userSkuCollectionsAddDTO
* @return
*/
@Mappings({})
UserProductSpuCollectionsDO convert(UserProductSpuCollectionsAddDTO userSkuCollectionsAddDTO);
/**
* update DTO convert DO
* @param userProductSpuCollectionsUpdateDTO
* @return
*/
@Mappings({})
UserProductSpuCollectionsDO convert(UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO);
/**
* DO Convert BO
* @param userSkuCollectionsDO
* @return
*/
@Mappings({})
UserProductSpuCollectionsBO convert(UserProductSpuCollectionsDO userSkuCollectionsDO);
/**
* DO List convert BO LIST
* @param userSkuCollectionsDOS
* @return
*/
@Mappings({})
List<UserProductSpuCollectionsBO> convert(List<UserProductSpuCollectionsDO> userSkuCollectionsDOS);
// /**
// * 消处数据转换
// * @param productSpuCollectionMessage
// * @return
// */
// @Mappings({})
// UserProductSpuCollectionsAddDTO convert(ProductSpuCollectionMessage productSpuCollectionMessage);
}

View File

@@ -0,0 +1,5 @@
/**
* author: sin
* time: 2020/5/3 8:28 下午
*/
package cn.iocoder.mall.product.biz.dao;

View File

@@ -0,0 +1,10 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductAttrMapper extends BaseMapper<ProductAttrDO> {
}

View File

@@ -0,0 +1,11 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrValueDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductAttrValueMapper extends BaseMapper<ProductAttrValueDO> {
}

View File

@@ -0,0 +1,11 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.ProductBrandDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductBrandMapper extends BaseMapper<ProductBrandDO> {
}

View File

@@ -0,0 +1,10 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.ProductBrandDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductCategoryMapper extends BaseMapper<ProductBrandDO> {
}

View File

@@ -0,0 +1,10 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.ProductBrandDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductSkuMapper extends BaseMapper<ProductBrandDO> {
}

View File

@@ -0,0 +1,11 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.ProductBrandDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductSpuMapper extends BaseMapper<ProductBrandDO> {
}

View File

@@ -0,0 +1,54 @@
package cn.iocoder.mall.product.biz.dao.product;
import cn.iocoder.mall.product.biz.dataobject.product.UserProductSpuCollectionsDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 用户_商品_收藏记录表
*
* @author xiaofeng
* @date 2019-07-01 20:23:30
*/
@Repository
public interface UserProductSpuCollectionsMapper extends BaseMapper<UserProductSpuCollectionsDO> {
/**
* 根据用户id 和 spuId 查找用户商品收藏
*
* @param userId
* @param spuId
* @return
*/
default UserProductSpuCollectionsDO getUserSpuCollectionsByUserIdAndSpuId(final Integer userId,
final Integer spuId) {
QueryWrapper<UserProductSpuCollectionsDO> query = new QueryWrapper<UserProductSpuCollectionsDO>()
.eq("user_id", userId).eq("spu_id", spuId);
return selectOne(query);
}
/**
* 查询用户收藏列表
*
* @param userId
* @param offset
* @param limit
* @return
*/
List<UserProductSpuCollectionsDO> selectListByUser(@Param("userId") Integer userId, @Param("offset") Integer offset,
@Param("limit") Integer limit);
/**
* 根据用户ID 查找总数
*
* @param userId
* @return
*/
Integer selectCountByUser(Integer userId);
}

View File

@@ -0,0 +1,5 @@
/**
* author: sin
* time: 2020/5/3 8:27 下午
*/
package cn.iocoder.mall.product.biz.dataobject;

View File

@@ -0,0 +1,30 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import cn.iocoder.mall.mybatis.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Product 规格
*/
@Data
@Accessors(chain = true)
public class ProductAttrDO extends DeletableDO {
/**
* 规格编号
*/
private Integer id;
/**
* 名称
*/
private String name;
/**
* 状态
*
* 1-开启
* 2-禁用
*/
private Integer status;
}

View File

@@ -0,0 +1,34 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import cn.iocoder.mall.mybatis.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Product 规格值
*/
@Data
@Accessors(chain = true)
public class ProductAttrValueDO extends DeletableDO {
/**
* 规格值编号
*/
private Integer id;
/**
* 规格编号
*/
private Integer attrId;
/**
* 规格值
*/
private String name;
/**
* 状态
*
* 1-正常
* 2-禁用
*/
private Integer status;
}

View File

@@ -0,0 +1,41 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import cn.iocoder.mall.mybatis.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Product 品牌
*/
@Data
@Accessors(chain = true)
public class ProductBrandDO extends DeletableDO {
/**
* 规格编号
*/
private Integer id;
/**
* 名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 图片地址
*/
private String picUrl;
/**
* 状态
*
* 1-开启
* 2-禁用
*/
private Integer status;
}

View File

@@ -0,0 +1,48 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import cn.iocoder.mall.mybatis.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 商品分类
*/
@Data
@Accessors(chain = true)
public class ProductCategoryDO extends DeletableDO {
/**
* 分类编号
*/
private Integer id;
/**
* 父分类编号
*
* 如果不存在父级,则 pid = 0 。
*/
private Integer pid;
/**
* 名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 分类图片
*/
private String picUrl;
/**
* 排序值
*/
private Integer sort;
/**
* 状态
*
* 1-开启
* 2-关闭
*/
private Integer status;
}

View File

@@ -0,0 +1,61 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import cn.iocoder.mall.mybatis.dataobject.DeletableDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品 SKU
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductSkuDO extends DeletableDO {
/**
* sku 编号
*/
private Integer id;
/**
* 商品编号
*/
private Integer spuId;
// TODO 店铺编号
/**
* 状态
*
* 1-正常
* 2-禁用
*/
private Integer status;
/**
* 图片地址
*/
private String picUrl;
/**
* 规格值({@link ProductAttrDO})数组
*
* 数组,以逗号分隔
*/
private String attrs;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
// /**
// * 商品在付款减库存的状态下该Sku上未付款的订单数量
// */
// private Integer withHoldQuantity;
// /**
// * 销量
// */
// private Integer soldNum;
}

View File

@@ -0,0 +1,78 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import cn.iocoder.mall.mybatis.dataobject.DeletableDO;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 商品 SPU
*
* TODO 芋艿,后面增加商品普通参数。例如说,正面材料,背面材料,屏幕尺寸。
*/
@Data
@Accessors(chain = true)
public class ProductSpuDO extends DeletableDO {
/**
* SPU 编号
*/
private Integer id;
// TODO 店铺编号 先不考虑,因为第一个版本,不做 B2B2C
// ========== 基本信息 =========
/**
* SPU 名字
*/
private String name;
/**
* 卖点
*/
private String sellPoint;
/**
* 描述
*/
private String description;
/**
* 分类编号
*/
private Integer cid;
/**
* 商品主图地址
*
* 数组,以逗号分隔
*
* 建议尺寸800*800像素你可以拖拽图片调整顺序最多上传15张
*/
private String picUrls;
// TODO 运费信息
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
private Boolean visible;
/**
* 排序字段
*/
private Integer sort;
// ========== Sku 相关字段 =========
/**
* 价格
*
* 目前的计算方式是,以 Sku 最小价格为准
*/
private Integer price;
/**
* 库存数量
*
* 目前的计算方式是,以 Sku 库存累加为准
*/
private Integer quantity;
}

View File

@@ -0,0 +1,44 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* Product 库存
*/
@Deprecated // TODO 芋艿,咱暂时不加库存表和库存服务
@Data
@Accessors(chain = true)
public class ProductStockDO {
/**
* 编号,自增
*/
private Integer id;
/**
* SKU 编号
*/
private Integer skuId;
/**
* 库存数
*/
private Integer quantity;
/**
* 创建时间
*/
private Date createTime;
/**
* 最后更新时间
*/
private Date updateTime;
/**
* 状态
*
* 1-正常
* 2-删除
*/
private Integer status;
}

View File

@@ -0,0 +1,78 @@
package cn.iocoder.mall.product.biz.dataobject.product;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 用户_商品_收藏记录表
*
* @author xiaofeng
* @date 2019-07-01 20:23:30
*/
@TableName("user_spu_collections")
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsDO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id自增长
*/
private Integer id;
/**
* 用户id
*/
private Integer userId;
/**
* 用户名称
*/
private String nickname;
/**
* 商品id
*/
private Integer spuId;
/**
* 商品名字
*/
private String spuName;
/**
* 图片名字
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 删除状态
*/
private Integer deleted;
}

View File

@@ -0,0 +1,19 @@
package cn.iocoder.mall.product.biz.dto.attr;
import cn.iocoder.common.framework.vo.PageParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品规格模块 - 商品规格分页 DTO
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class AdminProductAttrPageDTO extends PageParam {
/**
* 商品规格名字
*/
private String name;
}

View File

@@ -0,0 +1,5 @@
/**
* author: sin
* time: 2020/5/3 8:29 下午
*/
package cn.iocoder.mall.product.biz.dto;

View File

@@ -0,0 +1,21 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
/**
* Product 规格添加 DTO
*/
@Data
@Accessors(chain = true)
public class ProductAttrAddDTO {
/**
* 名称
*/
@NotEmpty(message = "规格名不能为空")
private String name;
}

View File

@@ -0,0 +1,22 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 商品规格分页 DTO
*/
@Data
@Accessors(chain = true)
public class ProductAttrPageDTO {
private String name;
@NotNull(message = "页码不能为空")
private Integer pageNo;
@NotNull(message = "每页条数不能为空")
private Integer pageSize;
}

View File

@@ -0,0 +1,28 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* Product 规格修改 DTO
*/
@Data
@Accessors(chain = true)
public class ProductAttrUpdateDTO {
/**
* 规格编号
*/
@NotNull(message = "规格编号不能为空")
private Integer id;
/**
* 名称
*/
@NotEmpty(message = "规格名不能为空")
private String name;
}

View File

@@ -0,0 +1,27 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* Product 规格值添加 DTO
*/
@Data
@Accessors(chain = true)
public class ProductAttrValueAddDTO {
/**
* 规格编号
*/
@NotNull(message = "规格编号不能为空")
private Integer attrId;
/**
* 名称
*/
@NotEmpty(message = "规格值名不能为空")
private String name;
}

View File

@@ -0,0 +1,29 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* Product 规格值修改 DTO
*
* 注意,不允许修改所属规格
*/
@Data
@Accessors(chain = true)
public class ProductAttrValueUpdateDTO {
/**
* 规格值编号
*/
@NotNull(message = "规格编号不能为空")
private Integer id;
/**
* 名称
*/
@NotEmpty(message = "规格名不能为空")
private String name;
}

View File

@@ -0,0 +1,43 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* Product 品牌添加 DTO
*/
@Data
@Accessors(chain = true)
public class ProductBrandAddDTO {
/**
* 名称
*/
@NotEmpty(message = "品牌名不能为空")
private String name;
/**
* 描述
*/
@NotEmpty(message = "品牌描述不能为空")
private String description;
/**
* 图片地址
*/
@NotEmpty(message = "品牌图片地址不能为空")
private String picUrl;
/**
* 状态
*
* 1-开启
* 2-禁用
*/
@NotNull(message = "品牌状态不能为空")
private Integer status;
}

View File

@@ -0,0 +1,36 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 商品品牌分页 DTO
*/
@Data
@Accessors(chain = true)
public class ProductBrandPageDTO {
/**
* 名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 状态 1-开启 2-禁用
*/
private Integer status;
@NotNull(message = "页码不能为空")
private Integer pageNo;
@NotNull(message = "每页条数不能为空")
private Integer pageSize;
}

View File

@@ -0,0 +1,49 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* Product 品牌添加 DTO
*/
@Data
@Accessors(chain = true)
public class ProductBrandUpdateDTO {
/**
* 主键
*/
@NotNull(message = "品牌主键不能为空")
private Integer id;
/**
* 名称
*/
@NotEmpty(message = "品牌名不能为空")
private String name;
/**
* 描述
*/
@NotEmpty(message = "品牌描述不能为空")
private String description;
/**
* 图片地址
*/
@NotEmpty(message = "品牌图片地址不能为空")
private String picUrl;
/**
* 状态
*
* 1-开启
* 2-禁用
*/
@NotNull(message = "品牌状态不能为空")
private Integer status;
}

View File

@@ -0,0 +1,41 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 商品分类添加 DTO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryAddDTO {
/**
* 父分类编号
*/
@NotNull(message = "父分类编号不能为空")
private Integer pid;
/**
* 名称
*/
@NotNull(message = "名称不能为空")
private String name;
/**
* 描述
*/
@NotNull(message = "描述不能为空")
private String description;
/**
* 分类图片
*/
// @NotNull(message = "分类图片不能为空")
private String picUrl;
/**
* 排序值
*/
@NotNull(message = "排序值不能为空")
private Integer sort;
}

View File

@@ -0,0 +1,46 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 商品分类更新 DTO
*/
@Data
@Accessors(chain = true)
public class ProductCategoryUpdateDTO {
/**
* 编号
*/
@NotNull(message = "编号不能为空")
private Integer id;
/**
* 父分类编号
*/
@NotNull(message = "父分类编号不能为空")
private Integer pid;
/**
* 名称
*/
@NotNull(message = "名称不能为空")
private String name;
/**
* 描述
*/
@NotNull(message = "描述不能为空")
private String description;
/**
* 分类图片
*/
// @NotNull(message = "分类图片不能为空")
private String picUrl;
/**
* 排序值
*/
@NotNull(message = "排序值不能为空")
private Integer sort;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 Sku 添加 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSkuAddOrUpdateDTO {
/**
* 规格值数组
*/
@NotNull(message = "规格值数组不能为空")
private List<Integer> attrs;
/**
* 价格,单位:分
*/
@NotNull(message = "价格不能为空")
@Min(value = 1L, message = "最小价格为 1")
private Integer price;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空")
@Min(value = 1L, message = "最小库存为 1")
private Integer quantity;
}

View File

@@ -0,0 +1,62 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU + SKU 添加 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuAddDTO {
// ========== 基本信息 =========
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotNull(message = "商品主图不能为空")
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
@NotNull(message = "是否上架不能为空")
private Boolean visible;
// ========== SKU =========
/**
* SKU 数组
*/
@NotNull(message = "SKU 不能为空")
private List<ProductSkuAddOrUpdateDTO> skus;
}

View File

@@ -0,0 +1,41 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 商品 Spu 分页 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuPageDTO {
/**
* 商品名
*
* 模糊匹配
*/
private String name;
/**
* 分类编号
*/
private Integer cid;
/**
* 是否可见
*/
private Boolean visible;
/**
* 是否有库存
*
* 允许为空。空时,不进行筛选
*/
private Boolean hasQuantity;
@NotNull(message = "页码不能为空")
private Integer pageNo;
@NotNull(message = "每页条数不能为空")
private Integer pageSize;
}

View File

@@ -0,0 +1,20 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 商品 Spu 搜索列表 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuSearchListDTO {
/**
* 商品名
*
* 模糊匹配
*/
private String name;
}

View File

@@ -0,0 +1,68 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU + SKU 更新 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuUpdateDTO {
/**
* Spu 编号
*/
@NotNull(message = "SPU 编号不能为空")
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotNull(message = "商品主图不能为空")
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
@NotNull(message = "是否上架不能为空")
private Boolean visible;
// ========== SKU =========
/**
* SKU 数组
*/
@NotNull(message = "SKU 不能为空")
private List<ProductSkuAddOrUpdateDTO> skus;
}

View File

@@ -0,0 +1,75 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 添加商品收藏参数
* @author xiaofeng
* @date 2019/07/01 20:38
* @version 1.0
*/
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsAddDTO implements Serializable {
/**
* id自增长
*/
private Integer id;
/**
* 用户id
*/
private Integer userId;
/**
* 用户名称
*/
private String nickname;
/**
* 商品id
*/
private Integer spuId;
/**
* 商品名字
*/
private String spuName;
/**
* 图片名字
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 删除状态
*/
private Integer deleted;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 商品收藏分页参数
* @author xiaofeng
* @date 2019/07/06 18:40
* @version 1.0
*/
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsPageDTO implements Serializable {
/**
* 用户ID
*/
private Integer userId;
/**
* 当前页
*/
@NotNull(message = "页码不能为空")
private Integer pageNo;
/**
* 每页显示的条数
*/
@NotNull(message = "每页条数不能为空")
private Integer pageSize;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 更新商品收藏参数
* @author xiaofeng
* @date 2019/07/01 20:38
* @version 1.0
*/
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsUpdateDTO implements Serializable {
/**
* id自增长
*/
private Integer id;
/**
* 更新时间
*/
private Date updateTime;
/**
* 删除状态
*/
private Integer deleted;
}

View File

@@ -0,0 +1,27 @@
package cn.iocoder.mall.product.biz.message;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
/**
* Spring Cloud Stream Source 接口
*/
public interface MQStreamProducer {
/**
* 商品更新 Output
*/
String PRODUCT_UPDATE_OUTPUT = "product-update-output";
@Output(PRODUCT_UPDATE_OUTPUT)
MessageChannel productUpdateOutput();
// default boolean sendProductUpdateMessage(ProductUpdateMessage message) {
// // 创建 Spring Message 对象
// Message<ProductUpdateMessage> springMessage = MessageBuilder.withPayload(message)
// .build();
// // 发送消息
// return productUpdateOutput().send(springMessage);
// }
}

View File

@@ -0,0 +1,109 @@
package cn.iocoder.mall.product.biz.message;
import org.springframework.stereotype.Service;
/**
* 商品收藏 消费者
* @author xiaofeng
* @date 2019/07/02 19:57
* @version 1.0
*/
@Service
//@RocketMQMessageListener(topic = ProductSpuCollectionMessage.TOPIC, consumerGroup = "product-spu-consumer-group-"
// + ProductSpuCollectionMessage.TOPIC)
public class UserProductSpuCollectionsConsumer
// implements RocketMQListener<ProductSpuCollectionMessage>
{
// @Autowired
// private UserProductSpuCollectionsService userProductSpuCollectionsService;
//
// @Reference(validation = "true", version = "${dubbo.consumer.UserService.version}")
// private UserService userService;
//
// @Override
// public void onMessage(ProductSpuCollectionMessage productSpuCollectionMessage) {
// UserBO userBO = userService.getUser(productSpuCollectionMessage.getUserId());
// if (userBO == null) {
// throw ServiceExceptionUtil.exception(UserErrorCodeEnum.USER_NOT_EXISTS.getCode());
// }
// // 收藏
// if (productSpuCollectionMessage.getHasCollectionType().equals(1)) {
// this.saveUserProductSpuCollections(productSpuCollectionMessage, userBO.getNickname());
// } else if (productSpuCollectionMessage.getHasCollectionType().equals(2)) {
// // 取消收藏
// this.deleteUserProductSpuCollections(productSpuCollectionMessage.getUserId(),
// productSpuCollectionMessage.getSpuId());
// }
//
// }
//
// /**
// * 保存商品收藏
// * @param productSpuCollectionMessage
// * @param nickname
// * @return
// */
// private int saveUserProductSpuCollections(final ProductSpuCollectionMessage productSpuCollectionMessage,
// final String nickname) {
// int result = 0;
// UserProductSpuCollectionsBO userProductSpuCollectionsBO = this.userProductSpuCollectionsService
// .getUserSpuCollectionsByUserIdAndSpuId(productSpuCollectionMessage.getUserId(),
// productSpuCollectionMessage.getSpuId());
// if (userProductSpuCollectionsBO == null) {
// UserProductSpuCollectionsAddDTO userProductSpuCollectionsAddDTO = UserProductSpuCollectionsConvert.INSTANCE
// .convert(productSpuCollectionMessage);
// userProductSpuCollectionsAddDTO.setNickname(StringUtils.isEmpty(nickname) ? "" : nickname);
// userProductSpuCollectionsAddDTO.setCreateTime(new Date());
// userProductSpuCollectionsAddDTO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
// result = userProductSpuCollectionsService.addUserSkuCollections(userProductSpuCollectionsAddDTO);
// } else {
// // 存在重新收藏
// if (userProductSpuCollectionsBO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
// UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO = this
// .setUserProductSpuCollectionsUpdateDTO(userProductSpuCollectionsBO.getId(),
// DeletedStatusEnum.DELETED_NO);
// result = this.userProductSpuCollectionsService
// .updateUserProductSpuCollections(userProductSpuCollectionsUpdateDTO);
// }
// }
// return result;
// }
//
// /**
// * 取消收藏
// * @param userId
// * @param spuId
// * @return
// */
// private int deleteUserProductSpuCollections(final Integer userId, final Integer spuId) {
// UserProductSpuCollectionsBO userProductSpuCollectionsBO = this.userProductSpuCollectionsService
// .getUserSpuCollectionsByUserIdAndSpuId(userId, spuId);
// int result = 0;
// if (userProductSpuCollectionsBO != null) {
// // 未取消收藏的数据
// if (userProductSpuCollectionsBO.getDeleted().equals(DeletedStatusEnum.DELETED_NO.getValue())) {
// UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO = this
// .setUserProductSpuCollectionsUpdateDTO(userProductSpuCollectionsBO.getId(),
// DeletedStatusEnum.DELETED_YES);
// result = this.userProductSpuCollectionsService
// .updateUserProductSpuCollections(userProductSpuCollectionsUpdateDTO);
// }
// }
// return result;
// }
//
// /**
// * 设置更新值
// * @param id
// * @param deletedStatusEnum
// * @return
// */
// private UserProductSpuCollectionsUpdateDTO setUserProductSpuCollectionsUpdateDTO(final Integer id,
// final DeletedStatusEnum deletedStatusEnum) {
// return new UserProductSpuCollectionsUpdateDTO().setId(id).setUpdateTime(new Date())
// .setDeleted(deletedStatusEnum.getValue());
// }
}

View File

@@ -0,0 +1,5 @@
/**
* author: sin
* time: 2020/5/3 8:31 下午
*/
package cn.iocoder.mall.product.biz.service;

View File

@@ -0,0 +1,50 @@
package cn.iocoder.mall.product.biz.service.product;
import cn.iocoder.common.framework.constant.CommonStatusEnum;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrBO;
import cn.iocoder.mall.product.biz.bo.product.ProductAttrBO2;
import cn.iocoder.mall.product.biz.bo.product.ProductAttrSimpleBO;
import cn.iocoder.mall.product.biz.bo.product.ProductAttrValueBO;
import cn.iocoder.mall.product.biz.dto.attr.AdminProductAttrPageDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrUpdateDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrValueAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrValueUpdateDTO;
import java.util.List;
public interface ProductAttrService {
/**
* 获取规格分页数据
*
* @param productAttrPageDTO 查询参数
* @return 规格分页信息
*/
PageResult<ProductAttrBO> getProductAttrPage(AdminProductAttrPageDTO productAttrPageDTO);
/**
* 获得规格属性数组
* <p>
* 注意,该方法过滤了禁用的规格
*
* @return 规格属性数组
*/
List<ProductAttrSimpleBO> getProductAttrList();
ProductAttrBO2 addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO);
Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO);
Boolean updateProductAttrStatus(Integer adminId, Integer productAttrId,
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status);
ProductAttrValueBO addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO);
Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO);
Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId,
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status);
}

View File

@@ -0,0 +1,255 @@
package cn.iocoder.mall.product.biz.service.product.impl;
import cn.iocoder.common.framework.util.CollectionUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.mybatis.enums.DeletedStatusEnum;
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrBO;
import cn.iocoder.mall.product.biz.bo.product.ProductAttrAndValuePairBO;
import cn.iocoder.mall.product.biz.bo.product.ProductAttrBO2;
import cn.iocoder.mall.product.biz.bo.product.ProductAttrSimpleBO;
import cn.iocoder.mall.product.biz.bo.product.ProductAttrValueBO;
import cn.iocoder.mall.product.biz.convert.attr.ProductAttrConvert;
import cn.iocoder.mall.product.biz.convert.product.ProductAttrConvert2;
import cn.iocoder.mall.product.biz.dao.product.ProductAttrMapper;
import cn.iocoder.mall.product.biz.dao.product.ProductAttrValueMapper;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrDO;
import cn.iocoder.mall.product.biz.dataobject.product.ProductAttrValueDO;
import cn.iocoder.mall.product.biz.dto.attr.AdminProductAttrPageDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrUpdateDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrValueAddDTO;
import cn.iocoder.mall.product.biz.dto.product.ProductAttrValueUpdateDTO;
import cn.iocoder.mall.product.biz.enums.ProductErrorCodeEnum;
import cn.iocoder.mall.product.biz.enums.product.ProductAttrConstants;
import cn.iocoder.mall.product.biz.service.product.ProductAttrService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Multimaps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
/**
* 商品规格 Service 实现类
*
* @see cn.iocoder.mall.product.biz.dataobject.product.ProductAttrDO
* @see cn.iocoder.mall.product.biz.dataobject.product.ProductAttrValueDO
*/
@Service
public class ProductAttrServiceImpl implements ProductAttrService {
@Autowired
private ProductAttrMapper productAttrMapper;
@Autowired
private ProductAttrValueMapper productAttrValueMapper;
@Override
public PageResult<ProductAttrBO> getProductAttrPage(AdminProductAttrPageDTO productAttrPageDTO) {
//查询分页
Page<ProductAttrDO> page = new Page<>(productAttrPageDTO.getPageNo(), productAttrPageDTO.getPageSize());
LambdaQueryWrapper<ProductAttrDO> queryWrapper = Wrappers.<ProductAttrDO>query().lambda()
.like(StringUtils.isNotBlank(productAttrPageDTO.getName()), ProductAttrDO::getName, productAttrPageDTO.getName())
.eq(ProductAttrDO::getDeleted, false);
IPage<ProductAttrDO> attrPage = productAttrMapper.selectPage(page, queryWrapper);
PageResult<ProductAttrBO> productAttrPage = ProductAttrConvert.INSTANCE.convertPage(attrPage);
// 将规格值拼接上去
if (!CollectionUtil.isEmpty(productAttrPage.getList())) {
Set<Integer> attrIds = productAttrPage.getList().stream().map(ProductAttrBO::getId).collect(Collectors.toSet());
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectList(Wrappers.<ProductAttrValueDO>query().lambda()
.in(ProductAttrValueDO::getAttrId, attrIds)
.eq(ProductAttrValueDO::getDeleted, false));
Map<Integer, List<ProductAttrValueDO>> attrValueMap = attrValues.stream().collect(Collectors.groupingBy(ProductAttrValueDO::getAttrId));
for (ProductAttrBO productAttrBO : productAttrPage.getList()) {
productAttrBO.setValues(ProductAttrConvert.INSTANCE.convertAttrValue(attrValueMap.get(productAttrBO.getId())));
}
}
// 返回结果
return productAttrPage;
}
public List<ProductAttrAndValuePairBO> validProductAttrAndValue(Set<Integer> productAttrValueIds, boolean validStatus) {
// 首先,校验规格值
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectBatchIds(productAttrValueIds);
if (attrValues.size() != productAttrValueIds.size()) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
}
if (validStatus) {
// 同时,校验下状态
for (ProductAttrValueDO attrValue : attrValues) {
if (ProductAttrConstants.ATTR_STATUS_DISABLE.equals(attrValue.getStatus())) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
}
}
}
// 然后,校验规格
Set<Integer> attrIds = attrValues.stream().map(ProductAttrValueDO::getAttrId).collect(Collectors.toSet());
List<ProductAttrDO> attrs = productAttrMapper.selectBatchIds(attrIds);
if (attrs.size() != attrIds.size()) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
}
if (validStatus) {
// 同时,校验下状态
for (ProductAttrDO attr : attrs) {
if (ProductAttrConstants.ATTR_VALUE_STATUS_DISABLE.equals(attr.getStatus())) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
}
}
}
// 返回成功
// ProductAttrDO 的映射,方便查找。
Map<Integer, ProductAttrDO> attrMap = attrs.stream().collect(Collectors.toMap(ProductAttrDO::getId, productAttrDO -> productAttrDO));
return attrValues.stream().map(productAttrValueDO -> new ProductAttrAndValuePairBO()
.setAttrId(productAttrValueDO.getAttrId()).setAttrName(attrMap.get(productAttrValueDO.getAttrId()).getName())
.setAttrValueId(productAttrValueDO.getId()).setAttrValueName(productAttrValueDO.getName())).collect(Collectors.toList());
}
@Override
public List<ProductAttrSimpleBO> getProductAttrList() {
// 查询所有开启的规格数组
List<ProductAttrDO> attrDos = productAttrMapper.selectList(Wrappers.<ProductAttrDO>query().lambda()
.in(ProductAttrDO::getStatus, ProductAttrConstants.ATTR_STATUS_ENABLE)
.eq(ProductAttrDO::getDeleted, false));
List<ProductAttrSimpleBO> attrs = ProductAttrConvert2.INSTANCE.convert3(attrDos);
// 如果为空,则返回空
if (attrs.isEmpty()) {
return Collections.emptyList();
}
// 将规格值拼接上去
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectList(Wrappers.<ProductAttrValueDO>query().lambda()
.in(ProductAttrValueDO::getStatus, ProductAttrConstants.ATTR_STATUS_ENABLE)
.eq(ProductAttrValueDO::getDeleted, false));
// KEY 是 attrId VALUE 是 ProductAttrValueDO 数组
ImmutableListMultimap<Integer, ProductAttrValueDO> attrValueMap = Multimaps.index(attrValues, ProductAttrValueDO::getAttrId);
for (ProductAttrSimpleBO productAttrSimpleBO : attrs) {
productAttrSimpleBO.setValues(ProductAttrConvert2.INSTANCE.convert4(((attrValueMap).get(productAttrSimpleBO.getId()))));
}
return attrs;
}
@Override
public ProductAttrBO2 addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO) {
// 校验规格名不重复
int count = productAttrMapper.selectCount(Wrappers.<ProductAttrDO>query().lambda()
.eq(ProductAttrDO::getName, productAttrAddDTO.getName())
.eq(ProductAttrDO::getDeleted, false));
if (count > 0) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode());
}
// 插入到数据库
ProductAttrDO productAttrDO = ProductAttrConvert2.INSTANCE.convert(productAttrAddDTO)
.setStatus(ProductAttrConstants.ATTR_STATUS_ENABLE);
productAttrDO.setCreateTime(new Date());
productAttrDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
productAttrMapper.insert(productAttrDO);
// 返回成功
return ProductAttrConvert2.INSTANCE.convert(productAttrDO);
}
@Override
public Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO) {
// 校验存在
if (productAttrMapper.selectById(productAttrUpdateDTO.getId()) == null) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
}
// 校验规格名不重复
ProductAttrDO existsAttrDO = productAttrMapper.selectOne(Wrappers.<ProductAttrDO>query().lambda()
.eq(ProductAttrDO::getName, productAttrUpdateDTO.getName())
.eq(ProductAttrDO::getDeleted, false));
if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrUpdateDTO.getId())) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode());
}
// 更新到数据库
ProductAttrDO updateProductAttr = ProductAttrConvert2.INSTANCE.convert(productAttrUpdateDTO);
productAttrMapper.updateById(updateProductAttr);
// 返回成功
return true;
}
@Override
public Boolean updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status) {
// 校验存在
ProductAttrDO productAttrDO = productAttrMapper.selectById(productAttrId);
if (productAttrDO == null) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
}
// 校验状态
if (productAttrDO.getStatus().equals(status)) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_STATUS_EQUALS.getCode());
}
// 更新到数据库
ProductAttrDO updateProductAttr = new ProductAttrDO().setId(productAttrId).setStatus(status);
productAttrMapper.updateById(updateProductAttr);
// 返回成功
return true;
}
@Override
public ProductAttrValueBO addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO) {
// 校验规格名不重复
int count = productAttrValueMapper.selectCount(Wrappers.<ProductAttrValueDO>query().lambda()
.eq(ProductAttrValueDO::getName, productAttrValueAddDTO.getName())
.eq(ProductAttrValueDO::getAttrId, productAttrValueAddDTO.getAttrId())
.eq(ProductAttrValueDO::getDeleted, false));
if (count > 0) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode());
}
// 插入到数据库
ProductAttrValueDO productAttrValueDO = ProductAttrConvert2.INSTANCE.convert(productAttrValueAddDTO)
.setStatus(ProductAttrConstants.ATTR_VALUE_STATUS_ENABLE);
productAttrValueDO.setCreateTime(new Date());
productAttrValueDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
productAttrValueMapper.insert(productAttrValueDO);
// 返回成功
return ProductAttrConvert2.INSTANCE.convert2(productAttrValueDO);
}
@Override
public Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO) {
// 校验存在
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueUpdateDTO.getId());
if (productAttrValueDO == null) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
}
// 校验规格名不重复
ProductAttrValueDO existsAttrDO = productAttrValueMapper.selectOne(Wrappers.<ProductAttrValueDO>query().lambda()
.eq(ProductAttrValueDO::getName, productAttrValueDO.getName())
.eq(ProductAttrValueDO::getAttrId, productAttrValueDO.getAttrId())
.eq(ProductAttrValueDO::getDeleted, false));
if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrValueUpdateDTO.getId())) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode());
}
// 更新到数据库
ProductAttrValueDO updateProductValue = ProductAttrConvert2.INSTANCE.convert(productAttrValueUpdateDTO);
productAttrValueMapper.updateById(updateProductValue);
// 返回成功
return true;
}
@Override
public Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status) {
// 校验存在
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueId);
if (productAttrValueDO == null) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
}
// 校验状态
if (productAttrValueDO.getStatus().equals(status)) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_STATUS_EQUALS.getCode());
}
// 更新到数据库
ProductAttrValueDO updateProductAttrValue = new ProductAttrValueDO().setId(productAttrValueId).setStatus(status);
productAttrValueMapper.updateById(updateProductAttrValue);
// 返回成功
return true;
}
}

View File

@@ -0,0 +1,2 @@
##################### 业务模块 #####################

View File

@@ -0,0 +1,19 @@
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://s1.iocoder.cn:3306/mall_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 3WLiVUBEwTbvAfsh
# MyBatis Plus 配置项
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: cn.iocoder.mall.product.biz.dataobject

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.product.biz.dao.product.ProductSpuMapper">
</mapper>