商品 SPU 开始迁移

This commit is contained in:
YunaiV 2020-07-26 11:04:32 +08:00
parent de81e5f5ae
commit e87cb91332
30 changed files with 1135 additions and 200 deletions

View File

@ -0,0 +1,67 @@
package cn.iocoder.mall.managementweb.controller.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuPageReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuUpdateReqVO;
import cn.iocoder.mall.managementweb.manager.product.ProductSpuManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
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 javax.validation.Valid;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
/**
* 商品 SPU Controller
*/
@RestController
@RequestMapping("/product_spu")
@Api(tags = "商品 SPU")
@Validated
public class ProductSpuController {
@Autowired
private ProductSpuManager productSpuManager;
@PostMapping("/create")
@ApiOperation("创建商品 SPU")
public CommonResult<Integer> createProductSpu(@Valid ProductSpuCreateReqVO createVO) {
return success(productSpuManager.createProductSpu(createVO));
}
@PostMapping("/update")
@ApiOperation("更新商品 SPU")
public CommonResult<Boolean> updateProductSpu(@Valid ProductSpuUpdateReqVO updateVO) {
productSpuManager.updateProductSpu(updateVO);
return success(true);
}
@GetMapping("/get")
@ApiOperation("获得商品 SPU")
@ApiImplicitParam(name = "productSpuId", value = "商品 SPU编号", required = true)
public CommonResult<ProductSpuRespVO> getProductSpu(@RequestParam("productSpuId") Integer productSpuId) {
return success(productSpuManager.getProductSpu(productSpuId));
}
@GetMapping("/list")
@ApiOperation("获得商品 SPU 列表")
@ApiImplicitParam(name = "productSpuIds", value = "商品 SPU编号列表", required = true)
public CommonResult<List<ProductSpuRespVO>> listProductSpus(@RequestParam("productSpuIds") List<Integer> productSpuIds) {
return success(productSpuManager.listProductSpus(productSpuIds));
}
@GetMapping("/page")
@ApiOperation("获得商品 SPU 分页")
public CommonResult<PageResult<ProductSpuRespVO>> pageProductSpu(ProductSpuPageReqVO pageVO) {
return success(productSpuManager.pageProductSpu(pageVO));
}
}

View File

