diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java index ca21069fd..a14c331d2 100644 --- a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java @@ -82,7 +82,7 @@ public class AdminController { @GetMapping("/page") @ApiOperation(value = "管理员分页") @ApiImplicitParams({ - @ApiImplicitParam(name = "nickname", value = "昵称,模糊匹配", required = true, example = "小王"), + @ApiImplicitParam(name = "nickname", value = "昵称,模糊匹配", example = "小王"), @ApiImplicitParam(name = "pageNo", value = "页码,从 0 开始", example = "0"), @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"), }) diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/AdminPageDTO.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/AdminPageDTO.java index 959a3babe..d1e89acef 100644 --- a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/AdminPageDTO.java +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/AdminPageDTO.java @@ -1,10 +1,14 @@ package cn.iocoder.mall.admin.api.dto; +import javax.validation.constraints.NotNull; + public class AdminPageDTO { private String nickname; + @NotNull(message = "页码不能为空") private Integer pageNo; + @NotNull(message = "每页条数不能为空") private Integer pageSize; public Integer getPageNo() { diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/StringUtil.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/StringUtil.java index 05292a919..8e98169ed 100644 --- a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/StringUtil.java +++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/StringUtil.java @@ -2,6 +2,7 @@ package cn.iocoder.common.framework.util; import org.springframework.util.StringUtils; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -17,4 +18,13 @@ public class StringUtil { return Arrays.asList(stringArray); } + public static List splitToInt(String toSplit, String delim) { + String[] stringArray = StringUtils.tokenizeToStringArray(toSplit, delim); + List array = new ArrayList<>(stringArray.length); + for (String string : stringArray) { + array.add(Integer.valueOf(string)); + } + return array; + } + } \ No newline at end of file diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java index a6eba1d27..0c64f6dab 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductSpuController.java @@ -4,9 +4,10 @@ import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder; import cn.iocoder.mall.product.api.ProductSpuService; import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO; -import cn.iocoder.mall.product.api.dto.ProductSkuAddDTO; -import cn.iocoder.mall.product.api.dto.ProductSkuUpdateDTO; +import cn.iocoder.mall.product.api.bo.ProductSpuPageBO; +import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO; import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO; +import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO; import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO; import cn.iocoder.mall.product.application.convert.ProductSpuConvert; import cn.iocoder.mall.product.application.vo.admins.AdminsProductSpuDetailVO; @@ -57,7 +58,7 @@ public class AdminsProductSpuController { // 创建 ProductSpuAddDTO 对象 ProductSpuAddDTO productSpuAddDTO = new ProductSpuAddDTO().setName(name).setSellPoint(sellPoint) .setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible) - .setSkus(parseSkus(skuStr, ProductSkuAddDTO.class)); + .setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class)); // 保存商品 CommonResult result = productSpuService.addProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuAddDTO); // 返回结果 @@ -88,7 +89,7 @@ public class AdminsProductSpuController { // 创建 ProductSpuUpdateDTO 对象 ProductSpuUpdateDTO productSpuUpdateDTO = new ProductSpuUpdateDTO().setId(id).setName(name).setSellPoint(sellPoint) .setDescription(description).setCid(cid).setPicUrls(picUrls).setVisible(visible) - .setSkus(parseSkus(skuStr, ProductSkuUpdateDTO.class)); + .setSkus(parseSkus(skuStr, ProductSkuAddOrUpdateDTO.class)); // 更新商品 return productSpuService.updateProductSpu(AdminSecurityContextHolder.getContext().getAdminId(), productSpuUpdateDTO); } @@ -97,19 +98,32 @@ public class AdminsProductSpuController { @ApiOperation("更新商品的排序") public CommonResult updateSort(@RequestParam("id") Integer id, @RequestParam("sort") Integer sort) { - return null; + return productSpuService.updateProductSpuSort(AdminSecurityContextHolder.getContext().getAdminId(), id, sort); } + // TODO 芋艿,删除功能暂时不做。主要原因是,关联的数据太多。删除带来的问题会比较大 + @GetMapping("/spu/page") @ApiOperation("商品 SPU 分页列表") - public CommonResult spuPage() { - return null; + @ApiImplicitParams({ + @ApiImplicitParam(name = "name", value = "商品名称,模糊匹配", example = "小王"), + @ApiImplicitParam(name = "pageNo", value = "页码,从 0 开始", example = "0"), + @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"), + }) + public CommonResult spuPage(@RequestParam(value = "name", required = false) String name, + @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { + // 创建 ProductSpuPageDTO 对象 + ProductSpuPageDTO productSpuPageDTO = new ProductSpuPageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize); + CommonResult result = productSpuService.getProductSpuPage(productSpuPageDTO); + return ProductSpuConvert.INSTANCE.convert2(result); } @GetMapping("/spu/info") @ApiOperation("商品 SPU 明细") - public CommonResult info() { - return null; + @ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100") + public CommonResult info(@RequestParam("id") Integer id) { + return ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpu(id)); } private List parseSkus(String skuStr, Class clazz) { diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/ProductSpuController.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/ProductSpuController.java index ac88a885a..44162ced1 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/ProductSpuController.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/controller/users/ProductSpuController.java @@ -19,7 +19,8 @@ public class ProductSpuController { // TODO 详情 @GetMapping("/info") public ProductSpuBO info(@RequestParam("id") Integer id) { - return productSpuService.getProductSpu(id); +// return productSpuService.getProductSpu(id); + return null; } // TODO 分页 diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java index d734a1aa3..590e6ae66 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/convert/ProductSpuConvert.java @@ -2,7 +2,9 @@ package cn.iocoder.mall.product.application.convert; import cn.iocoder.common.framework.vo.CommonResult; 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 org.mapstruct.Mapper; import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; @@ -18,4 +20,7 @@ public interface ProductSpuConvert { @Mappings({}) CommonResult convert(CommonResult result); + @Mappings({}) + CommonResult convert2(CommonResult result); + } \ No newline at end of file diff --git a/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java b/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java index b36f6b789..78c92406c 100644 --- a/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java +++ b/product/product-application/src/main/java/cn/iocoder/mall/product/application/vo/admins/AdminsProductSpuVO.java @@ -1,10 +1,104 @@ package cn.iocoder.mall.product.application.vo.admins; import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; @ApiModel(value = "商品 SPU VO", description = "不包括 SKU 信息 VO") public class AdminsProductSpuVO { + @ApiModelProperty(value = "SPU 编号", required = true, example = "1") + private Integer id; + // ========== 基本信息 ========= + @ApiModelProperty(value = "SPU 名字", required = true, example = "厮大牛逼") + private String name; + @ApiModelProperty(value = "卖点", required = true, example = "各种 MQ 骚操作") + private String sellPoint; + @ApiModelProperty(value = "描述", required = true, example = "你就说强不强") + private String description; + @ApiModelProperty(value = "分类编号", required = true, example = "反正我是信了") + private Integer cid; + @ApiModelProperty(value = "商品主图地址的数组", required = true, example = "http://www.iocoder.cn") + private List picUrls; + + // ========== 其他信息 ========= + @ApiModelProperty(value = "是否上架商品(是否可见)", required = true, example = "true") + private Boolean visible; + @ApiModelProperty(value = "排序字段", required = true, example = "10") + private Integer sort; + + public Integer getId() { + return id; + } + + public AdminsProductSpuVO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public AdminsProductSpuVO setName(String name) { + this.name = name; + return this; + } + + public String getSellPoint() { + return sellPoint; + } + + public AdminsProductSpuVO setSellPoint(String sellPoint) { + this.sellPoint = sellPoint; + return this; + } + + public String getDescription() { + return description; + } + + public AdminsProductSpuVO setDescription(String description) { + this.description = description; + return this; + } + + public Integer getCid() { + return cid; + } + + public AdminsProductSpuVO setCid(Integer cid) { + this.cid = cid; + return this; + } + + public List getPicUrls() { + return picUrls; + } + + public AdminsProductSpuVO setPicUrls(List picUrls) { + this.picUrls = picUrls; + return this; + } + + public Boolean getVisible() { + return visible; + } + + public AdminsProductSpuVO setVisible(Boolean visible) { + this.visible = visible; + return this; + } + + public Integer getSort() { + return sort; + } + + public AdminsProductSpuVO setSort(Integer sort) { + this.sort = sort; + return this; + } } \ No newline at end of file diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java index 17256f3d6..845a7b1c4 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/ProductSpuService.java @@ -1,19 +1,22 @@ package cn.iocoder.mall.product.api; import cn.iocoder.common.framework.vo.CommonResult; -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.ProductSpuAddDTO; +import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO; import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO; public interface ProductSpuService { - ProductSpuBO getProductSpu(Integer id); + CommonResult getProductSpu(Integer id); CommonResult addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO); CommonResult updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO); + CommonResult updateProductSpuSort(Integer adminId, Integer spuId, Integer sort); + CommonResult getProductSpuPage(ProductSpuPageDTO productSpuPageDTO); -} +} \ No newline at end of file diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java index 7ae0a87bf..b77874859 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java @@ -1,15 +1,123 @@ package cn.iocoder.mall.product.api.bo; +import java.util.List; + public class ProductSpuBO { + /** + * SPU 编号 + */ private Integer id; + // ========== 基本信息 ========= + /** + * SPU 名字 + */ + private String name; + /** + * 卖点 + */ + private String sellPoint; + /** + * 描述 + */ + private String description; + /** + * 分类编号 + */ + private Integer cid; + /** + * 商品主图地址 + * + * 数组,以逗号分隔 + * + * 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张 + */ + private List picUrls; + + // ========== 其他信息 ========= + /** + * 是否上架商品(是否可见)。 + * + * true 为已上架 + * false 为已下架 + */ + private Boolean visible; + /** + * 排序字段 + */ + private Integer sort; + public Integer getId() { return id; } - public void setId(Integer id) { + public ProductSpuBO setId(Integer id) { this.id = id; + return this; + } + + public String getName() { + return name; + } + + public ProductSpuBO setName(String name) { + this.name = name; + return this; + } + + public String getSellPoint() { + return sellPoint; + } + + public ProductSpuBO setSellPoint(String sellPoint) { + this.sellPoint = sellPoint; + return this; + } + + public String getDescription() { + return description; + } + + public ProductSpuBO setDescription(String description) { + this.description = description; + return this; + } + + public Integer getCid() { + return cid; + } + + public ProductSpuBO setCid(Integer cid) { + this.cid = cid; + return this; + } + + public List getPicUrls() { + return picUrls; + } + + public ProductSpuBO setPicUrls(List picUrls) { + this.picUrls = picUrls; + return this; + } + + public Boolean getVisible() { + return visible; + } + + public ProductSpuBO setVisible(Boolean visible) { + this.visible = visible; + return this; + } + + public Integer getSort() { + return sort; + } + + public ProductSpuBO setSort(Integer sort) { + this.sort = sort; + return this; } } \ No newline at end of file diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java new file mode 100644 index 000000000..89ca0756d --- /dev/null +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java @@ -0,0 +1,34 @@ +package cn.iocoder.mall.product.api.bo; + +import java.util.List; + +public class ProductSpuPageBO { + + /** + * Spu 数组 + */ + private List spus; + /** + * 总量 + */ + private Integer count; + + public List getSpus() { + return spus; + } + + public ProductSpuPageBO setSpus(List spus) { + this.spus = spus; + return this; + } + + public Integer getCount() { + return count; + } + + public ProductSpuPageBO setCount(Integer count) { + this.count = count; + return this; + } + +} \ No newline at end of file diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuAddDTO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuAddOrUpdateDTO.java similarity index 54% rename from product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuAddDTO.java rename to product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuAddOrUpdateDTO.java index d3986ccac..3c6bbffc8 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuAddDTO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuAddOrUpdateDTO.java @@ -1,30 +1,37 @@ package cn.iocoder.mall.product.api.dto; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; import java.util.List; /** * 商品 Sku 添加 DTO */ -public class ProductSkuAddDTO { +public class ProductSkuAddOrUpdateDTO { /** * 规格值数组 */ + @NotNull(message = "规格值数组不能为空") private List attrs; /** * 价格,单位:分 */ + @NotNull(message = "价格不能为空") + @Min(value = 1L, message = "最小价格为 1") private Integer price; /** * 库存数量 */ + @NotNull(message = "库存数量不能为空") + @Min(value = 1L, message = "最小库存为 1") private Integer quantity; public List getAttrs() { return attrs; } - public ProductSkuAddDTO setAttrs(List attrs) { + public ProductSkuAddOrUpdateDTO setAttrs(List attrs) { this.attrs = attrs; return this; } @@ -33,7 +40,7 @@ public class ProductSkuAddDTO { return price; } - public ProductSkuAddDTO setPrice(Integer price) { + public ProductSkuAddOrUpdateDTO setPrice(Integer price) { this.price = price; return this; } @@ -42,7 +49,7 @@ public class ProductSkuAddDTO { return quantity; } - public ProductSkuAddDTO setQuantity(Integer quantity) { + public ProductSkuAddOrUpdateDTO setQuantity(Integer quantity) { this.quantity = quantity; return this; } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuUpdateDTO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuUpdateDTO.java deleted file mode 100644 index f11ad3707..000000000 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSkuUpdateDTO.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.mall.product.api.dto; - -import java.util.List; - -/** - * 商品 Sku 更新 DTO - */ -public class ProductSkuUpdateDTO { - - /** - * 规格值数组 - */ - private List attrs; - /** - * 价格,单位:分 - */ - private Integer price; - /** - * 库存数量 - */ - private Integer quantity; - - public List getAttrs() { - return attrs; - } - - public ProductSkuUpdateDTO setAttrs(List attrs) { - this.attrs = attrs; - return this; - } - - public Integer getPrice() { - return price; - } - - public ProductSkuUpdateDTO setPrice(Integer price) { - this.price = price; - return this; - } - - public Integer getQuantity() { - return quantity; - } - - public ProductSkuUpdateDTO setQuantity(Integer quantity) { - this.quantity = quantity; - return this; - } - -} \ No newline at end of file diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuAddDTO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuAddDTO.java index 948c60a02..86c650db1 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuAddDTO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuAddDTO.java @@ -52,7 +52,7 @@ public class ProductSpuAddDTO { * SKU 数组 */ @NotNull(message = "SKU 不能为空") - private List skus; + private List skus; public String getName() { return name; @@ -108,11 +108,11 @@ public class ProductSpuAddDTO { return this; } - public List getSkus() { + public List getSkus() { return skus; } - public ProductSpuAddDTO setSkus(List skus) { + public ProductSpuAddDTO setSkus(List skus) { this.skus = skus; return this; } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuPageDTO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuPageDTO.java new file mode 100644 index 000000000..b325904ee --- /dev/null +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuPageDTO.java @@ -0,0 +1,41 @@ +package cn.iocoder.mall.product.api.dto; + +import javax.validation.constraints.NotNull; + +public class ProductSpuPageDTO { + + private String name; + + @NotNull(message = "页码不能为空") + private Integer pageNo; + @NotNull(message = "每页条数不能为空") + private Integer pageSize; + + public String getName() { + return name; + } + + public ProductSpuPageDTO setName(String name) { + this.name = name; + return this; + } + + public Integer getPageNo() { + return pageNo; + } + + public ProductSpuPageDTO setPageNo(Integer pageNo) { + this.pageNo = pageNo; + return this; + } + + public Integer getPageSize() { + return pageSize; + } + + public ProductSpuPageDTO setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + +} \ No newline at end of file diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java index 4021f7fb0..7847ed61b 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/dto/ProductSpuUpdateDTO.java @@ -58,7 +58,7 @@ public class ProductSpuUpdateDTO { * SKU 数组 */ @NotNull(message = "SKU 不能为空") - private List skus; + private List skus; public String getName() { return name; @@ -114,11 +114,11 @@ public class ProductSpuUpdateDTO { return this; } - public List getSkus() { + public List getSkus() { return skus; } - public ProductSpuUpdateDTO setSkus(List skus) { + public ProductSpuUpdateDTO setSkus(List skus) { this.skus = skus; return this; } diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/convert/ProductSpuConvert.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/convert/ProductSpuConvert.java index a016b3444..4935dafe4 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/convert/ProductSpuConvert.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/convert/ProductSpuConvert.java @@ -5,8 +5,7 @@ import cn.iocoder.mall.product.api.bo.ProductAttrDetailBO; import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO; import cn.iocoder.mall.product.api.bo.ProductSpuBO; import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO; -import cn.iocoder.mall.product.api.dto.ProductSkuAddDTO; -import cn.iocoder.mall.product.api.dto.ProductSkuUpdateDTO; +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.ProductSkuDO; @@ -14,6 +13,7 @@ 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; @@ -26,9 +26,14 @@ public interface ProductSpuConvert { ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class); - @Mappings({}) + @Mappings({ + @Mapping(source = "picUrls", target = "picUrls", qualifiedByName = "translatePicUrlsFromString") + }) ProductSpuBO convert(ProductSpuDO spu); + @Mappings({}) + List convert(List spus); + @Mappings({ @Mapping(source = "picUrls", target = "picUrls", ignore = true) }) @@ -37,7 +42,7 @@ public interface ProductSpuConvert { @Mappings({ @Mapping(source = "attrs", target = "attrs", ignore = true) }) - ProductSkuDO convert(ProductSkuAddDTO productSkuAddDTO); + ProductSkuDO convert(ProductSkuAddOrUpdateDTO productSkuAddDTO); @Mappings({ @@ -45,11 +50,6 @@ public interface ProductSpuConvert { }) ProductSpuDO convert(ProductSpuUpdateDTO productSpuUpdateDTO); - @Mappings({ - @Mapping(source = "attrs", target = "attrs", ignore = true) - }) - ProductSkuDO convert(ProductSkuUpdateDTO productSkuUpdateDTO); - @Mappings({}) ProductSpuDetailBO convert(ProductSpuBO spu); @@ -85,4 +85,9 @@ public interface ProductSpuConvert { return spuDetail; } + @Named("translatePicUrlsFromString") + default List translatePicUrlsFromString(String picUrls) { + return StringUtil.split(picUrls, ","); + } + } \ No newline at end of file diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java index b5c5d02dd..acb590d8d 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java @@ -1,8 +1,11 @@ package cn.iocoder.mall.product.dao; import cn.iocoder.mall.product.dataobject.ProductSpuDO; +import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface ProductSpuMapper { @@ -12,4 +15,10 @@ public interface ProductSpuMapper { void update(ProductSpuDO productSpuDO); + List selectListByNameLikeOrderBySortAsc(@Param("name") String name, + @Param("offset") Integer offset, + @Param("limit") Integer limit); + + Integer selectCountByNameLike(@Param("name") String name); + } \ No newline at end of file diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java index e64d9949f..82906c340 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dataobject/ProductSpuDO.java @@ -61,8 +61,9 @@ public class ProductSpuDO extends BaseDO { return id; } - public void setId(Integer id) { + public ProductSpuDO setId(Integer id) { this.id = id; + return this; } public String getName() { @@ -127,7 +128,4 @@ public class ProductSpuDO extends BaseDO { this.sort = sort; return this; } - - - } \ No newline at end of file diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java index 9bf868b21..145d32041 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuServiceImpl.java @@ -7,13 +7,13 @@ import cn.iocoder.common.framework.util.StringUtil; import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.product.api.ProductSpuService; import cn.iocoder.mall.product.api.bo.ProductAttrDetailBO; -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.constant.ProductErrorCodeEnum; import cn.iocoder.mall.product.api.constant.ProductSpuConstants; -import cn.iocoder.mall.product.api.dto.ProductSkuAddDTO; -import cn.iocoder.mall.product.api.dto.ProductSkuUpdateDTO; +import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO; import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO; +import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO; import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO; import cn.iocoder.mall.product.convert.ProductSpuConvert; import cn.iocoder.mall.product.dao.ProductSkuMapper; @@ -42,11 +42,31 @@ public class ProductSpuServiceImpl implements ProductSpuService { @Autowired private ProductAttrServiceImpl productAttrService; +// @Override +// public ProductSpuBO getProductSpu(Integer id) { +// ProductSpuDO productSpuDO = productSpuMapper.selectById(id); +// // 转换成 BO +// return ProductSpuConvert.INSTANCE.convert(productSpuDO); +// } + @Override - public ProductSpuBO getProductSpu(Integer id) { - ProductSpuDO productSpuDO = productSpuMapper.selectById(id); - // 转换成 BO - return ProductSpuConvert.INSTANCE.convert(productSpuDO); + public CommonResult getProductSpu(Integer id) { + // 校验商品 spu 存在 + ProductSpuDO spu = productSpuMapper.selectById(id); + if (spu == null) { + return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); + } + // 获得商品 sku 数组 + List skus = productSkuMapper.selectListBySpuIdAndStatus(id, ProductSpuConstants.SKU_STATUS_ENABLE); + // 获得规格 + Set productAttrValueIds = new HashSet<>(); + skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ","))); + CommonResult> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds); + if (validAttrResult.isError()) { + return CommonResult.error(validAttrResult); + } + // 返回成功 + return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData())); } @SuppressWarnings("Duplicates") @@ -110,6 +130,11 @@ public class ProductSpuServiceImpl implements ProductSpuService { if (validAttrResult.isError()) { return CommonResult.error(validAttrResult); } + // 校验 Sku 规格 + CommonResult validProductSkuResult = validProductSku(productSpuUpdateDTO.getSkus(), validAttrResult.getData()); + if (validProductSkuResult.isError()) { + return CommonResult.error(validProductSkuResult); + } // 更新 Spu ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO) .setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ",")); @@ -119,7 +144,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { List insertSkus = new ArrayList<>(0); // 1、找不到,进行插入 List deleteSkus = new ArrayList<>(0); // 2、多余的,删除 List updateSkus = new ArrayList<>(0); // 3、找的到,进行更新。 - for (ProductSkuUpdateDTO skuUpdateDTO : productSpuUpdateDTO.getSkus()) { + for (ProductSkuAddOrUpdateDTO skuUpdateDTO : productSpuUpdateDTO.getSkus()) { ProductSkuDO existsSku = findProductSku(skuUpdateDTO.getAttrs(), existsSkus); // 3、找的到,进行更新。 if (existsSku != null) { @@ -149,19 +174,41 @@ public class ProductSpuServiceImpl implements ProductSpuService { if (!deleteSkus.isEmpty()) { productSkuMapper.updateToDeleted(deleteSkus); } -// if (true) { -// throw new RuntimeException("test"); -// } - // 校验 Sku 规格 return CommonResult.success(true); } - private CommonResult validProductSku(List productSkuAddDTOs, List productAttrDetailBOs) { + @Override + public CommonResult updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) { + // 校验 Spu 是否存在 + if (productSpuMapper.selectById(spuId) == null) { + return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode()); + } + // 更新排序 + ProductSpuDO updateSpu = new ProductSpuDO().setId(spuId).setSort(sort); + productSpuMapper.update(updateSpu); + // 返回成功 + return CommonResult.success(true); + } + + @Override + public CommonResult getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) { + ProductSpuPageBO productSpuPage = new ProductSpuPageBO(); + // 查询分页数据 + int offset = productSpuPageDTO.getPageNo() * productSpuPageDTO.getPageSize(); + productSpuPage.setSpus(ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectListByNameLikeOrderBySortAsc(productSpuPageDTO.getName(), + offset, productSpuPageDTO.getPageSize()))); + // 查询分页总数 + productSpuPage.setCount(productSpuMapper.selectCountByNameLike(productSpuPageDTO.getName())); + // 返回结果 + return CommonResult.success(productSpuPage); + } + + private CommonResult validProductSku(List productSkuAddDTOs, List productAttrDetailBOs) { // 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号 Map productAttrDetailBOMap = productAttrDetailBOs.stream().collect( Collectors.toMap(ProductAttrDetailBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO)); // 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId - for (ProductSkuAddDTO sku : productSkuAddDTOs) { + for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) { Set attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId()).collect(Collectors.toSet()); if (attrIds.size() != sku.getAttrs().size()) { return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE.getCode()); @@ -176,7 +223,7 @@ public class ProductSpuServiceImpl implements ProductSpuService { } // 3. 最后校验,每个 Sku 之间不是重复的 Set> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的. - for (ProductSkuAddDTO sku : productSkuAddDTOs) { + for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) { if (!skuAttrValues.add(new HashSet<>(sku.getAttrs()))) { // 添加失败,说明重复 return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_SKU__NOT_DUPLICATE.getCode()); } diff --git a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml index d5b04aa49..2389a1634 100644 --- a/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml +++ b/product/product-service-impl/src/main/resources/mapper/ProductSpuMapper.xml @@ -2,11 +2,17 @@ + + id, name, sell_point, description, cid, + pic_urls, visible, sort, create_time + + @@ -50,4 +56,30 @@ WHERE id = #{id} + + + + \ No newline at end of file