完成的商品搜索和条件功能
This commit is contained in:
35
moved/product/pom.xml
Normal file
35
moved/product/pom.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?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>onemall</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product</artifactId>
|
||||
<name>product</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>product-rpc-api</module>
|
||||
<module>product-rpc</module>
|
||||
<module>product-rest</module>
|
||||
<module>product-biz</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-dependencies</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
94
moved/product/product-biz/pom.xml
Normal file
94
moved/product/product-biz/pom.xml
Normal file
@@ -0,0 +1,94 @@
|
||||
<?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>product</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product-biz</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-biz-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring 核心 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 短信平台 阿里云、云片 -->
|
||||
<dependency>
|
||||
<groupId>com.yunpian.sdk</groupId>
|
||||
<artifactId>yunpian-java-sdk</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>aliyun-java-sdk-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- MQ 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.mall.product.biz.bo.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 规格名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.mall.product.biz.bo.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 商品规格精简 VO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrSimpleBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 规格名
|
||||
*/
|
||||
private String name;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.iocoder.mall.product.biz.bo.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrSimpleWithValueBO extends ProductAttrSimpleBO {
|
||||
|
||||
/**
|
||||
* 规格值数组
|
||||
*/
|
||||
private List<ProductAttrValueSimpleBO> values;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.mall.product.biz.bo.attr;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.iocoder.mall.product.biz.bo.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrWithValueBO extends ProductAttrBO {
|
||||
|
||||
/**
|
||||
* 规格值数组
|
||||
*/
|
||||
private List<ProductAttrValueBO> values;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.mall.product.biz.bo.product;
|
||||
|
||||
import cn.iocoder.mall.product.biz.bo.brand.ProductBrandBO;
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package cn.iocoder.mall.product.biz.convert.attr;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.*;
|
||||
import cn.iocoder.mall.product.biz.dataobject.attr.ProductAttrDO;
|
||||
import cn.iocoder.mall.product.biz.dataobject.attr.ProductAttrValueDO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.ProductAttrUpdateDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.ProductAttrValueAddDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.ProductAttrValueUpdateDTO;
|
||||
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<ProductAttrWithValueBO> convertPage(IPage<ProductAttrDO> bean);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrBO convertAttr(ProductAttrDO values);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrValueBO convertAttrValue(ProductAttrValueDO productAttrValueDO);
|
||||
|
||||
@Mappings({})
|
||||
List<ProductAttrValueBO> convertAttrValues(List<ProductAttrValueDO> values);
|
||||
|
||||
@Mappings({})
|
||||
List<ProductAttrSimpleWithValueBO> convertAttrSimple(List<ProductAttrDO> attrs);
|
||||
|
||||
@Mappings({})
|
||||
List<ProductAttrValueSimpleBO> convertAttrValueSimple(List<ProductAttrValueDO> values);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrDO convertUpdate(ProductAttrUpdateDTO productAttrUpdateDTO);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrValueDO convertValueAdd(ProductAttrValueAddDTO productAttrValueAddDTO);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrValueDO convertValueUpdate(ProductAttrValueUpdateDTO productAttrValueUpdateDTO);
|
||||
}
|
||||
@@ -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.spu.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);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package cn.iocoder.mall.product.biz.convert.sku;
|
||||
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import cn.iocoder.mall.product.biz.bo.product.*;
|
||||
import cn.iocoder.mall.product.biz.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.mall.product.biz.dataobject.spu.ProductSkuDO;
|
||||
import cn.iocoder.mall.product.biz.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.mall.product.biz.dto.sku.ProductSkuAddOrUpdateDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.sku.ProductSpuAddDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.sku.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", ignore = true)
|
||||
})
|
||||
ProductSpuDO convertToSpuDO(ProductSpuAddDTO productSpuAddDTO);
|
||||
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "attrs", target = "attrs", ignore = true)
|
||||
})
|
||||
ProductSkuDO convertToSkuDO(ProductSkuAddOrUpdateDTO productSkuAddDTO);
|
||||
|
||||
@Mappings({
|
||||
@Mapping(source = "picUrls", target = "picUrls", qualifiedByName = "translatePicUrlsFromString")
|
||||
})
|
||||
ProductSpuBO convert(ProductSpuDO spu);
|
||||
|
||||
@Mappings({})
|
||||
List<ProductSpuBO> convert(List<ProductSpuDO> spus);
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Named("translatePicUrlsFromString")
|
||||
default List<String> translatePicUrlsFromString(String picUrls) {
|
||||
return StringUtil.split(picUrls, ",");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package cn.iocoder.mall.product.biz.dao.sku;
|
||||
|
||||
import cn.iocoder.mall.product.biz.dataobject.spu.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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package cn.iocoder.mall.product.biz.dataobject.spu;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.mall.product.biz.dataobject.stock;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.iocoder.mall.product.biz.service.attr;
|
||||
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrSimpleWithValueBO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProductAttrService {
|
||||
|
||||
/**
|
||||
* 获得规格属性数组
|
||||
* <p>
|
||||
* 注意,该方法过滤了禁用的规格
|
||||
*
|
||||
* @return 规格属性数组
|
||||
*/
|
||||
List<ProductAttrSimpleWithValueBO> getProductAttrList();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package cn.iocoder.mall.product.biz.service.attr;
|
||||
|
||||
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.core.enums.DeletedStatusEnum;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrSimpleWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.product.ProductAttrAndValuePairBO;
|
||||
import cn.iocoder.mall.product.biz.convert.attr.ProductAttrConvert;
|
||||
import cn.iocoder.mall.product.biz.dao.attr.ProductAttrMapper;
|
||||
import cn.iocoder.mall.product.biz.dao.attr.ProductAttrValueMapper;
|
||||
import cn.iocoder.mall.product.biz.dataobject.attr.ProductAttrDO;
|
||||
import cn.iocoder.mall.product.biz.dataobject.attr.ProductAttrValueDO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.*;
|
||||
import cn.iocoder.mall.product.biz.enums.ProductErrorCodeEnum;
|
||||
import cn.iocoder.mall.product.biz.enums.attr.ProductAttrConstants;
|
||||
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 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 ProductAttrDO
|
||||
* @see ProductAttrValueDO
|
||||
*/
|
||||
@Service
|
||||
public class ProductAttrServiceImpl implements ProductAttrService {
|
||||
|
||||
@Override
|
||||
public List<ProductAttrSimpleWithValueBO> getProductAttrList() {
|
||||
// 查询所有开启的规格数组
|
||||
List<ProductAttrDO> attrDos = productAttrMapper.selectList(Wrappers.<ProductAttrDO>query().lambda()
|
||||
.in(ProductAttrDO::getStatus, ProductAttrConstants.ATTR_STATUS_ENABLE)
|
||||
.eq(ProductAttrDO::getDeleted, false));
|
||||
// 如果为空,则返回空
|
||||
if (attrDos.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<ProductAttrSimpleWithValueBO> attrs = ProductAttrConvert.INSTANCE.convertAttrSimple(attrDos);
|
||||
// 将规格值拼接上去
|
||||
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectList(Wrappers.<ProductAttrValueDO>query().lambda()
|
||||
.in(ProductAttrValueDO::getStatus, ProductAttrConstants.ATTR_STATUS_ENABLE)
|
||||
.eq(ProductAttrValueDO::getDeleted, false));
|
||||
Map<Integer, List<ProductAttrValueDO>> attrValueMap = attrValues.stream().collect(Collectors.groupingBy(ProductAttrValueDO::getAttrId));
|
||||
for (ProductAttrSimpleWithValueBO item : attrs) {
|
||||
item.setValues(ProductAttrConvert.INSTANCE.convertAttrValueSimple(attrValueMap.get(item.getId())));
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package cn.iocoder.mall.product.biz.service.spu;
|
||||
|
||||
|
||||
import cn.iocoder.mall.product.biz.bo.product.ProductSpuDetailBO;
|
||||
|
||||
public interface ProductSpuService {
|
||||
/**
|
||||
* 获取SPU明细
|
||||
*
|
||||
* @param id spuId
|
||||
* @return SPU明细
|
||||
*/
|
||||
ProductSpuDetailBO getProductSpuDetail(Integer id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.mall.product.biz.service.spu;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum;
|
||||
import cn.iocoder.mall.product.biz.bo.product.ProductAttrAndValuePairBO;
|
||||
import cn.iocoder.mall.product.biz.bo.product.ProductSpuDetailBO;
|
||||
import cn.iocoder.mall.product.biz.convert.sku.ProductSpuConvert;
|
||||
import cn.iocoder.mall.product.biz.dao.category.ProductCategoryMapper;
|
||||
import cn.iocoder.mall.product.biz.dao.sku.ProductSkuMapper;
|
||||
import cn.iocoder.mall.product.biz.dao.sku.ProductSpuMapper;
|
||||
import cn.iocoder.mall.product.biz.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.mall.product.biz.dataobject.spu.ProductSkuDO;
|
||||
import cn.iocoder.mall.product.biz.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.mall.product.biz.dto.sku.ProductSkuAddOrUpdateDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.sku.ProductSpuAddDTO;
|
||||
import cn.iocoder.mall.product.biz.enums.ProductErrorCodeEnum;
|
||||
import cn.iocoder.mall.product.biz.enums.category.ProductCategoryNodeEnum;
|
||||
import cn.iocoder.mall.product.biz.enums.spu.ProductSpuConstants;
|
||||
import cn.iocoder.mall.product.biz.service.attr.ProductAttrService;
|
||||
import cn.iocoder.mall.product.biz.service.category.ProductCategoryService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
|
||||
@Autowired
|
||||
private ProductAttrService productAttrService;
|
||||
|
||||
@Override
|
||||
public ProductSpuDetailBO getProductSpuDetail(Integer spuId) {
|
||||
// 校验商品 spu 存在
|
||||
ProductSpuDO spu = productSpuMapper.selectById(spuId);
|
||||
if (spu == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 获得商品分类分类
|
||||
ProductCategoryDO category = productCategoryMapper.selectById(spu.getCid());
|
||||
Assert.notNull(category, String.format("分类编号(%d) 对应", spu.getCid()));
|
||||
// 获得商品 sku 数组
|
||||
List<ProductSkuDO> skus = productSkuMapper.selectListBySpuIdAndStatus(spuId, ProductSpuConstants.SKU_STATUS_ENABLE);
|
||||
// 获得规格
|
||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
||||
// 读取规格时,不考虑规格是否被禁用
|
||||
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds, false);
|
||||
// 返回成功
|
||||
return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category);
|
||||
}
|
||||
|
||||
}
|
||||
41
moved/product/product-rest/pom.xml
Normal file
41
moved/product/product-rest/pom.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?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>product</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product-rest</artifactId>
|
||||
<description>提供 system 服务的 Rest 接口的实现,提供对外调用</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-biz</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-web</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-security</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-swagger</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,54 @@
|
||||
package cn.iocoder.mall.product.rest.controller.attr;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrSimpleWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.*;
|
||||
import cn.iocoder.mall.product.biz.service.attr.ProductAttrService;
|
||||
import cn.iocoder.mall.product.rest.convert.attr.ProductAttrConvert;
|
||||
import cn.iocoder.mall.product.rest.request.attr.ProductAttrPageRequest;
|
||||
import cn.iocoder.mall.product.rest.request.attr.ProductAttrAddRequest;
|
||||
import cn.iocoder.mall.product.rest.request.attr.ProductAttrUpdateRequest;
|
||||
import cn.iocoder.mall.product.rest.request.attr.ProductAttrValueAddRequest;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProductAttrPageResponse;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProductAttrSimpleResponse;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProdutAttrResponse;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProductAttrValueResponse;
|
||||
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品规格
|
||||
*
|
||||
* @author lanmao
|
||||
* @version 1.0
|
||||
* @date 2020/05/06 16:36
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("admins")
|
||||
@Api("商品规格")
|
||||
public class AdminsProductAttrController {
|
||||
|
||||
@Autowired
|
||||
private ProductAttrService productAttrService;
|
||||
|
||||
@GetMapping("/attr/tree")
|
||||
@ApiOperation(value = "获得规格树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。")
|
||||
public CommonResult<List<AdminsProductAttrSimpleResponse>> tree() {
|
||||
// 查询全列表
|
||||
List<ProductAttrSimpleWithValueBO> result = productAttrService.getProductAttrList();
|
||||
return CommonResult.success(ProductAttrConvert.INSTANCE.convertSimple(result));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.mall.product.rest.controller.favorite;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* 用户收藏
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/07 11:06
|
||||
* @version 1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("users/favorite")
|
||||
@Api("用户收藏")
|
||||
// TODO FROM 芋艿 to ilnhj:controller 分包的话,还是按照模块。然后通过 Admins 和 Users 前缀,区分不同的 Controlller
|
||||
public class UserFavoriteController {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.mall.product.rest.convert.attr;
|
||||
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrSimpleWithValueBO;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProductAttrSimpleResponse;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ProductAttrConvert {
|
||||
|
||||
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
List<AdminsProductAttrSimpleResponse> convertSimple(List<ProductAttrSimpleWithValueBO> simpleList);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.mall.product.rest.request.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@ApiModel("商品 - 规格模块 - 商品规格添加 Request")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrAddRequest {
|
||||
|
||||
@ApiModelProperty(name = "name", value = "规格名", required = true, example = "颜色")
|
||||
@NotEmpty(message = "规格名不能为空")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.mall.product.rest.request.attr;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageParam;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel("商品 - 规格模块 - 商品规格 Request")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrPageRequest extends PageParam {
|
||||
|
||||
@ApiModelProperty(value = "商品规格名字,模糊匹配", example = "材料")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package cn.iocoder.mall.product.rest.request.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("商品 - 规格模块 - 商品规格修改 Request")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrUpdateRequest {
|
||||
|
||||
@ApiModelProperty(name = "id", value = "规格编号", required = true, example = "1")
|
||||
@NotNull(message = "规格编号不能为空")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty(name = "name", value = "规格名", required = true, example = "颜色")
|
||||
@NotEmpty(message = "规格名不能为空")
|
||||
private String name;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.mall.product.rest.request.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@ApiModel("商品 - 规格模块 - 商品规格值添加 Request")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrValueAddRequest {
|
||||
|
||||
@ApiModelProperty(name = "attrId", value = "规格编号", required = true, example = "1")
|
||||
@NotNull(message = "规格编号不能为空")
|
||||
private Integer attrId;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@ApiModelProperty(name = "name", value = "规格值名", required = true, example = "红色")
|
||||
@NotEmpty(message = "规格值名不能为空")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.mall.product.rest.request.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* Product 规格值修改 DTO
|
||||
* <p>
|
||||
* 注意,不允许修改所属规格
|
||||
*/
|
||||
@ApiModel("商品 - 规格模块 - 商品规格值修改 Request")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrValueUpdateRequest {
|
||||
|
||||
@ApiModelProperty(name = "id", value = "规格值编号", required = true, example = "1")
|
||||
@NotNull(message = "规格值编号不能为空")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty(name = "id", value = "规格值编号", required = true, example = "1")
|
||||
@NotEmpty(message = "规格名不能为空")
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package cn.iocoder.mall.product.rest.response.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel("商品管理 - 商品规格模块 - 商品规格分页信息 Response")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminsProductAttrPageResponse {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 规格名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 规格值数组
|
||||
*/
|
||||
private List<ProductAttrValue> values;
|
||||
|
||||
@ApiModel("规格值")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class ProductAttrValue {
|
||||
|
||||
/**
|
||||
* 规格值编号
|
||||
*/
|
||||
@ApiModelProperty(value = "规格值编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
/**
|
||||
* 规格值名
|
||||
*/
|
||||
@ApiModelProperty(value = "规格值名", required = true, example = "小")
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1")
|
||||
private Integer status;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
|
||||
private Date createTime;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package cn.iocoder.mall.product.rest.response.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(value = "商品规格精简 VO", description = "带有规格值数组")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminsProductAttrSimpleResponse {
|
||||
|
||||
@ApiModelProperty(value = "规格编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "规格名", required = true, example = "颜色")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "规格值数组", required = true)
|
||||
private List<ProductAttrValue> values;
|
||||
|
||||
@ApiModel("规格值")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class ProductAttrValue {
|
||||
|
||||
/**
|
||||
* 规格值编号
|
||||
*/
|
||||
@ApiModelProperty(value = "规格值编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
/**
|
||||
* 规格值名
|
||||
*/
|
||||
@ApiModelProperty(value = "规格值名", required = true, example = "小")
|
||||
private String name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.mall.product.rest.response.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel(value = "商品规格值 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminsProductAttrValueResponse {
|
||||
|
||||
@ApiModelProperty(value = "规格值编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "规格编号", required = true, example = "1")
|
||||
private Integer attrId;
|
||||
@ApiModelProperty(value = "规格名", required = true, example = "颜色")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1")
|
||||
private Integer status;
|
||||
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.mall.product.rest.response.attr;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@ApiModel(value = "商品规格 VO", description = "不带有规格值数组")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminsProdutAttrResponse {
|
||||
|
||||
@ApiModelProperty(value = "规格编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
@ApiModelProperty(value = "规格名", required = true, example = "颜色")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "状态", required = true, example = "1")
|
||||
private Integer status;
|
||||
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳")
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
34
moved/product/product-rpc-api/pom.xml
Normal file
34
moved/product/product-rpc-api/pom.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?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>product</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product-rpc-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-biz-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,12 @@
|
||||
package cn.iocoder.mall.product.rpc.api;
|
||||
|
||||
import cn.iocoder.mall.product.rpc.response.ProductSpuDetailResponse;
|
||||
|
||||
/**
|
||||
* @author Rai
|
||||
*/
|
||||
public interface ProductSpuRpc {
|
||||
|
||||
ProductSpuDetailResponse getProductSpuDetail(Integer spuId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package cn.iocoder.mall.product.rpc.response;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 Spu 明细 BO(包括 Sku 明细)
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuDetailResponse implements Serializable {
|
||||
|
||||
/**
|
||||
* SPU 编号
|
||||
*/
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 分类名
|
||||
*/
|
||||
private String categoryName;
|
||||
/**
|
||||
* 商品主图地址
|
||||
* <p>
|
||||
* 数组,以逗号分隔
|
||||
* <p>
|
||||
* 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张
|
||||
*/
|
||||
private List<String> picUrls;
|
||||
|
||||
// ========== 其他信息 =========
|
||||
/**
|
||||
* 是否上架商品(是否可见)。
|
||||
* <p>
|
||||
* 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<ProductAttrAndValuePair> attrs;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public static class ProductAttrAndValuePair implements Serializable {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
private Integer attrId;
|
||||
/**
|
||||
* 规格名
|
||||
*/
|
||||
private String attrName;
|
||||
/**
|
||||
* 规格值
|
||||
*/
|
||||
private Integer attrValueId;
|
||||
/**
|
||||
* 规格值名
|
||||
*/
|
||||
private String attrValueName;
|
||||
|
||||
}
|
||||
}
|
||||
40
moved/product/product-rpc/pom.xml
Normal file
40
moved/product/product-rpc/pom.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?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>product</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product-rpc</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-rpc-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-biz</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,16 @@
|
||||
package cn.iocoder.mall.product.rpc.convert;
|
||||
|
||||
import cn.iocoder.mall.product.biz.bo.product.ProductSpuDetailBO;
|
||||
import cn.iocoder.mall.product.rpc.response.ProductSpuDetailResponse;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface ProductSpuConvert {
|
||||
|
||||
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
ProductSpuDetailResponse convertDetail(ProductSpuDetailBO productSpuDetail);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.mall.product.rpc.rpc;
|
||||
|
||||
import cn.iocoder.mall.product.biz.bo.product.ProductSpuDetailBO;
|
||||
import cn.iocoder.mall.product.biz.service.spu.ProductSpuService;
|
||||
import cn.iocoder.mall.product.rpc.api.ProductSpuRpc;
|
||||
import cn.iocoder.mall.product.rpc.convert.ProductSpuConvert;
|
||||
import cn.iocoder.mall.product.rpc.response.ProductSpuDetailResponse;
|
||||
import org.apache.dubbo.config.annotation.Service;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
@Service(validation = "true", version = "${dubbo.provider.ProductSpuService.version}")
|
||||
public class ProductSpuRpcImpl implements ProductSpuRpc {
|
||||
|
||||
@Autowired
|
||||
private ProductSpuService productSpuService;
|
||||
|
||||
@Override
|
||||
public ProductSpuDetailResponse getProductSpuDetail(Integer spuId) {
|
||||
ProductSpuDetailBO productSpuDetail = productSpuService.getProductSpuDetail(spuId);
|
||||
return ProductSpuConvert.INSTANCE.convertDetail(productSpuDetail);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
38
moved/product/product-service-api/pom.xml
Normal file
38
moved/product/product-service-api/pom.xml
Normal file
@@ -0,0 +1,38 @@
|
||||
<?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>product</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product-service-api</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>common-framework</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.mall.product.api;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrValueBO;
|
||||
import cn.iocoder.mall.product.api.dto.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProductAttrService {
|
||||
|
||||
ProductAttrPageBO getProductAttrPage(ProductAttrPageDTO productAttrPageDTO);
|
||||
|
||||
/**
|
||||
* 获得规格属性数组
|
||||
*
|
||||
* 注意,该方法过滤了禁用的规格
|
||||
*
|
||||
* @return 规格属性数组
|
||||
*/
|
||||
List<ProductAttrSimpleBO> getProductAttrList();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package cn.iocoder.mall.product.api;
|
||||
|
||||
/**
|
||||
* 商品收藏
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/01 23:13
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface ProductSpuCollectionService {
|
||||
|
||||
/**
|
||||
* 商品收藏
|
||||
* @param spuId
|
||||
* @param hasCollectionType 1 商品收藏 2 取消收藏
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
boolean productSpuCollection(Integer spuId,Integer hasCollectionType,Integer userId);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.mall.product.api;
|
||||
|
||||
import cn.iocoder.mall.product.api.bo.*;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSpuSearchListDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface ProductSpuService {
|
||||
|
||||
ProductSpuDetailBO getProductSpuDetail(Integer id);
|
||||
|
||||
/**
|
||||
* 增量获得商品列表,按照 lastId 递增获得
|
||||
*
|
||||
* @param lastId 最后查询的编号
|
||||
* @param limit 大小
|
||||
* @return 商品列表
|
||||
*/
|
||||
List<ProductSpuDetailBO> getProductSpuDetailListForSync(Integer lastId, Integer limit);
|
||||
|
||||
List<ProductSpuBO> getProductSpuSearchList(ProductSpuSearchListDTO productSpuSearchListDTO);
|
||||
|
||||
List<ProductSpuBO> getProductSpuList(Collection<Integer> ids);
|
||||
|
||||
ProductSkuBO getProductSku(Integer id);
|
||||
|
||||
List<ProductSkuDetailBO> getProductSkuDetailList(Collection<Integer> ids);
|
||||
|
||||
Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package cn.iocoder.mall.product.api;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.product.api.bo.UserProductSpuCollectionsBO;
|
||||
import cn.iocoder.mall.product.api.bo.UserProductSpuCollectionsPageBO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsPageDTO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsUpdateDTO;
|
||||
|
||||
/**
|
||||
* UserProductSpuCollectionsService
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/01 20:27
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface UserProductSpuCollectionsService {
|
||||
|
||||
/**
|
||||
* 添加商品收藏
|
||||
* @return
|
||||
*/
|
||||
int addUserSkuCollections(UserProductSpuCollectionsAddDTO userProductSpuCollectionsAddDTO);
|
||||
|
||||
/**
|
||||
* 获取用户商品收藏
|
||||
* @param userId 用户ID
|
||||
* @param spuId 商品ID
|
||||
* @return
|
||||
*/
|
||||
UserProductSpuCollectionsBO getUserSpuCollectionsByUserIdAndSpuId(Integer userId, Integer spuId);
|
||||
|
||||
/**
|
||||
* 取消商品收藏
|
||||
* @param userProductSpuCollectionsUpdateDTO
|
||||
* @return
|
||||
*/
|
||||
int updateUserProductSpuCollections(UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO);
|
||||
|
||||
/**
|
||||
* 获取用户收藏列表数据
|
||||
* @param userProductSpuCollectionsPageDTO
|
||||
* @return
|
||||
*/
|
||||
CommonResult<UserProductSpuCollectionsPageBO> getUserProductSpuCollectionsPage(
|
||||
UserProductSpuCollectionsPageDTO userProductSpuCollectionsPageDTO);
|
||||
|
||||
/**
|
||||
* 删除收藏数据
|
||||
* @param userId
|
||||
* @param spuId
|
||||
* @return
|
||||
*/
|
||||
CommonResult<Boolean> deleteUserProductSpuCollections(Integer userId, Integer spuId);
|
||||
|
||||
|
||||
/**
|
||||
* 检验用户商品是否收藏
|
||||
* @param spuId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
CommonResult<Boolean> hasUserSpuFavorite(Integer spuId, Integer userId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品规格 VO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 规格名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package cn.iocoder.mall.product.api.bo;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.mall.product.api.dto;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.mall.product.api.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 商品 Spu 搜索列表 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuSearchListDTO {
|
||||
|
||||
/**
|
||||
* 商品名
|
||||
*
|
||||
* 模糊匹配
|
||||
*/
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package cn.iocoder.mall.product.api.dto;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.mall.product.api.dto;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.mall.product.api.dto;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.iocoder.mall.product.api.message;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 商品收藏或取消收藏时发送消息
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/01 22:33
|
||||
* @version 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSpuCollectionMessage {
|
||||
|
||||
public static final String TOPIC = "ProductSpuCollection";
|
||||
|
||||
/**
|
||||
* SPU 编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private Integer userId;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
private String spuName;
|
||||
|
||||
|
||||
/**
|
||||
* 商品图片
|
||||
*/
|
||||
private String spuImage;
|
||||
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
private String sellPoint;
|
||||
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
|
||||
/**
|
||||
* 1 收藏 2 取消
|
||||
*/
|
||||
private Integer hasCollectionType;
|
||||
|
||||
|
||||
}
|
||||
106
moved/product/product-service-impl/pom.xml
Normal file
106
moved/product/product-service-impl/pom.xml
Normal file
@@ -0,0 +1,106 @@
|
||||
<?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>product</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product-service-impl</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>user-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- RPC 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Transaction 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-seata</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- MQ 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rocketmq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>user-biz</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- 提供给 mapstruct 使用 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,58 @@
|
||||
package cn.iocoder.mall.product.convert;
|
||||
|
||||
import cn.iocoder.mall.product.api.bo.*;
|
||||
import cn.iocoder.mall.product.api.dto.ProductAttrAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductAttrUpdateDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductAttrValueAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductAttrValueUpdateDTO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductAttrDO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductAttrValueDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ProductAttrConvert {
|
||||
|
||||
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.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({})
|
||||
ProductAttrBO convert(ProductAttrDO productAttrDO);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrValueBO convert2(ProductAttrValueDO productAttrValueDO);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package cn.iocoder.mall.product.convert;
|
||||
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import cn.iocoder.mall.product.api.bo.*;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductCategoryDO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductSkuDO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductSpuDO;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package cn.iocoder.mall.product.convert;
|
||||
|
||||
import cn.iocoder.mall.product.api.bo.UserProductSpuCollectionsBO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsUpdateDTO;
|
||||
import cn.iocoder.mall.product.api.message.ProductSpuCollectionMessage;
|
||||
import cn.iocoder.mall.product.dataobject.UserProductSpuCollectionsDO;
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package cn.iocoder.mall.product.dao;
|
||||
|
||||
import cn.iocoder.mall.product.dataobject.ProductAttrDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ProductAttrMapper {
|
||||
|
||||
ProductAttrDO selectById(@Param("id") Integer id);
|
||||
|
||||
ProductAttrDO selectByName(@Param("name") String name);
|
||||
|
||||
List<ProductAttrDO> selectListByIds(@Param("ids") Collection<Integer> ids);
|
||||
|
||||
List<ProductAttrDO> selectListByStatus(@Param("status") Integer status);
|
||||
|
||||
List<ProductAttrDO> selectListByNameLike(@Param("name") String name,
|
||||
@Param("offset") Integer offset,
|
||||
@Param("limit") Integer limit);
|
||||
|
||||
Integer selectCountByNameLike(@Param("name") String name);
|
||||
|
||||
void insert(ProductAttrDO productAttrDO);
|
||||
|
||||
void update(ProductAttrDO productAttrDO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package cn.iocoder.mall.product.dao;
|
||||
|
||||
import cn.iocoder.mall.product.dataobject.ProductAttrValueDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ProductAttrValueMapper {
|
||||
|
||||
ProductAttrValueDO selectById(@Param("id") Integer id);
|
||||
|
||||
List<ProductAttrValueDO> selectListByIds(@Param("ids") Collection<Integer> ids);
|
||||
|
||||
List<ProductAttrValueDO> selectListByStatus(@Param("status") Integer status);
|
||||
|
||||
List<ProductAttrValueDO> selectListByAttrIds(@Param("attrIds") Collection<Integer> attrIds);
|
||||
|
||||
ProductAttrValueDO selectByAttrIdAndName(@Param("attrId") Integer attrId,
|
||||
@Param("name") String name);
|
||||
|
||||
|
||||
void insert(ProductAttrValueDO productAttrValueDO);
|
||||
|
||||
void update(ProductAttrValueDO productAttrValueDO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package cn.iocoder.mall.product.dao;
|
||||
|
||||
import cn.iocoder.mall.product.dataobject.ProductSkuDO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ProductSkuMapper {
|
||||
|
||||
ProductSkuDO selectById(Integer id);
|
||||
|
||||
List<ProductSkuDO> selectByIds(@Param("ids") Collection<Integer> ids);
|
||||
|
||||
List<ProductSkuDO> selectListBySpuIdAndStatus(@Param("spuId") Integer spuId,
|
||||
@Param("status") Integer status);
|
||||
|
||||
void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
|
||||
|
||||
int update(ProductSkuDO productSkuDO);
|
||||
|
||||
int updateToDeleted(@Param("ids") List<Integer> ids);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package cn.iocoder.mall.product.dao;
|
||||
|
||||
import cn.iocoder.mall.product.dataobject.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);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.mall.product.dataobject;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package cn.iocoder.mall.product.dataobject;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package cn.iocoder.mall.product.message;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum;
|
||||
import cn.iocoder.mall.product.api.UserProductSpuCollectionsService;
|
||||
import cn.iocoder.mall.product.api.bo.UserProductSpuCollectionsBO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsUpdateDTO;
|
||||
import cn.iocoder.mall.product.api.message.ProductSpuCollectionMessage;
|
||||
import cn.iocoder.mall.product.convert.UserProductSpuCollectionsConvert;
|
||||
import cn.iocoder.mall.user.api.UserService;
|
||||
import cn.iocoder.mall.user.api.bo.UserBO;
|
||||
import cn.iocoder.mall.user.biz.enums.UserErrorCodeEnum;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品收藏 消费者
|
||||
* @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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.iocoder.mall.product.service;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum;
|
||||
import cn.iocoder.mall.product.api.ProductAttrService;
|
||||
import cn.iocoder.mall.product.api.bo.*;
|
||||
import cn.iocoder.mall.product.api.constant.ProductAttrConstants;
|
||||
import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
|
||||
import cn.iocoder.mall.product.api.dto.*;
|
||||
import cn.iocoder.mall.product.convert.ProductAttrConvert;
|
||||
import cn.iocoder.mall.product.dao.ProductAttrMapper;
|
||||
import cn.iocoder.mall.product.dao.ProductAttrValueMapper;
|
||||
import cn.iocoder.mall.product.dataobject.ProductAttrDO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductAttrValueDO;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
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.dataobject.ProductAttrDO
|
||||
* @see cn.iocoder.mall.product.dataobject.ProductAttrValueDO
|
||||
*/
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.ProductAttrService.version}")
|
||||
public class ProductAttrServiceImpl implements ProductAttrService {
|
||||
|
||||
@Autowired
|
||||
private ProductAttrMapper productAttrMapper;
|
||||
@Autowired
|
||||
private ProductAttrValueMapper productAttrValueMapper;
|
||||
|
||||
@Override
|
||||
public List<ProductAttrSimpleBO> getProductAttrList() {
|
||||
// 查询所有开启的规格数组
|
||||
List<ProductAttrSimpleBO> attrs = ProductAttrConvert.INSTANCE.convert3(productAttrMapper.selectListByStatus(ProductAttrConstants.ATTR_STATUS_ENABLE));
|
||||
// 如果为空,则返回空
|
||||
if (attrs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 将规格值拼接上去
|
||||
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectListByStatus(ProductAttrConstants.ATTR_VALUE_STATUS_ENABLE);
|
||||
ImmutableListMultimap<Integer, ProductAttrValueDO> attrValueMap = Multimaps.index(attrValues, ProductAttrValueDO::getAttrId); // KEY 是 attrId ,VALUE 是 ProductAttrValueDO 数组
|
||||
for (ProductAttrSimpleBO productAttrSimpleBO : attrs) {
|
||||
productAttrSimpleBO.setValues(ProductAttrConvert.INSTANCE.convert4(((attrValueMap).get(productAttrSimpleBO.getId()))));
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package cn.iocoder.mall.product.service;
|
||||
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.mall.product.api.ProductSpuCollectionService;
|
||||
import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
|
||||
import cn.iocoder.mall.product.api.message.ProductSpuCollectionMessage;
|
||||
import cn.iocoder.mall.product.dao.ProductSpuMapper;
|
||||
import cn.iocoder.mall.product.dataobject.ProductSpuDO;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ProductSpuCollectionServiceImpl
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/01 23:14
|
||||
* @version 1.0
|
||||
*/
|
||||
@Service // 实际上不用添加。添加的原因是,必须 Spring 报错提示
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.ProductSpuCollectionService.version}")
|
||||
public class ProductSpuCollectionServiceImpl implements ProductSpuCollectionService {
|
||||
|
||||
@Autowired
|
||||
private ProductSpuMapper productSpuMapper;
|
||||
|
||||
@Resource
|
||||
private RocketMQTemplate rocketMQTemplate;
|
||||
|
||||
@Override
|
||||
public boolean productSpuCollection(Integer spuId, Integer hasCollectionType, Integer userId) {
|
||||
ProductSpuDO productSpuDO = this.productSpuMapper.selectById(spuId);
|
||||
// 校验 Spu 是否存在
|
||||
if (productSpuDO == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
|
||||
}
|
||||
this.sendProductSpuCollectionMessage(productSpuDO, hasCollectionType, userId);
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送商品收藏或取消消息
|
||||
* @param productSpuDO
|
||||
* @param hasCollectionType
|
||||
*/
|
||||
// TODO FROM 芋艿 to ??:切换到 Spring Cloud Stream 发送消息
|
||||
private void sendProductSpuCollectionMessage(final ProductSpuDO productSpuDO, final Integer hasCollectionType,
|
||||
final Integer userId) {
|
||||
List<String> result = Lists.newArrayList(Splitter.on(",").omitEmptyStrings().trimResults().split(productSpuDO.getPicUrls()));
|
||||
ProductSpuCollectionMessage productSpuCollectionMessage = new ProductSpuCollectionMessage()
|
||||
.setSpuId(productSpuDO.getId())
|
||||
.setSpuName(productSpuDO.getName())
|
||||
.setSpuImage(result.size() > 0 ? result.get(0) : "")
|
||||
.setSellPoint(productSpuDO.getSellPoint())
|
||||
.setPrice(productSpuDO.getPrice())
|
||||
.setHasCollectionType(hasCollectionType)
|
||||
.setUserId(userId);
|
||||
rocketMQTemplate.convertAndSend(ProductSpuCollectionMessage.TOPIC, productSpuCollectionMessage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package cn.iocoder.mall.product.service;
|
||||
|
||||
import cn.iocoder.common.framework.util.CollectionUtil;
|
||||
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum;
|
||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||
import cn.iocoder.mall.product.api.bo.*;
|
||||
import cn.iocoder.mall.product.api.constant.ProductCategoryConstants;
|
||||
import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
|
||||
import cn.iocoder.mall.product.api.constant.ProductSpuConstants;
|
||||
import cn.iocoder.mall.product.api.dto.*;
|
||||
import cn.iocoder.mall.product.api.message.ProductUpdateMessage;
|
||||
import cn.iocoder.mall.product.convert.ProductSpuConvert;
|
||||
import cn.iocoder.mall.product.dao.ProductSkuMapper;
|
||||
import cn.iocoder.mall.product.dao.ProductSpuMapper;
|
||||
import cn.iocoder.mall.product.dataobject.ProductCategoryDO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductSkuDO;
|
||||
import cn.iocoder.mall.product.dataobject.ProductSpuDO;
|
||||
import cn.iocoder.mall.product.message.MQStreamProducer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service // 实际上不用添加。添加的原因是,必须 Spring 报错提示
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.ProductSpuService.version}")
|
||||
public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
|
||||
@Autowired
|
||||
private ProductSpuMapper productSpuMapper;
|
||||
@Autowired
|
||||
private ProductSkuMapper productSkuMapper;
|
||||
|
||||
@Autowired
|
||||
private ProductCategoryServiceImpl productCategoryService;
|
||||
@Autowired
|
||||
private ProductAttrServiceImpl productAttrService;
|
||||
|
||||
// @Override
|
||||
// public ProductSpuBO getProductSpuDetail(Integer id) {
|
||||
// ProductSpuDO productSpuDO = productSpuMapper.selectById(id);
|
||||
// // 转换成 BO
|
||||
// return ProductSpuConvert.INSTANCE.convert(productSpuDO);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public ProductSpuDetailBO getProductSpuDetail(Integer id) {
|
||||
// 校验商品 spu 存在
|
||||
ProductSpuDO spu = productSpuMapper.selectById(id);
|
||||
if (spu == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 获得商品分类分类
|
||||
ProductCategoryDO category = productCategoryService.getProductCategory(spu.getCid());
|
||||
Assert.notNull(category, String.format("分类编号(%d) 对应", spu.getCid()));
|
||||
// 获得商品 sku 数组
|
||||
List<ProductSkuDO> skus = productSkuMapper.selectListBySpuIdAndStatus(id, ProductSpuConstants.SKU_STATUS_ENABLE);
|
||||
// 获得规格
|
||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
||||
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||
false); // 读取规格时,不考虑规格是否被禁用
|
||||
// 返回成功
|
||||
return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) {
|
||||
// 校验 Spu 是否存在
|
||||
if (productSpuMapper.selectById(spuId) == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 更新排序
|
||||
ProductSpuDO updateSpu = new ProductSpuDO().setId(spuId).setSort(sort);
|
||||
productSpuMapper.update(updateSpu);
|
||||
// 修改成功,发送商品 Topic 消息
|
||||
sendProductUpdateMessage(spuId);
|
||||
// 返回成功
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSpuBO> getProductSpuSearchList(ProductSpuSearchListDTO productSpuSearchListDTO) {
|
||||
return ProductSpuConvert.INSTANCE.convert(
|
||||
productSpuMapper.selectListByNameLikeOrderBySortAsc(productSpuSearchListDTO.getName(), null, null,
|
||||
null, null, null)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSpuBO> getProductSpuList(Collection<Integer> ids) {
|
||||
List<ProductSpuDO> spus = productSpuMapper.selectByIds(ids);
|
||||
return ProductSpuConvert.INSTANCE.convert(spus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductSkuBO getProductSku(Integer id) {
|
||||
ProductSkuDO sku = productSkuMapper.selectById(id);
|
||||
return ProductSpuConvert.INSTANCE.convert4(sku);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductSkuDetailBO> getProductSkuDetailList(Collection<Integer> ids) {
|
||||
// 查询 SKU 数组
|
||||
List<ProductSkuDO> skus = productSkuMapper.selectByIds(ids);
|
||||
if (skus.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 查询 SPU 数组
|
||||
List<ProductSpuDO> spus = productSpuMapper.selectByIds(skus.stream().map(ProductSkuDO::getSpuId).collect(Collectors.toSet()));
|
||||
if (spus.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
// 获得规格
|
||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
||||
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||
false); // 读取规格时,不考虑规格是否被禁用
|
||||
// 返回成功
|
||||
return ProductSpuConvert.INSTANCE.convert3(skus, spus, attrAndValuePairList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package cn.iocoder.mall.product.service;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum;
|
||||
import cn.iocoder.mall.product.api.UserProductSpuCollectionsService;
|
||||
import cn.iocoder.mall.product.api.bo.UserProductSpuCollectionsBO;
|
||||
import cn.iocoder.mall.product.api.bo.UserProductSpuCollectionsPageBO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsAddDTO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsPageDTO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsUpdateDTO;
|
||||
import cn.iocoder.mall.product.convert.UserProductSpuCollectionsConvert;
|
||||
import cn.iocoder.mall.product.dao.UserProductSpuCollectionsMapper;
|
||||
import cn.iocoder.mall.product.dataobject.UserProductSpuCollectionsDO;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* UserSkuCollectionsServiceImpl
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/01 21:02
|
||||
* @version 1.0
|
||||
*/
|
||||
@Service
|
||||
@org.apache.dubbo.config.annotation.Service(validation = "true", version = "${dubbo.provider.UserProductSpuCollectionsService.version}")
|
||||
public class UserProductSpuCollectionsServiceImpl implements UserProductSpuCollectionsService {
|
||||
|
||||
|
||||
@Autowired
|
||||
private UserProductSpuCollectionsMapper userProductSpuCollectionsMapper;
|
||||
|
||||
// TODO 暂时先使用冗余字段,有需要在对接实时数据查询
|
||||
// @Reference(validation = "true", version = "${dubbo.consumer.PromotionActivityService.version}")
|
||||
// private ProductSpuService productSpuService;
|
||||
|
||||
|
||||
@Override
|
||||
public int addUserSkuCollections(UserProductSpuCollectionsAddDTO userProductSpuCollectionsAddDTO) {
|
||||
return userProductSpuCollectionsMapper
|
||||
.insert(UserProductSpuCollectionsConvert.INSTANCE.convert(userProductSpuCollectionsAddDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserProductSpuCollectionsBO getUserSpuCollectionsByUserIdAndSpuId(Integer userId, Integer spuId) {
|
||||
UserProductSpuCollectionsDO userProductSpuCollectionsDO = userProductSpuCollectionsMapper
|
||||
.getUserSpuCollectionsByUserIdAndSpuId(userId, spuId);
|
||||
return UserProductSpuCollectionsConvert.INSTANCE.convert(userProductSpuCollectionsDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateUserProductSpuCollections(UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO) {
|
||||
return userProductSpuCollectionsMapper
|
||||
.updateById(UserProductSpuCollectionsConvert.INSTANCE.convert(userProductSpuCollectionsUpdateDTO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<UserProductSpuCollectionsPageBO> getUserProductSpuCollectionsPage(
|
||||
UserProductSpuCollectionsPageDTO userProductSpuCollectionsPageDTO) {
|
||||
final int offset =
|
||||
(userProductSpuCollectionsPageDTO.getPageNo() - 1) * userProductSpuCollectionsPageDTO.getPageSize();
|
||||
final int totalCount = this.userProductSpuCollectionsMapper
|
||||
.selectCountByUser(userProductSpuCollectionsPageDTO.getUserId());
|
||||
if (totalCount == 0) {
|
||||
return CommonResult
|
||||
.success(new UserProductSpuCollectionsPageBO().setList(Collections.emptyList()).setTotal(0));
|
||||
}
|
||||
|
||||
List<UserProductSpuCollectionsDO> list = userProductSpuCollectionsMapper
|
||||
.selectListByUser(userProductSpuCollectionsPageDTO.getUserId(), offset,
|
||||
userProductSpuCollectionsPageDTO.getPageSize());
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return CommonResult.success(
|
||||
new UserProductSpuCollectionsPageBO().setList(Collections.emptyList()).setTotal(totalCount));
|
||||
}
|
||||
for (UserProductSpuCollectionsDO userProductSpuCollectionsDO : list
|
||||
) {
|
||||
List<String> result = Lists.newArrayList(Splitter.on(",").omitEmptyStrings().trimResults().split(userProductSpuCollectionsDO.getSpuImage()));
|
||||
userProductSpuCollectionsDO.setSpuImage(result.size() > 0 ? result.get(0) : "");
|
||||
}
|
||||
|
||||
UserProductSpuCollectionsPageBO userProductSpuCollectionsPageBO = new UserProductSpuCollectionsPageBO();
|
||||
userProductSpuCollectionsPageBO.setList(UserProductSpuCollectionsConvert.INSTANCE.convert(list));
|
||||
// 查询分页总数
|
||||
userProductSpuCollectionsPageBO.setTotal(totalCount);
|
||||
// 返回结果
|
||||
return CommonResult.success(userProductSpuCollectionsPageBO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取消收藏
|
||||
* @param userId
|
||||
* @param spuId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public CommonResult<Boolean> deleteUserProductSpuCollections(final Integer userId, final Integer spuId) {
|
||||
UserProductSpuCollectionsBO userProductSpuCollectionsBO = this
|
||||
.getUserSpuCollectionsByUserIdAndSpuId(userId, spuId);
|
||||
int result = 0;
|
||||
if (userProductSpuCollectionsBO != null) {
|
||||
// 未取消收藏的数据
|
||||
if (userProductSpuCollectionsBO.getDeleted().equals(DeletedStatusEnum.DELETED_NO.getValue())) {
|
||||
UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO = new UserProductSpuCollectionsUpdateDTO()
|
||||
.setId(userProductSpuCollectionsBO.getId()).setUpdateTime(new Date())
|
||||
.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
|
||||
result = this.updateUserProductSpuCollections(userProductSpuCollectionsUpdateDTO);
|
||||
}
|
||||
}
|
||||
return CommonResult.success(result > 0 ? Boolean.TRUE : Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> hasUserSpuFavorite(final Integer spuId, final Integer userId) {
|
||||
UserProductSpuCollectionsBO userProductSpuCollectionsBO = this
|
||||
.getUserSpuCollectionsByUserIdAndSpuId(userId, spuId);
|
||||
|
||||
if (userProductSpuCollectionsBO != null) {
|
||||
// 收藏
|
||||
final boolean hasCollect = userProductSpuCollectionsBO.getDeleted()
|
||||
.equals(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
return CommonResult.success(hasCollect);
|
||||
}
|
||||
return CommonResult.success(Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
spring:
|
||||
# datasource
|
||||
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
|
||||
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: s1.iocoder.cn:8848 # Nacos 服务器地址
|
||||
|
||||
# Spring Cloud Stream 配置
|
||||
stream:
|
||||
# Binding 配置项
|
||||
bindings:
|
||||
product-update-output:
|
||||
destination: ProductUpdate
|
||||
# Spring Cloud Stream RocketMQ 配置项
|
||||
rocketmq:
|
||||
# RocketMQ Binder 配置项
|
||||
binder:
|
||||
name-server: s1.iocoder.cn:9876 # RocketMQ Namesrv 地址
|
||||
# RocketMQ 默认 Binding 配置项
|
||||
default:
|
||||
# RocketMQ 生产者
|
||||
producer:
|
||||
group: product-producer-group # 生产者分组
|
||||
sync: true # 是否同步发送消息,默认为 false 异步。
|
||||
|
||||
# mybatis
|
||||
mybatis-plus:
|
||||
config-location: classpath:mybatis-config.xml
|
||||
mapper-locations: classpath:mapper/*.xml
|
||||
type-aliases-package: cn.iocoder.mall.product.dataobject
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
address: spring-cloud://s1.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
# Spring Cloud Alibaba Dubbo 专属配置
|
||||
cloud:
|
||||
subscribed-services: admin-application, user-application # 设置订阅的应用列表,默认为 * 订阅所有应用
|
||||
# Dubbo 提供者的协议
|
||||
protocol:
|
||||
name: dubbo
|
||||
port: -1
|
||||
# Dubbo 提供服务的扫描基础包
|
||||
scan:
|
||||
base-packages: cn.iocoder.mall.product.service
|
||||
# Dubbo 服务提供者的配置
|
||||
provider:
|
||||
filter: -exception
|
||||
ProductAttrService:
|
||||
version: 1.0.0
|
||||
ProductCategoryService:
|
||||
version: 1.0.0
|
||||
ProductSpuService:
|
||||
version: 1.0.0
|
||||
ProductBrandService:
|
||||
version: 1.0.0
|
||||
OAuth2Service:
|
||||
version: 1.0.0
|
||||
ProductSpuCollectionService:
|
||||
version: 1.0.0
|
||||
UserProductSpuCollectionsService:
|
||||
version: 1.0.0
|
||||
consumer:
|
||||
UserService:
|
||||
version: 1.0.0
|
||||
|
||||
# Seata 配置项
|
||||
seata:
|
||||
tx-service-group: default # Seata 事务组编号,用于 TC 集群名
|
||||
# 服务配置项,对应 ServiceProperties 类
|
||||
service:
|
||||
# 虚拟组和分组的映射
|
||||
vgroup-mapping:
|
||||
default: default
|
||||
# Seata 注册中心配置项
|
||||
registry:
|
||||
type: nacos # 注册中心类型
|
||||
nacos:
|
||||
serverAddr: ${spring.cloud.nacos.discovery.server-addr} # Nacos 服务地址
|
||||
namespace: # Nacos 命名空间
|
||||
cluster: default # 使用的 Seata 分组
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?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.dao.ProductAttrMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, name, status, create_time
|
||||
</sql>
|
||||
|
||||
<!--<select id="selectList" resultType="ProductCategoryDO">-->
|
||||
<!--SELECT-->
|
||||
<!--<include refid="FIELDS" />-->
|
||||
<!--FROM product_category-->
|
||||
<!--WHERE deleted = 0-->
|
||||
<!--</select>-->
|
||||
|
||||
<select id="selectById" parameterType="Integer" resultType="ProductAttrDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr
|
||||
WHERE id = #{id}
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectByName" parameterType="String" resultType="ProductAttrDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr
|
||||
WHERE name = #{name}
|
||||
AND deleted = 0
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="ProductAttrDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||
INSERT INTO product_attr (
|
||||
name, status, create_time, deleted
|
||||
) VALUES (
|
||||
#{name}, #{status}, #{createTime}, #{deleted}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="ProductAttrDO">
|
||||
UPDATE product_attr
|
||||
<set>
|
||||
<if test="name != null">
|
||||
name = #{name},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status},
|
||||
</if>
|
||||
<if test="deleted != null">
|
||||
deleted = #{deleted}
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="selectListByIds" resultType="ProductAttrDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr
|
||||
WHERE id IN
|
||||
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
|
||||
#{id}
|
||||
</foreach>
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectListByNameLike" resultType="ProductAttrDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr
|
||||
<where>
|
||||
<if test="name != null">
|
||||
name LIKE "%"#{name}"%"
|
||||
</if>
|
||||
AND deleted = 0
|
||||
</where>
|
||||
LIMIT #{offset}, #{limit}
|
||||
</select>
|
||||
|
||||
<select id="selectCountByNameLike" resultType="Integer">
|
||||
SELECT
|
||||
COUNT(1)
|
||||
FROM product_attr
|
||||
<where>
|
||||
<if test="name != null">
|
||||
name LIKE "%"#{name}"%"
|
||||
</if>
|
||||
AND deleted = 0
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectListByStatus" parameterType="Integer" resultType="ProductAttrDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr
|
||||
<where>
|
||||
<if test="status != null">
|
||||
status = #{status}
|
||||
</if>
|
||||
AND deleted = 0
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,130 @@
|
||||
<?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.dao.ProductAttrValueMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, attr_id, name, status, create_time
|
||||
</sql>
|
||||
|
||||
<!--<select id="selectList" resultType="ProductCategoryDO">-->
|
||||
<!--SELECT-->
|
||||
<!--<include refid="FIELDS" />-->
|
||||
<!--FROM product_category-->
|
||||
<!--WHERE deleted = 0-->
|
||||
<!--</select>-->
|
||||
|
||||
<select id="selectById" parameterType="Integer" resultType="ProductAttrValueDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr_value
|
||||
WHERE id = #{id}
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<!--<insert id="insert" parameterType="ProductCategoryDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">-->
|
||||
<!--INSERT INTO product_category (-->
|
||||
<!--pid, name, description, pic_url, sort,-->
|
||||
<!--status, create_time, deleted-->
|
||||
<!--) VALUES (-->
|
||||
<!--#{pid}, #{name}, #{description}, #{picUrl}, #{sort},-->
|
||||
<!--#{status}, #{createTime}, #{deleted}-->
|
||||
<!--)-->
|
||||
<!--</insert>-->
|
||||
|
||||
<!--<update id="update" parameterType="ProductCategoryDO">-->
|
||||
<!--UPDATE product_category-->
|
||||
<!--<set>-->
|
||||
<!--<if test="pid != null">-->
|
||||
<!--pid = #{pid},-->
|
||||
<!--</if>-->
|
||||
<!--<if test="name != null">-->
|
||||
<!--name = #{name},-->
|
||||
<!--</if>-->
|
||||
<!--<if test="description != null">-->
|
||||
<!--description = #{description},-->
|
||||
<!--</if>-->
|
||||
<!--<if test="picUrl != null">-->
|
||||
<!--pic_url = #{picUrl},-->
|
||||
<!--</if>-->
|
||||
<!--<if test="sort != null">-->
|
||||
<!--sort = #{sort},-->
|
||||
<!--</if>-->
|
||||
<!--<if test="status != null">-->
|
||||
<!--status = #{status},-->
|
||||
<!--</if>-->
|
||||
<!--<if test="deleted != null">-->
|
||||
<!--deleted = #{deleted}-->
|
||||
<!--</if>-->
|
||||
<!--</set>-->
|
||||
<!--WHERE id = #{id}-->
|
||||
<!--</update>-->
|
||||
|
||||
<select id="selectListByIds" resultType="ProductAttrValueDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr_value
|
||||
WHERE id IN
|
||||
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
|
||||
#{id}
|
||||
</foreach>
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectListByAttrIds" resultType="ProductAttrValueDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr_value
|
||||
WHERE attr_id IN
|
||||
<foreach item="attrId" collection="attrIds" separator="," open="(" close=")" index="">
|
||||
#{attrId}
|
||||
</foreach>
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectListByStatus" resultType="ProductAttrValueDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr_value
|
||||
<where>
|
||||
<if test="status != null">
|
||||
status = #{status}
|
||||
</if>
|
||||
AND deleted = 0
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="selectByAttrIdAndName" resultType="ProductAttrValueDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_attr_value
|
||||
WHERE name = #{name}
|
||||
AND deleted = 0
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="ProductAttrValueDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||
INSERT INTO product_attr_value (
|
||||
attr_id, name, status, create_time, deleted
|
||||
) VALUES (
|
||||
#{attrId}, #{name}, #{status}, #{createTime}, #{deleted}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="ProductAttrValueDO">
|
||||
UPDATE product_attr_value
|
||||
<set>
|
||||
<if test="name != null">
|
||||
name = #{name},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status},
|
||||
</if>
|
||||
<if test="deleted != null">
|
||||
deleted = #{deleted}
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?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.dao.ProductSkuMapper">
|
||||
|
||||
<sql id="FIELDS">
|
||||
id, spu_id, status, pic_url, attrs,
|
||||
price, quantity, create_time
|
||||
</sql>
|
||||
|
||||
<select id="selectById" parameterType="Integer" resultType="ProductSkuDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_sku
|
||||
WHERE id = #{id}
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="selectByIds" resultType="ProductSkuDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_sku
|
||||
WHERE id IN
|
||||
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
|
||||
#{id}
|
||||
</foreach>
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||
INSERT INTO product_sku (
|
||||
spu_id, status, pic_url, attrs, price,
|
||||
quantity, deleted, create_time
|
||||
) VALUES
|
||||
<foreach collection="productSkuDOs" item="productSkuDO" separator=",">
|
||||
(#{productSkuDO.spuId}, #{productSkuDO.status}, #{productSkuDO.picUrl}, #{productSkuDO.attrs}, #{productSkuDO.price},
|
||||
#{productSkuDO.quantity}, #{productSkuDO.deleted}, #{productSkuDO.createTime}
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<select id="selectListBySpuIdAndStatus" resultType="ProductSkuDO">
|
||||
SELECT
|
||||
<include refid="FIELDS" />
|
||||
FROM product_sku
|
||||
WHERE spu_id = #{spuId}
|
||||
AND status = #{status}
|
||||
AND deleted = 0
|
||||
</select>
|
||||
|
||||
<update id="update" parameterType="ProductSpuDO">
|
||||
UPDATE product_sku
|
||||
<set>
|
||||
<if test="spuId != null">
|
||||
spu_id = #{spuId},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status},
|
||||
</if>
|
||||
<if test="picUrl != null">
|
||||
pic_url = #{picUrl},
|
||||
</if>
|
||||
<if test="attrs != null">
|
||||
attrs = #{attrs},
|
||||
</if>
|
||||
<if test="price != null">
|
||||
price = #{price},
|
||||
</if>
|
||||
<if test="quantity != null">
|
||||
quantity = #{quantity},
|
||||
</if>
|
||||
<if test="deleted != null">
|
||||
deleted = #{deleted}
|
||||
</if>
|
||||
</set>
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateToDeleted" parameterType="Integer">
|
||||
UPDATE product_sku
|
||||
SET deleted = 1
|
||||
WHERE id IN
|
||||
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
|
||||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
106
moved/product/product-start/pom.xml
Normal file
106
moved/product/product-start/pom.xml
Normal file
@@ -0,0 +1,106 @@
|
||||
<?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>product</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>product-start</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- Mall 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>common-framework</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-service-impl</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-mybatis</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>swagger-bootstrap-ui</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 服务保障相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 监控 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 测试相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-security</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- 提供给 mapstruct 使用 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<!-- 打包 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,44 @@
|
||||
package cn.iocoder.mall.product.application.controller.admins;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.product.api.ProductAttrService;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrValueBO;
|
||||
import cn.iocoder.mall.product.api.dto.*;
|
||||
import cn.iocoder.mall.product.application.convert.ProductAttrConvert;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrPageVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrSimpleVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrValueVO;
|
||||
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("admins")
|
||||
@Api("商品规格")
|
||||
public class AdminsProductAttrController {
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.provider.ProductAttrService.version}")
|
||||
private ProductAttrService productAttrService;
|
||||
|
||||
@GetMapping("/attr/tree")
|
||||
@ApiOperation(value = "获得规格树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。")
|
||||
public CommonResult<List<AdminsProductAttrSimpleVO>> tree() {
|
||||
// 查询全列表
|
||||
List<ProductAttrSimpleBO> result = productAttrService.getProductAttrList();
|
||||
// 返回结果
|
||||
return success(ProductAttrConvert.INSTANCE.convert(result));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package cn.iocoder.mall.product.application.controller.admins;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
||||
import cn.iocoder.mall.product.api.dto.*;
|
||||
import cn.iocoder.mall.product.application.convert.ProductSpuConvert;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuPageVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuVO;
|
||||
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("admins")
|
||||
@Api("商品 SPU + SKU")
|
||||
public class AdminsProductSpuController {
|
||||
|
||||
@PostMapping("/spu/update_sort")
|
||||
@ApiOperation("更新商品的排序")
|
||||
public CommonResult<Boolean> updateSort(@RequestParam("id") Integer id,
|
||||
@RequestParam("sort") Integer sort) {
|
||||
return success(productSpuService.updateProductSpuSort(AdminSecurityContextHolder.getContext().getAdminId(), id, sort));
|
||||
}
|
||||
|
||||
@GetMapping("/spu/search_list")
|
||||
@ApiOperation("商品 SPU 搜索列表")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "name", value = "商品名称,模糊匹配", example = "小王"),
|
||||
})
|
||||
public CommonResult<List<AdminsProductSpuVO>> spuSearchList(@RequestParam(value = "name", required = false) String name) {
|
||||
// 创建 ProductSpuSearchListDTO 对象
|
||||
ProductSpuSearchListDTO productSpuSearchListDTO = new ProductSpuSearchListDTO().setName(name);
|
||||
// 执行搜索
|
||||
List<ProductSpuBO> list = productSpuService.getProductSpuSearchList(productSpuSearchListDTO);
|
||||
// 转换返回
|
||||
return success(ProductSpuConvert.INSTANCE.convert3(list));
|
||||
}
|
||||
|
||||
@GetMapping("/spu/info")
|
||||
@ApiOperation("商品 SPU 明细")
|
||||
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
||||
public CommonResult<AdminsProductSpuDetailVO> spuInfo(@RequestParam("id") Integer id) {
|
||||
return success(ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpuDetail(id)));
|
||||
}
|
||||
|
||||
@GetMapping("/spu/list")
|
||||
@ApiOperation("商品 SPU 列表")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "ids", value = "商品 SPU 编号数组", example = "1,2,3"),
|
||||
})
|
||||
public CommonResult<List<AdminsProductSpuVO>> spuList(@RequestParam("ids") Collection<Integer> ids) {
|
||||
List<ProductSpuBO> list = productSpuService.getProductSpuList(ids);
|
||||
// 转换返回
|
||||
return success(ProductSpuConvert.INSTANCE.convert3(list));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package cn.iocoder.mall.product.application.controller.users;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.product.api.UserProductSpuCollectionsService;
|
||||
import cn.iocoder.mall.product.api.bo.UserProductSpuCollectionsPageBO;
|
||||
import cn.iocoder.mall.product.api.dto.UserProductSpuCollectionsPageDTO;
|
||||
import cn.iocoder.mall.security.core.context.UserSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 用户收藏
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/07 11:06
|
||||
* @version 1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("users/favorite")
|
||||
@Api("用户收藏")
|
||||
public class UserFavoriteController {
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.provider.UserProductSpuCollectionsService.version}")
|
||||
private UserProductSpuCollectionsService userProductSpuCollectionsService;
|
||||
|
||||
@GetMapping("page")
|
||||
@ApiOperation("用户商品收藏列表")
|
||||
public CommonResult<UserProductSpuCollectionsPageBO> getUserProductSpuCollectionsPage(
|
||||
@Validated UserProductSpuCollectionsPageDTO userProductSpuCollectionsPageDTO) {
|
||||
final Integer userId = UserSecurityContextHolder.getContext().getUserId();
|
||||
userProductSpuCollectionsPageDTO.setUserId(userId);
|
||||
return userProductSpuCollectionsService.getUserProductSpuCollectionsPage(userProductSpuCollectionsPageDTO);
|
||||
}
|
||||
|
||||
@DeleteMapping("remove")
|
||||
@ApiOperation(value = "用户商品收藏-删除")
|
||||
public CommonResult<Boolean> removeUserFavorite(@RequestParam("spuId") final Integer spuId) {
|
||||
final Integer userId = UserSecurityContextHolder.getContext().getUserId();
|
||||
return userProductSpuCollectionsService.deleteUserProductSpuCollections(userId, spuId);
|
||||
}
|
||||
|
||||
@GetMapping("hasUserFavorite")
|
||||
@ApiOperation(value = "用户商品收藏-是否收藏")
|
||||
public CommonResult<Boolean> hasUserSpuFavorite(@RequestParam("spuId") final Integer spuId) {
|
||||
final Integer userId = UserSecurityContextHolder.getContext().getUserId();
|
||||
return userProductSpuCollectionsService.hasUserSpuFavorite(spuId, userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package cn.iocoder.mall.product.application.controller.users;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.product.api.ProductSpuCollectionService;
|
||||
import cn.iocoder.mall.security.core.context.UserSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 商品收藏接口
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/01 23:21
|
||||
* @version 1.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("users/spu")
|
||||
@Api("商品收藏")
|
||||
public class UsersProductSpuCollectionController {
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.provider.ProductSpuCollectionService.version}")
|
||||
private ProductSpuCollectionService productSpuCollectionService;
|
||||
|
||||
@PostMapping("/collection/{spuId}/{hasCollectionType}")
|
||||
@ApiOperation("商品收藏")
|
||||
public CommonResult<Boolean> productSpuCollection(@PathVariable("spuId") Integer spuId,
|
||||
@PathVariable("hasCollectionType") Integer hasCollectionType) {
|
||||
final Integer userId = UserSecurityContextHolder.getContext().getUserId();
|
||||
return success(productSpuCollectionService.productSpuCollection(spuId, hasCollectionType,userId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.mall.product.application.controller.users;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
||||
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
|
||||
import cn.iocoder.mall.product.application.convert.ProductSpuConvert;
|
||||
import cn.iocoder.mall.product.application.vo.users.UsersProductSpuDetailVO;
|
||||
import cn.iocoder.mall.product.application.vo.users.UsersProductSpuPageVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.dubbo.config.annotation.Reference;
|
||||
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 static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("users/spu")
|
||||
@Api("商品 SPU + SKU")
|
||||
public class UsersProductSpuController {
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.provider.ProductSpuService.version}")
|
||||
private ProductSpuService productSpuService;
|
||||
|
||||
@GetMapping("/info")
|
||||
@ApiOperation("商品 SPU 明细")
|
||||
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
||||
public CommonResult<UsersProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
||||
return success(ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpuDetail(id)));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("商品 SPU 分页列表")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "cid", value = "分类编号", example = "1"),
|
||||
@ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"),
|
||||
})
|
||||
@Deprecated // 使用商品搜索接口
|
||||
public CommonResult<UsersProductSpuPageVO> page(@RequestParam(value = "cid", required = false) Integer cid,
|
||||
@RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
// 创建 ProductSpuPageDTO 对象
|
||||
ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setCid(cid).setVisible(true)
|
||||
.setPageNo(pageNo).setPageSize(pageSize);
|
||||
// 查询分页
|
||||
ProductSpuPageBO result = productSpuService.getProductSpuPage(productSpuPageDTO);
|
||||
// 返回结果
|
||||
return success(ProductSpuConvert.INSTANCE.convert3(result));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package cn.iocoder.mall.product.application.convert;
|
||||
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrPageBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrSimpleBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductAttrValueBO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrPageVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrSimpleVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductAttrValueVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ProductAttrConvert {
|
||||
|
||||
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProductAttrPageVO convert2(ProductAttrPageBO result);
|
||||
|
||||
@Mappings({})
|
||||
List<AdminsProductAttrSimpleVO> convert(List<ProductAttrSimpleBO> result);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProductAttrVO convert3(ProductAttrBO productAttrBO);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProductAttrValueVO convert4(ProductAttrValueBO productAttrValueBO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package cn.iocoder.mall.product.application.convert;
|
||||
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuPageVO;
|
||||
import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuVO;
|
||||
import cn.iocoder.mall.product.application.vo.users.UsersProductSpuDetailVO;
|
||||
import cn.iocoder.mall.product.application.vo.users.UsersProductSpuPageVO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface ProductSpuConvert {
|
||||
|
||||
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProductSpuDetailVO convert(ProductSpuDetailBO productSpuDetailBO);
|
||||
|
||||
// @Mappings({})
|
||||
// CommonResult<AdminsProductSpuDetailVO> convert(CommonResult<ProductSpuDetailBO> result);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProductSpuPageVO convert2(ProductSpuPageBO result);
|
||||
|
||||
@Mappings({})
|
||||
List<AdminsProductSpuVO> convert3(List<ProductSpuBO> result);
|
||||
|
||||
@Mappings({})
|
||||
UsersProductSpuPageVO convert3(ProductSpuPageBO result);
|
||||
|
||||
@Mappings({})
|
||||
UsersProductSpuDetailVO convert4(ProductSpuDetailBO result);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.mall.product.application.vo.admins;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@ApiModel(value = "商品规格属性和值对 VO")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminsProductAttrAndValuePairVO {
|
||||
|
||||
@ApiModelProperty(value = "规格编号", required = true, example = "1")
|
||||
private Integer attrId;
|
||||
@ApiModelProperty(value = "规格名", required = true, example = "颜色")
|
||||
private String attrName;
|
||||
@ApiModelProperty(value = "规格值", required = true, example = "10")
|
||||
private Integer attrValueId;
|
||||
@ApiModelProperty(value = "规格值名", required = true, example = "红色")
|
||||
private String attrValueName;
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user