@ -0,0 +1,42 @@
package cn.iocoder.mall.managementweb.controller.product.vo.spu;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品 SPU创建 Request VO")
@Data
public class ProductSpuCreateReqVO {
@ApiModelProperty(value = "SPU 名字", required = true)
@NotEmpty(message = "SPU 名字不能为空")
private String name;
@ApiModelProperty(value = "卖点", required = true)
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
@ApiModelProperty(value = "描述", required = true)
@NotEmpty(message = "描述不能为空")
private String description;
@ApiModelProperty(value = "分类编号", required = true)
@NotNull(message = "分类编号不能为空")
private Integer cid;
@ApiModelProperty(value = "商品主图地址", required = true)
@NotEmpty(message = "商品主图地址不能为空")
private String picUrls;
@ApiModelProperty(value = "是否上架商品", required = true)
@NotNull(message = "是否上架商品不能为空")
private Integer visible;
@ApiModelProperty(value = "排序字段", required = true)
@NotNull(message = "排序字段不能为空")
private Integer sort;
@ApiModelProperty(value = "价格", required = true)
@NotNull(message = "价格不能为空")
private Integer price;
@ApiModelProperty(value = "库存数量", required = true)
@NotNull(message = "库存数量不能为空")
private Integer quantity;
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.mall.managementweb.controller.product.vo.spu;
import cn.iocoder.common.framework.vo.PageParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ApiModel("商品 SPU分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
public class ProductSpuPageReqVO extends PageParam {
@ApiModelProperty(value = "SPU 名字", required = true)
private String name;
@ApiModelProperty(value = "卖点", required = true)
private String sellPoint;
@ApiModelProperty(value = "描述", required = true)
private String description;
@ApiModelProperty(value = "分类编号", required = true)
private Integer cid;
@ApiModelProperty(value = "商品主图地址", required = true)
private String picUrls;
@ApiModelProperty(value = "是否上架商品", required = true)
private Integer visible;
@ApiModelProperty(value = "排序字段", required = true)
private Integer sort;
@ApiModelProperty(value = "价格", required = true)
private Integer price;
@ApiModelProperty(value = "库存数量", required = true)
private Integer quantity;
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.mall.managementweb.controller.product.vo.spu;
import lombok.*;
import io.swagger.annotations.*;
import java.util.*;
@ApiModel("商品 SPU Response VO")
@Data
public class ProductSpuRespVO {
@ApiModelProperty(value = "SPU 编号", required = true)
private Integer id;
@ApiModelProperty(value = "SPU 名字", required = true)
private String name;
@ApiModelProperty(value = "卖点", required = true)
private String sellPoint;
@ApiModelProperty(value = "描述", required = true)
private String description;
@ApiModelProperty(value = "分类编号", required = true)
private Integer cid;
@ApiModelProperty(value = "商品主图地址", required = true)
private String picUrls;
@ApiModelProperty(value = "是否上架商品", required = true)
private Integer visible;
@ApiModelProperty(value = "排序字段", required = true)
private Integer sort;
@ApiModelProperty(value = "价格", required = true)
private Integer price;
@ApiModelProperty(value = "库存数量", required = true)
private Integer quantity;
@ApiModelProperty(value = "创建时间", required = true)
private Date createTime;
@ApiModelProperty(value = "最后更新时间", required = true)
private Date updateTime;
}

View File

@ -0,0 +1,45 @@
package cn.iocoder.mall.managementweb.controller.product.vo.spu;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@ApiModel("商品 SPU更新 Request VO")
@Data
public class ProductSpuUpdateReqVO {
@ApiModelProperty(value = "SPU 编号", required = true)
@NotNull(message = "SPU 编号不能为空")
private Integer id;
@ApiModelProperty(value = "SPU 名字", required = true)
@NotEmpty(message = "SPU 名字不能为空")
private String name;
@ApiModelProperty(value = "卖点", required = true)
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
@ApiModelProperty(value = "描述", required = true)
@NotEmpty(message = "描述不能为空")
private String description;
@ApiModelProperty(value = "分类编号", required = true)
@NotNull(message = "分类编号不能为空")
private Integer cid;
@ApiModelProperty(value = "商品主图地址", required = true)
@NotEmpty(message = "商品主图地址不能为空")
private String picUrls;
@ApiModelProperty(value = "是否上架商品", required = true)
@NotNull(message = "是否上架商品不能为空")
private Integer visible;
@ApiModelProperty(value = "排序字段", required = true)
@NotNull(message = "排序字段不能为空")
private Integer sort;
@ApiModelProperty(value = "价格", required = true)
@NotNull(message = "价格不能为空")
private Integer price;
@ApiModelProperty(value = "库存数量", required = true)
@NotNull(message = "库存数量不能为空")
private Integer quantity;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.mall.managementweb.convert.product;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuPageReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuUpdateReqVO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductSpuConvert {
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
ProductSpuCreateReqDTO convert(ProductSpuCreateReqVO bean);
ProductSpuUpdateReqDTO convert(ProductSpuUpdateReqVO bean);
ProductSpuRespVO convert(ProductSpuRespDTO bean);
List<ProductSpuRespVO> convertList(List<ProductSpuRespDTO> list);
PageResult<ProductSpuRespVO> convertPage(PageResult<ProductSpuRespDTO> page);
ProductSpuPageReqDTO convert(ProductSpuPageReqVO bean);
}

View File

@ -0,0 +1,84 @@
package cn.iocoder.mall.managementweb.manager.product;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuCreateReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuPageReqVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuRespVO;
import cn.iocoder.mall.managementweb.controller.product.vo.spu.ProductSpuUpdateReqVO;
import cn.iocoder.mall.managementweb.convert.product.ProductSpuConvert;
import cn.iocoder.mall.productservice.rpc.spu.ProductSpuRpc;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 商品 SPU Manager
*/
@Service
public class ProductSpuManager {
@DubboReference(version = "${dubbo.consumer.ProductSpuRpc.version}")
private ProductSpuRpc productSpuRpc;
/**
* 创建商品 SPU
*
* @param createVO 创建商品 SPU VO
* @return 商品 SPU
*/
public Integer createProductSpu(ProductSpuCreateReqVO createVO) {
CommonResult<Integer> createProductSpuResult = productSpuRpc.createProductSpu(ProductSpuConvert.INSTANCE.convert(createVO));
createProductSpuResult.checkError();
return createProductSpuResult.getData();
}
/**
* 更新商品 SPU
*
* @param updateVO 更新商品 SPU VO
*/
public void updateProductSpu(ProductSpuUpdateReqVO updateVO) {
CommonResult<Boolean> updateProductSpuResult = productSpuRpc.updateProductSpu(ProductSpuConvert.INSTANCE.convert(updateVO));
updateProductSpuResult.checkError();
}
/**
* 获得商品 SPU
*
* @param productSpuId 商品 SPU编号
* @return 商品 SPU
*/
public ProductSpuRespVO getProductSpu(Integer productSpuId) {
CommonResult<ProductSpuRespDTO> getProductSpuResult = productSpuRpc.getProductSpu(productSpuId);
getProductSpuResult.checkError();
return ProductSpuConvert.INSTANCE.convert(getProductSpuResult.getData());
}
/**
* 获得商品 SPU列表
*
* @param productSpuIds 商品 SPU编号列表
* @return 商品 SPU列表
*/
public List<ProductSpuRespVO> listProductSpus(List<Integer> productSpuIds) {
CommonResult<List<ProductSpuRespDTO>> listProductSpuResult = productSpuRpc.listProductSpus(productSpuIds);
listProductSpuResult.checkError();
return ProductSpuConvert.INSTANCE.convertList(listProductSpuResult.getData());
}
/**
* 获得商品 SPU分页
*
* @param pageVO 商品 SPU分页查询
* @return 商品 SPU分页结果
*/
public PageResult<ProductSpuRespVO> pageProductSpu(ProductSpuPageReqVO pageVO) {
CommonResult<PageResult<ProductSpuRespDTO>> pageProductSpuResult = productSpuRpc.pageProductSpu(ProductSpuConvert.INSTANCE.convert(pageVO));
pageProductSpuResult.checkError();
return ProductSpuConvert.INSTANCE.convertPage(pageProductSpuResult.getData());
}
}

View File

@ -53,6 +53,8 @@ dubbo:
version: 1.0.0
ProductBrandRpc:
version: 1.0.0
ProductSpuRpc:
version: 1.0.0
# Swagger 配置项
swagger:

View File

@ -0,0 +1,56 @@
package cn.iocoder.mall.productservice.rpc.spu;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
import java.util.List;
/**
* 商品 SPU Rpc 接口
*/
public interface ProductSpuRpc {
/**
* 创建商品 SPU
*
* @param createDTO 创建商品 SPU DTO
* @return 商品 SPU编号
*/
CommonResult<Integer> createProductSpu(ProductSpuCreateReqDTO createDTO);
/**
* 更新商品 SPU
*
* @param updateDTO 更新商品 SPU DTO
*/
CommonResult<Boolean> updateProductSpu(ProductSpuUpdateReqDTO updateDTO);
/**
* 获得商品 SPU
*
* @param productSpuId 商品 SPU 编号
* @return 商品 SPU
*/
CommonResult<ProductSpuRespDTO> getProductSpu(Integer productSpuId);
/**
* 获得商品 SPU列表
*
* @param productSpuIds 商品 SPU 编号列表
* @return 商品 SPU 列表
*/
CommonResult<List<ProductSpuRespDTO>> listProductSpus(List<Integer> productSpuIds);
/**
* 获得商品 SPU分页
*
* @param pageDTO 商品 SPU分页查询
* @return 商品 SPU分页结果
*/
CommonResult<PageResult<ProductSpuRespDTO>> pageProductSpu(ProductSpuPageReqDTO pageDTO);
}

View File

@ -0,0 +1,63 @@
package cn.iocoder.mall.productservice.rpc.spu.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU 创建 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuCreateReqDTO {
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
/**
* 是否上架商品
*/
@NotNull(message = "是否上架商品不能为空")
private Integer visible;
/**
* 排序字段
*/
@NotNull(message = "排序字段不能为空")
private Integer sort;
/**
* 价格
*/
@NotNull(message = "价格不能为空")
private Integer price;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空")
private Integer quantity;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.mall.productservice.rpc.spu.dto;
import cn.iocoder.common.framework.vo.PageParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品 SPU 分页 Request DTO
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductSpuPageReqDTO extends PageParam {
/**
* SPU 名字
*/
private String name;
/**
* 是否有库存
*/
private Boolean hasQuantity;
}

View File

@ -0,0 +1,61 @@
package cn.iocoder.mall.productservice.rpc.spu.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
/**
* 商品 SPU 信息 Response DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuRespDTO {
/**
* 商品 SPU 编号
*/
private Integer id;
/**
* SPU 名字
*/
private String name;
/**
* 卖点
*/
private String sellPoint;
/**
* 描述
*/
private String description;
/**
* 分类编号
*/
private Integer cid;
/**
* 商品主图地址
*/
private List<String> picUrls;
/**
* 是否上架商品
*/
private Integer visible;
/**
* 排序字段
*/
private Integer sort;
/**
* 价格
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -0,0 +1,68 @@
package cn.iocoder.mall.productservice.rpc.spu.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU 更新 Request DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuUpdateReqDTO {
/**
* 商品 SPU 编号
*/
@NotNull(message = "商品 SPU 编号不能为空")
private Integer id;
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
/**
* 是否上架商品
*/
@NotNull(message = "是否上架商品不能为空")
private Integer visible;
/**
* 排序字段
*/
@NotNull(message = "排序字段不能为空")
private Integer sort;
/**
* 价格
*/
@NotNull(message = "价格不能为空")
private Integer price;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空")
private Integer quantity;
}

View File

@ -0,0 +1,46 @@
package cn.iocoder.mall.productservice.convert.spu;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSpuDO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuCreateBO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuPageBO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuUpdateBO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface ProductSpuConvert {
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
ProductSpuDO convert(ProductSpuCreateBO bean);
ProductSpuBO convert(ProductSpuDO bean);
ProductSpuDO convert(ProductSpuUpdateBO bean);
List<ProductSpuBO> convertList(List<ProductSpuDO> list);
PageResult<ProductSpuBO> convertPage(IPage<ProductSpuDO> page);
ProductSpuCreateBO convert(ProductSpuCreateReqDTO bean);
ProductSpuUpdateBO convert(ProductSpuUpdateReqDTO bean);
ProductSpuRespDTO convert(ProductSpuBO bean);
List<ProductSpuRespDTO> convertList02(List<ProductSpuBO> list);
ProductSpuPageBO convert(ProductSpuPageReqDTO bean);
PageResult<ProductSpuRespDTO> convertPage(PageResult<ProductSpuBO> page);
}

View File

@ -1,7 +1,6 @@
package cn.iocoder.mall.product.biz.dataobject.spu;
package cn.iocoder.mall.productservice.dal.mysql.dataobject.spu;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import cn.iocoder.mall.product.biz.dataobject.attr.ProductAttrDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

View File

@ -1,7 +1,8 @@
package cn.iocoder.mall.product.biz.dataobject.spu;
package cn.iocoder.mall.productservice.dal.mysql.dataobject.spu;
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
@ -10,6 +11,7 @@ import lombok.experimental.Accessors;
* TODO 芋艿后面增加商品普通参数例如说正面材料背面材料屏幕尺寸
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductSpuDO extends DeletableDO {

View File

@ -0,0 +1,27 @@
package cn.iocoder.mall.productservice.dal.mysql.mapper.spu;
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSpuDO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuPageBO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductSpuMapper extends BaseMapper<ProductSpuDO> {
default IPage<ProductSpuDO> selectPage(ProductSpuPageBO pageBO) {
QueryWrapperX<ProductSpuDO> query = new QueryWrapperX<ProductSpuDO>().likeIfPresent("name", pageBO.getName());
// 库存过滤
if (pageBO.getHasQuantity() != null) {
if (pageBO.getHasQuantity()) {
query.gt("quantity", 0);
} else {
query.eq("quantity", 0);
}
}
return selectPage(new Page<>(pageBO.getPageNo(), pageBO.getPageSize()), query);
}
}

View File

@ -0,0 +1,77 @@
package cn.iocoder.mall.productservice.manager.spu;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.convert.spu.ProductSpuConvert;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
import cn.iocoder.mall.productservice.service.spu.ProductSpuService;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 商品 SPU Manager
*/
@Service
public class ProductSpuManager {
@Autowired
private ProductSpuService productSpuService;
/**
* 创建商品 SPU
*
* @param createDTO 创建商品 SPU DTO
* @return 商品 SPU
*/
public Integer createProductSpu(ProductSpuCreateReqDTO createDTO) {
ProductSpuBO productSpuBO = productSpuService.createProductSpu(ProductSpuConvert.INSTANCE.convert(createDTO));
return productSpuBO.getId();
}
/**
* 更新商品 SPU
*
* @param updateDTO 更新商品 SPU DTO
*/
public void updateProductSpu(ProductSpuUpdateReqDTO updateDTO) {
productSpuService.updateProductSpu(ProductSpuConvert.INSTANCE.convert(updateDTO));
}
/**
* 获得商品 SPU
*
* @param productSpuId 商品 SPU编号
* @return 商品 SPU
*/
public ProductSpuRespDTO getProductSpu(Integer productSpuId) {
ProductSpuBO productSpuBO = productSpuService.getProductSpu(productSpuId);
return ProductSpuConvert.INSTANCE.convert(productSpuBO);
}
/**
* 获得商品 SPU列表
*
* @param productSpuIds 商品 SPU编号列表
* @return 商品 SPU列表
*/
public List<ProductSpuRespDTO> listProductSpus(List<Integer> productSpuIds) {
List<ProductSpuBO> productSpuBOs = productSpuService.listProductSpus(productSpuIds);
return ProductSpuConvert.INSTANCE.convertList02(productSpuBOs);
}
/**
* 获得商品 SPU分页
*
* @param pageDTO 商品 SPU分页查询
* @return 商品 SPU分页结果
*/
public PageResult<ProductSpuRespDTO> pageProductSpu(ProductSpuPageReqDTO pageDTO) {
PageResult<ProductSpuBO> pageResultBO = productSpuService.pageProductSpu(ProductSpuConvert.INSTANCE.convert(pageDTO));
return ProductSpuConvert.INSTANCE.convertPage(pageResultBO);
}
}

View File

@ -0,0 +1,52 @@
package cn.iocoder.mall.productservice.rpc.spu;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.manager.spu.ProductSpuManager;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuCreateReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuUpdateReqDTO;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import static cn.iocoder.common.framework.vo.CommonResult.success;
/**
* 商品 SPU Rpc 实现类
*/
@Service(version = "${dubbo.provider.ProductSpuRpc.version}")
public class ProductSpuRpcImpl implements ProductSpuRpc {
@Autowired
private ProductSpuManager productSpuManager;
@Override
public CommonResult<Integer> createProductSpu(ProductSpuCreateReqDTO createDTO) {
return success(productSpuManager.createProductSpu(createDTO));
}
@Override
public CommonResult<Boolean> updateProductSpu(ProductSpuUpdateReqDTO updateDTO) {
productSpuManager.updateProductSpu(updateDTO);
return success(true);
}
@Override
public CommonResult<ProductSpuRespDTO> getProductSpu(Integer productSpuId) {
return success(productSpuManager.getProductSpu(productSpuId));
}
@Override
public CommonResult<List<ProductSpuRespDTO>> listProductSpus(List<Integer> productSpuIds) {
return success(productSpuManager.listProductSpus(productSpuIds));
}
@Override
public CommonResult<PageResult<ProductSpuRespDTO>> pageProductSpu(ProductSpuPageReqDTO pageDTO) {
return success(productSpuManager.pageProductSpu(pageDTO));
}
}

View File

@ -0,0 +1,94 @@
package cn.iocoder.mall.productservice.service.spu;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.convert.spu.ProductSpuConvert;
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSpuDO;
import cn.iocoder.mall.productservice.dal.mysql.mapper.spu.ProductSpuMapper;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuCreateBO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuPageBO;
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuUpdateBO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.mall.productservice.enums.ProductErrorCodeConstants.PRODUCT_SPU_NOT_EXISTS;
/**
* 商品 SPU Service
*/
@Service
@Validated
public class ProductSpuService {
@Autowired
private ProductSpuMapper productSpuMapper;
/**
* 创建商品 SPU
*
* @param createBO 创建商品 SPU BO
* @return 商品 SPU
*/
public ProductSpuBO createProductSpu(@Valid ProductSpuCreateBO createBO) {
// 插入到数据库
ProductSpuDO productSpuDO = ProductSpuConvert.INSTANCE.convert(createBO);
productSpuMapper.insert(productSpuDO);
// 返回
return ProductSpuConvert.INSTANCE.convert(productSpuDO);
}
/**
* 更新商品 SPU
*
* @param updateBO 更新商品 SPU BO
*/
public void updateProductSpu(@Valid ProductSpuUpdateBO updateBO) {
// 校验更新的商品 SPU是否存在
if (productSpuMapper.selectById(updateBO.getId()) == null) {
throw ServiceExceptionUtil.exception(PRODUCT_SPU_NOT_EXISTS);
}
// 更新到数据库
ProductSpuDO updateObject = ProductSpuConvert.INSTANCE.convert(updateBO);
productSpuMapper.updateById(updateObject);
}
/**
* 获得商品 SPU
*
* @param productSpuId 商品 SPU编号
* @return 商品 SPU
*/
public ProductSpuBO getProductSpu(Integer productSpuId) {
ProductSpuDO productSpuDO = productSpuMapper.selectById(productSpuId);
return ProductSpuConvert.INSTANCE.convert(productSpuDO);
}
/**
* 获得商品 SPU列表
*
* @param productSpuIds 商品 SPU编号列表
* @return 商品 SPU列表
*/
public List<ProductSpuBO> listProductSpus(List<Integer> productSpuIds) {
List<ProductSpuDO> productSpuDOs = productSpuMapper.selectBatchIds(productSpuIds);
return ProductSpuConvert.INSTANCE.convertList(productSpuDOs);
}
/**
* 获得商品 SPU分页
*
* @param pageBO 商品 SPU分页查询
* @return 商品 SPU分页结果
*/
public PageResult<ProductSpuBO> pageProductSpu(ProductSpuPageBO pageBO) {
IPage<ProductSpuDO> productSpuDOPage = productSpuMapper.selectPage(pageBO);
return ProductSpuConvert.INSTANCE.convertPage(productSpuDOPage);
}
}

View File

@ -0,0 +1,61 @@
package cn.iocoder.mall.productservice.service.spu.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
/**
* 商品 SPU 信息 BO
*/
@Data
@Accessors(chain = true)
public class ProductSpuBO {
/**
* 商品 SPU 编号
*/
private Integer id;
/**
* SPU 名字
*/
private String name;
/**
* 卖点
*/
private String sellPoint;
/**
* 描述
*/
private String description;
/**
* 分类编号
*/
private Integer cid;
/**
* 商品主图地址
*/
private List<String> picUrls;
/**
* 是否上架商品
*/
private Integer visible;
/**
* 排序字段
*/
private Integer sort;
/**
* 价格
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
/**
* 创建时间
*/
private Date createTime;
}

View File

@ -0,0 +1,63 @@
package cn.iocoder.mall.productservice.service.spu.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU 创建 BO
*/
@Data
@Accessors(chain = true)
public class ProductSpuCreateBO {
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
/**
* 是否上架商品
*/
@NotNull(message = "是否上架商品不能为空")
private Integer visible;
/**
* 排序字段
*/
@NotNull(message = "排序字段不能为空")
private Integer sort;
/**
* 价格
*/
@NotNull(message = "价格不能为空")
private Integer price;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空")
private Integer quantity;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.mall.productservice.service.spu.bo;
import cn.iocoder.common.framework.vo.PageParam;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 商品 SPU 分页 BO
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductSpuPageBO extends PageParam {
/**
* SPU 名字
*/
private String name;
/**
* 是否有库存
*/
private Boolean hasQuantity;
}

View File

@ -0,0 +1,68 @@
package cn.iocoder.mall.productservice.service.spu.bo;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU 更新 BO
*/
@Data
@Accessors(chain = true)
public class ProductSpuUpdateBO {
/**
* 商品 SPU 编号
*/
@NotNull(message = "商品 SPU 编号不能为空")
private Integer id;
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类编号不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotEmpty(message = "商品主图地址不能为空")
private List<String> picUrls;
/**
* 是否上架商品
*/
@NotNull(message = "是否上架商品不能为空")
private Integer visible;
/**
* 排序字段
*/
@NotNull(message = "排序字段不能为空")
private Integer sort;
/**
* 价格
*/
@NotNull(message = "价格不能为空")
private Integer price;
/**
* 库存数量
*/
@NotNull(message = "库存数量不能为空")
private Integer quantity;
}

View File

@ -38,6 +38,8 @@ dubbo:
version: 1.0.0
ProductBrandRpc:
version: 1.0.0
ProductSpuRpc:
version: 1.0.0
# Dubbo 服务消费者的配置
consumer:
ErrorCodeRpc:

View File

@ -14,13 +14,10 @@
<packaging>pom</packaging>
<modules>
<module>product-application</module>
<module>product-rpc-api</module>
<module>product-rpc</module>
<module>product-rest</module>
<module>product-biz</module>
<module>product-biz-api</module>
<module>product-mq</module>
</modules>
<dependencyManagement>

View File

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

View File

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

View File

@ -1,37 +0,0 @@
package cn.iocoder.mall.product.application.controller.users;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.product.api.ProductCategoryService;
import cn.iocoder.mall.product.api.bo.ProductCategoryBO;
import cn.iocoder.mall.product.application.convert.ProductCategoryConvert;
import cn.iocoder.mall.product.application.vo.users.UsersProductCategoryVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
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 java.util.List;
@RestController
@RequestMapping("users/category")
@Api("商品分类")
public class UsersProductCategoryController {
@Reference(validation = "true", version = "${dubbo.provider.ProductCategoryService.version}")
@Autowired
private ProductCategoryService productCategoryService;
@GetMapping("/list")
@ApiOperation("获得指定编号下的子分类的数组")
@ApiImplicitParam(name = "pid", value = "指定分类编号", required = true, example = "0")
public CommonResult<List<UsersProductCategoryVO>> list(@RequestParam("pid") Integer pid) {
List<ProductCategoryBO> result = productCategoryService.getListByPid(pid);
return CommonResult.success(ProductCategoryConvert.Users.INSTANCE.convertToVO(result));
}
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.mall.product.application.vo.users;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
@ApiModel("商品分类(简单)")
@Data
@Accessors(chain = true)
public class UsersProductCategoryVO {
@ApiModelProperty(value = "分类编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "分类名", required = true, example = "手机")
private String name;
@ApiModelProperty(value = "分类图片", notes = "一般情况下,只有根分类才有图片", example = "http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
private String picUrl;
}