From 8818b350d6c7c44efbd5d9cc8f03f722f4c6dfb8 Mon Sep 17 00:00:00 2001 From: YunaiV <> Date: Sat, 15 Aug 2020 15:37:53 +0800 Subject: [PATCH] =?UTF-8?q?Price=20=E4=BB=B7=E6=A0=BC=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9A=84=E7=BC=96=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rpc/sku/dto/ProductSkuRespDTO.java | 17 +++++ .../product-service-app/pom.xml | 7 ++ .../convert/sku/ProductSkuConvert.java | 32 ++++++++- .../convert/spu/ProductSpuConvert.java | 12 ++-- .../manager/sku/ProductSkuManager.java | 32 +++++++-- .../manager/spu/ProductSpuManager.java | 6 +- .../manager/spu/ProductSkuManagerTest.java | 34 +++++++++ .../mall/productservice/package-info.java | 1 + .../rpc/activity/PromotionActivityRpc.java | 21 +++--- .../dto/PromotionActivityListReqDTO.java | 21 ++++++ .../dto/PromotionActivityRespDTO.java | 2 +- .../rpc/price/dto/PriceProductCalcReqDTO.java | 10 ++- .../price/dto/PriceProductCalcRespDTO.java | 12 +++- .../activity/PromotionActivityMapper.java | 6 ++ .../activity/PromotionActivityManager.java | 26 +++++++ .../manager/package-info.java | 1 - .../manager/price/PriceManager.java | 15 ++-- .../activity/PromotionActivityRpcImpl.java | 26 +++++++ .../promotionservice/rpc/package-info.java | 1 - .../activity/PromotionActivityService.java | 20 ++---- .../recommend/ProductRecommendService.java | 4 +- .../controller/order/CartController.java | 2 +- .../shopweb/convert/order/CartConvert.java | 7 ++ .../manager/order/cart/CartManager.java | 72 +++++++++++++++++-- .../shopweb/manager/order/package-info.java | 1 - .../src/main/resources/application.yml | 2 + 26 files changed, 330 insertions(+), 60 deletions(-) create mode 100644 product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/manager/spu/ProductSkuManagerTest.java create mode 100644 product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/package-info.java create mode 100644 promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityListReqDTO.java create mode 100644 promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/activity/PromotionActivityManager.java delete mode 100644 promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/package-info.java create mode 100644 promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/activity/PromotionActivityRpcImpl.java delete mode 100644 promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/package-info.java delete mode 100644 shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/package-info.java diff --git a/product-service-project/product-service-api/src/main/java/cn/iocoder/mall/productservice/rpc/sku/dto/ProductSkuRespDTO.java b/product-service-project/product-service-api/src/main/java/cn/iocoder/mall/productservice/rpc/sku/dto/ProductSkuRespDTO.java index a256e9099..e97cd0e21 100644 --- a/product-service-project/product-service-api/src/main/java/cn/iocoder/mall/productservice/rpc/sku/dto/ProductSkuRespDTO.java +++ b/product-service-project/product-service-api/src/main/java/cn/iocoder/mall/productservice/rpc/sku/dto/ProductSkuRespDTO.java @@ -1,5 +1,8 @@ package cn.iocoder.mall.productservice.rpc.sku.dto; +import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum; +import cn.iocoder.mall.productservice.rpc.attr.dto.ProductAttrKeyValueRespDTO; +import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO; import lombok.Data; import lombok.experimental.Accessors; @@ -46,5 +49,19 @@ public class ProductSkuRespDTO implements Serializable { * 创建时间 */ private Date createTime; + /** + * 规格值数组 + * + * 需要设置 {@link ProductSkuDetailFieldEnum#ATTR} 才返回 + */ + private List attrs; + /** + * 商品 SPU 信息 + * + * 需要设置 {@link ProductSkuDetailFieldEnum#SPU} 才返回 + * + * // TODO 芋艿,后续考虑怎么优化下,目前是内嵌了别的 dto + */ + private ProductSpuRespDTO spu; } diff --git a/product-service-project/product-service-app/pom.xml b/product-service-project/product-service-app/pom.xml index e91aec96f..cafab548f 100644 --- a/product-service-project/product-service-app/pom.xml +++ b/product-service-project/product-service-app/pom.xml @@ -70,6 +70,13 @@ spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-test + test + + org.springframework.boot diff --git a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java index d2b22984d..8ac6df5b0 100644 --- a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java +++ b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java @@ -1,18 +1,25 @@ package cn.iocoder.mall.productservice.convert.sku; +import cn.iocoder.common.framework.util.CollectionUtils; import cn.iocoder.common.framework.util.StringUtils; import cn.iocoder.mall.productservice.dal.mysql.dataobject.sku.ProductSkuDO; +import cn.iocoder.mall.productservice.rpc.attr.dto.ProductAttrKeyValueRespDTO; import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO; import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; +import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO; +import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyValueBO; import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuBO; import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO; import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuListQueryBO; +import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; import org.mapstruct.factory.Mappers; +import java.util.ArrayList; import java.util.List; +import java.util.Map; @Mapper public interface ProductSkuConvert { @@ -33,7 +40,30 @@ public interface ProductSkuConvert { ProductSkuListQueryBO convert(ProductSkuListQueryReqDTO bean); - List convertList03(List list); + ProductSpuRespDTO convert(ProductSpuBO bean); + + ProductAttrKeyValueRespDTO convert(ProductAttrKeyValueBO bean); + + default List convertList(List skuBOs, List spuBOs, + List attrBOs) { + // 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号 + Map attrDetailBOMap = CollectionUtils.convertMap(attrBOs, + ProductAttrKeyValueBO::getAttrValueId); + // 构建 ProductSpuBO 的映射。 + Map spuBOMap = CollectionUtils.convertMap(spuBOs, ProductSpuBO::getId); + // 拼接数据 + List skuRespDTOs = new ArrayList<>(skuBOs.size()); + skuBOs.forEach(skuBO -> { + ProductSkuRespDTO skuRespDTO = convert(skuBO); + skuRespDTOs.add(skuRespDTO); + // 拼接商品 SPU + skuRespDTO.setSpu(convert(spuBOMap.get(skuBO.getSpuId()))); + // 拼接商品 Attr + skuRespDTO.setAttrs(new ArrayList<>()); + skuBO.getAttrValueIds().forEach(attrValueId -> skuRespDTO.getAttrs().add(convert(attrDetailBOMap.get(attrValueId)))); + }); + return skuRespDTOs; + } @Named("translateAttrValueIdsFromString") default List translateAttrValueIdsFromString(String attrValueIdsStar) { diff --git a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/spu/ProductSpuConvert.java b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/spu/ProductSpuConvert.java index bbde45c1b..4f694ba7b 100644 --- a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/spu/ProductSpuConvert.java +++ b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/spu/ProductSpuConvert.java @@ -63,21 +63,21 @@ public interface ProductSpuConvert { ProductAttrKeyValueRespDTO convert(ProductAttrKeyValueBO bean); - default ProductSpuDetailRespDTO convert(ProductSpuBO spuBO, List skuBOs, List attrBOs, - ProductCategoryBO categoryBO) { + default ProductSpuDetailRespDTO convert(ProductSpuBO spuBO, List skuBOs, + List attrBOs, ProductCategoryBO categoryBO) { // 创建并转换 ProductSpuDetailBO 对象 ProductSpuDetailRespDTO spuDetailDTO = this.convert2(spuBO); // 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号 - Map productAttrDetailBOMap = attrBOs.stream().collect( + Map attrDetailBOMap = attrBOs.stream().collect( Collectors.toMap(ProductAttrKeyValueBO::getAttrValueId, attrBO -> attrBO)); // 创建并转换 ProductSpuDetailBO 数组 spuDetailDTO.setSkus(new ArrayList<>()); - skuBOs.forEach(sku -> { + skuBOs.forEach(skuBO -> { // 创建 ProductSpuDetailBO 对象 - ProductSpuDetailRespDTO.Sku skuDetail = convert(sku).setAttrs(new ArrayList<>()); + ProductSpuDetailRespDTO.Sku skuDetail = convert(skuBO).setAttrs(new ArrayList<>()); spuDetailDTO.getSkus().add(skuDetail); // 设置 ProductSpuDetailBO 的 attrs 规格属性 - sku.getAttrValueIds().forEach(attrValueId -> skuDetail.getAttrs().add(convert(productAttrDetailBOMap.get(attrValueId)))); + skuBO.getAttrValueIds().forEach(attrValueId -> skuDetail.getAttrs().add(convert(attrDetailBOMap.get(attrValueId)))); }); // 设置分类名 spuDetailDTO.setCategoryName(categoryBO.getName()); diff --git a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/sku/ProductSkuManager.java b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/sku/ProductSkuManager.java index bafa60ffe..7a54adfa7 100644 --- a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/sku/ProductSkuManager.java +++ b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/sku/ProductSkuManager.java @@ -2,15 +2,22 @@ package cn.iocoder.mall.productservice.manager.sku; import cn.iocoder.common.framework.util.CollectionUtils; import cn.iocoder.mall.productservice.convert.sku.ProductSkuConvert; +import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum; import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO; import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; +import cn.iocoder.mall.productservice.service.attr.ProductAttrService; +import cn.iocoder.mall.productservice.service.attr.bo.ProductAttrKeyValueBO; import cn.iocoder.mall.productservice.service.sku.ProductSkuService; import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuBO; +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.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * 商品 SKU Manager @@ -20,6 +27,10 @@ public class ProductSkuManager { @Autowired private ProductSkuService productSkuService; + @Autowired + private ProductSpuService productSpuService; + @Autowired + private ProductAttrService productAttrService; /** * 获得商品 SKU @@ -40,13 +51,26 @@ public class ProductSkuManager { */ public List listProductSkus(ProductSkuListQueryReqDTO queryReqDTO) { // 获得商品 SKU 列表 - List productSkuBOs = productSkuService.listProductSkus( + List skuBOs = productSkuService.listProductSkus( ProductSkuConvert.INSTANCE.convert(queryReqDTO)); - if (CollectionUtils.isEmpty(productSkuBOs)) { + if (CollectionUtils.isEmpty(skuBOs)) { return Collections.emptyList(); } - // - return ProductSkuConvert.INSTANCE.convertList03(productSkuBOs); + // 获得商品 SPU 列表 + List spuBOs = Collections.emptyList(); + if (queryReqDTO.getFields().contains(ProductSkuDetailFieldEnum.SPU.getField())) { + spuBOs = productSpuService.listProductSpus( + CollectionUtils.convertSet(skuBOs, ProductSkuBO::getSpuId)); + } + // 获取商品 SKU 的规格数组 + List attrBOs = Collections.emptyList(); + if (queryReqDTO.getFields().contains(ProductSkuDetailFieldEnum.ATTR.getField())) { + Set attrValueIds = new HashSet<>(); + skuBOs.forEach(sku -> attrValueIds.addAll(sku.getAttrValueIds())); + attrBOs = productAttrService.validProductAttr(attrValueIds, false); // 读取规格时,不考虑规格是否被禁用 + } + // 拼接最终返回 + return ProductSkuConvert.INSTANCE.convertList(skuBOs, spuBOs, attrBOs); } } diff --git a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/spu/ProductSpuManager.java b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/spu/ProductSpuManager.java index 8b848420e..2007f3658 100644 --- a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/spu/ProductSpuManager.java +++ b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/manager/spu/ProductSpuManager.java @@ -231,9 +231,9 @@ public class ProductSpuManager { // 获取商品 SKU 的规格数组 List attrBOs = Collections.emptyList(); if (fields.contains(ProductSpuDetailFieldEnum.ATTR.getField()) && !CollectionUtils.isEmpty(skuBOs)) { - Set productAttrValueIds = new HashSet<>(); - skuBOs.forEach(sku -> productAttrValueIds.addAll(sku.getAttrValueIds())); - attrBOs = productAttrService.validProductAttr(productAttrValueIds, false); // 读取规格时,不考虑规格是否被禁用 + Set attrValueIds = new HashSet<>(); + skuBOs.forEach(sku -> attrValueIds.addAll(sku.getAttrValueIds())); + attrBOs = productAttrService.validProductAttr(attrValueIds, false); // 读取规格时,不考虑规格是否被禁用 } // 拼接最终返回 return ProductSpuConvert.INSTANCE.convert(spuBO, skuBOs, attrBOs, categoryBO); diff --git a/product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/manager/spu/ProductSkuManagerTest.java b/product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/manager/spu/ProductSkuManagerTest.java new file mode 100644 index 000000000..0a4993742 --- /dev/null +++ b/product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/manager/spu/ProductSkuManagerTest.java @@ -0,0 +1,34 @@ +package cn.iocoder.mall.productservice.manager.spu; + +import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum; +import cn.iocoder.mall.productservice.manager.sku.ProductSkuManager; +import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO; +import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; +import lombok.extern.slf4j.Slf4j; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.Arrays; +import java.util.List; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) +@Slf4j +public class ProductSkuManagerTest { + + @Autowired + private ProductSkuManager productSkuManager; + + @Test + public void testListProductSkus() { + List skuRespDTOs = productSkuManager.listProductSkus( + new ProductSkuListQueryReqDTO().setProductSkuIds(Arrays.asList(3, 4)) + .setFields(Arrays.asList(ProductSkuDetailFieldEnum.SPU.getField(), + ProductSkuDetailFieldEnum.ATTR.getField()))); + log.info("结果:{}", skuRespDTOs); + } + +} diff --git a/product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/package-info.java b/product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/package-info.java new file mode 100644 index 000000000..80135f6ed --- /dev/null +++ b/product-service-project/product-service-app/src/test/java/cn/iocoder/mall/productservice/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.mall.productservice; diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityRpc.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityRpc.java index 744340e3e..620718821 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityRpc.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/PromotionActivityRpc.java @@ -1,16 +1,21 @@ -package cn.iocoder.mall.promotion.api.rpc.activity.dto; +package cn.iocoder.mall.promotion.api.rpc.activity; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityListReqDTO; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; -import java.util.Collection; import java.util.List; public interface PromotionActivityRpc { - List getPromotionActivityListBySpuId(Integer spuId, - Collection activityStatuses); +// List getPromotionActivityListBySpuId(Integer spuId, +// Collection activityStatuses); +// +// List getPromotionActivityListBySpuIds(Collection spuIds, +// Collection activityStatuses); +// +// PromotionActivityPageReqDTO getPromotionActivityPage(PromotionActivityPageRespDTO promotionActivityPageDTO); - List getPromotionActivityListBySpuIds(Collection spuIds, - Collection activityStatuses); - - PromotionActivityPageReqDTO getPromotionActivityPage(PromotionActivityPageRespDTO promotionActivityPageDTO); + CommonResult> listPromotionActivities(PromotionActivityListReqDTO listReqDTO); } diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityListReqDTO.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityListReqDTO.java new file mode 100644 index 000000000..dce76f1d3 --- /dev/null +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityListReqDTO.java @@ -0,0 +1,21 @@ +package cn.iocoder.mall.promotion.api.rpc.activity.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Collection; + +/** + * 促销活动列表查询的 Request DTO + */ +@Data +@Accessors(chain = true) +public class PromotionActivityListReqDTO implements Serializable { + + /** + * 活动编号数组 + */ + private Collection activeIds; + +} diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityRespDTO.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityRespDTO.java index 6d2978fd5..26154270a 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityRespDTO.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/activity/dto/PromotionActivityRespDTO.java @@ -8,7 +8,7 @@ import java.util.Date; import java.util.List; /** - * 促销伙伴 Response DTO + * 促销活动 Response DTO */ @Data @Accessors(chain = true) diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java index 88372df54..279649173 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcReqDTO.java @@ -41,18 +41,26 @@ public class PriceProductCalcReqDTO implements Serializable { /** * SKU 编号 */ + @NotNull(message = "商品 SKU 编号不能为空") private Integer skuId; /** * 数量 */ + @NotNull(message = "商品 SKU 数量不能为空") private Integer quantity; + /** + * 是否选中 + */ + @NotNull(message = "是否选中不能为空") + private Boolean selected; public Item() { } - public Item(Integer skuId, Integer quantity) { + public Item(Integer skuId, Integer quantity, Boolean selected) { this.skuId = skuId; this.quantity = quantity; + this.selected = selected; } } diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java index b748c17bd..ee2f314da 100644 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/rpc/price/dto/PriceProductCalcRespDTO.java @@ -1,7 +1,6 @@ package cn.iocoder.mall.promotion.api.rpc.price.dto; import cn.iocoder.mall.promotion.api.enums.PromotionActivityTypeEnum; -import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; import lombok.Data; import lombok.experimental.Accessors; @@ -57,7 +56,7 @@ public class PriceProductCalcRespDTO implements Serializable { * * // TODO 芋艿,目前只会有【满减送】的情况,未来有新的促销方式,可能需要改成数组 */ - private PromotionActivityRespDTO activity; + private Integer activityId; /** * 促销减少的金额 * @@ -94,6 +93,13 @@ public class PriceProductCalcRespDTO implements Serializable { * 商品 Category 编号 */ private Integer cid; + + // 非 SKU 自带信息 + + /** + * 是否选中 + */ + private Boolean selected; /** * 购买数量 */ @@ -103,7 +109,7 @@ public class PriceProductCalcRespDTO implements Serializable { * * 目前会有限时折扣 {@link PromotionActivityTypeEnum#TIME_LIMITED_DISCOUNT} 类型的活动 */ - private PromotionActivityRespDTO activity; + private Integer activityId; /** * 原始单价,单位:分。 */ diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/activity/PromotionActivityMapper.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/activity/PromotionActivityMapper.java index e987a11de..86d6fc18d 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/activity/PromotionActivityMapper.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/dal/mysql/mapper/activity/PromotionActivityMapper.java @@ -1,5 +1,7 @@ package cn.iocoder.mall.promotionservice.dal.mysql.mapper.activity; +import cn.iocoder.mall.mybatis.core.query.QueryWrapperX; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityListReqDTO; import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.activity.PromotionActivityDO; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; @@ -26,4 +28,8 @@ public interface PromotionActivityMapper extends BaseMapper @Param("activityType") Integer activityType, @Param("statuses") Collection statuses); + default List selectList(PromotionActivityListReqDTO listReqDTO) { + return selectList(new QueryWrapperX().inIfPresent("id", listReqDTO.getActiveIds())); + } + } diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/activity/PromotionActivityManager.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/activity/PromotionActivityManager.java new file mode 100644 index 000000000..ec016a31f --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/activity/PromotionActivityManager.java @@ -0,0 +1,26 @@ +package cn.iocoder.mall.promotionservice.manager.activity; + +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityListReqDTO; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; +import cn.iocoder.mall.promotionservice.service.activity.PromotionActivityService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.List; + +/** + * 促销活动 Manager + */ +@Service +@Validated +public class PromotionActivityManager { + + @Autowired + private PromotionActivityService promotionActivityService; + + public List listPromotionActivities(PromotionActivityListReqDTO listReqDTO) { + return promotionActivityService.listPromotionActivities(listReqDTO); + } + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/package-info.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/package-info.java deleted file mode 100644 index d21a6c1f3..000000000 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.promotionservice.manager; diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java index 9ca8206cf..9d895a084 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/manager/price/PriceManager.java @@ -134,7 +134,7 @@ public class PriceManager { continue; } // 设置优惠 - item.setActivity(timeLimitedDiscount); + item.setActivityId(timeLimitedDiscount.getId()); // 设置价格 item.setBuyPrice(newBuyPrice); item.setBuyTotal(newBuyPrice * item.getBuyQuantity()); @@ -186,7 +186,7 @@ public class PriceManager { for (PromotionActivityRespDTO fullPrivilege : fullPrivileges) { // 创建 fullPrivilege 对应的分组 PriceProductCalcRespDTO.ItemGroup itemGroup = new PriceProductCalcRespDTO.ItemGroup() - .setActivity(fullPrivilege) + .setActivityId(fullPrivilege.getId()) .setItems(new ArrayList<>()); // 筛选商品到分组中 for (Iterator iterator = items.iterator(); iterator.hasNext(); ) { @@ -208,8 +208,9 @@ public class PriceManager { itemGroups.add(new PriceProductCalcRespDTO.ItemGroup().setItems(items)); } // 计算每个分组的价格 + Map activityMap = CollectionUtils.convertMap(activityList, PromotionActivityRespDTO::getId); for (PriceProductCalcRespDTO.ItemGroup itemGroup : itemGroups) { - itemGroup.setActivityDiscountTotal(calcSkuPriceByFullPrivilege(itemGroup)); + itemGroup.setActivityDiscountTotal(calcSkuPriceByFullPrivilege(itemGroup, activityMap.get(itemGroup.getActivityId()))); } // 返回结果 return itemGroups; @@ -227,11 +228,10 @@ public class PriceManager { throw new IllegalArgumentException(String.format("促销活动(%s) 可用范围的类型是不正确", activity.toString())); } - private Integer calcSkuPriceByFullPrivilege(PriceProductCalcRespDTO.ItemGroup itemGroup) { - if (itemGroup.getActivity() == null) { + private Integer calcSkuPriceByFullPrivilege(PriceProductCalcRespDTO.ItemGroup itemGroup, PromotionActivityRespDTO activity) { + if (itemGroup.getActivityId() == null) { return null; } - PromotionActivityRespDTO activity = itemGroup.getActivity(); Assert.isTrue(PromotionActivityTypeEnum.FULL_PRIVILEGE.getValue().equals(activity.getActivityType()), "传入的必须的满减送活动必须是满减送"); // 获得优惠信息 @@ -246,7 +246,8 @@ public class PriceManager { if (MeetTypeEnum.QUANTITY.getValue().equals(privilege.getMeetType())) { return itemCnt >= privilege.getMeetValue(); } - throw new IllegalArgumentException(String.format("满减送活动(%s) 的匹配(%s)不正确", itemGroup.getActivity().toString(), privilege.toString())); + throw new IllegalArgumentException(String.format("满减送活动(%s) 的匹配(%s)不正确", + activity.toString(), privilege.toString())); }).collect(Collectors.toList()); // 获得不到优惠信息,返回原始价格 if (privileges.isEmpty()) { diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/activity/PromotionActivityRpcImpl.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/activity/PromotionActivityRpcImpl.java new file mode 100644 index 000000000..3103e905a --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/activity/PromotionActivityRpcImpl.java @@ -0,0 +1,26 @@ +package cn.iocoder.mall.promotionservice.rpc.activity; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.promotion.api.rpc.activity.PromotionActivityRpc; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityListReqDTO; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; +import cn.iocoder.mall.promotionservice.manager.activity.PromotionActivityManager; +import org.apache.dubbo.config.annotation.DubboService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static cn.iocoder.common.framework.vo.CommonResult.success; + +@DubboService +public class PromotionActivityRpcImpl implements PromotionActivityRpc { + + @Autowired + private PromotionActivityManager promotionActivityManager; + + @Override + public CommonResult> listPromotionActivities(PromotionActivityListReqDTO listReqDTO) { + return success(promotionActivityManager.listPromotionActivities(listReqDTO)); + } + +} diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/package-info.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/package-info.java deleted file mode 100644 index f7ddc97c2..000000000 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/rpc/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.promotionservice.rpc; diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/PromotionActivityService.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/PromotionActivityService.java index 5f5f59795..011a8a7b7 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/PromotionActivityService.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/activity/PromotionActivityService.java @@ -2,6 +2,7 @@ package cn.iocoder.mall.promotionservice.service.activity; import cn.iocoder.mall.promotion.api.enums.PromotionActivityTypeEnum; import cn.iocoder.mall.promotion.api.enums.RangeTypeEnum; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityListReqDTO; import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; import cn.iocoder.mall.promotionservice.convert.activity.PromotionActivityConvert; import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.activity.PromotionActivityDO; @@ -25,24 +26,15 @@ public class PromotionActivityService { @Autowired private PromotionActivityMapper promotionActivityMapper; - /** - * 获取指定商品 - * - * @param spuId - * @param activityStatuses - * @return - */ + public List listPromotionActivities(PromotionActivityListReqDTO listReqDTO) { + List activityList = promotionActivityMapper.selectList(listReqDTO); + return PromotionActivityConvert.INSTANCE.convertList(activityList); + } + public List listPromotionActivitiesBySpuId(Integer spuId, Collection activityStatuses) { return this.listPromotionActivitiesBySpuIds(Collections.singleton(spuId), activityStatuses); } - /** - * - * - * @param spuIds - * @param activityStatuses - * @return - */ public List listPromotionActivitiesBySpuIds(Collection spuIds, Collection activityStatuses) { if (spuIds.isEmpty() || activityStatuses.isEmpty()) { return Collections.emptyList(); diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java index b8bb37102..42f49ad93 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java @@ -13,7 +13,7 @@ import cn.iocoder.mall.promotionservice.dal.mysql.mapper.recommend.ProductRecomm import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendAddBO; import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendBO; import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendUpdateBO; -import org.apache.dubbo.config.annotation.Reference; +import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -25,7 +25,7 @@ import java.util.List; @Validated public class ProductRecommendService { - @Reference(validation = "true", version = "${dubbo.consumer.ProductSpuService.version}") + @DubboReference(validation = "true", version = "${dubbo.consumer.ProductSpuRpc.version}") private ProductSpuRpc productSpuRpc; @Autowired diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java index 39448331a..a6d05afd2 100644 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java @@ -44,7 +44,7 @@ public class CartController { @GetMapping("/get-detail") @ApiOperation("查询用户的购物车的商品列表") public CommonResult getCartDetail() { - return success(cartManager.getCartDetail()); + return success(cartManager.getCartDetail(UserSecurityContextHolder.getUserId())); } } diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java index 7f99e5ec3..26c94e3e2 100644 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/convert/order/CartConvert.java @@ -1,5 +1,8 @@ package cn.iocoder.mall.shopweb.convert.order; +import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; +import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO; +import cn.iocoder.mall.shopweb.controller.order.vo.cart.CartDetailVO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -8,4 +11,8 @@ public interface CartConvert { CartConvert INSTANCE = Mappers.getMapper(CartConvert.class); + CartDetailVO.Fee convert(PriceProductCalcRespDTO.Fee bean); + + CartDetailVO.Sku convert(PriceProductCalcRespDTO.Item item, ProductSkuRespDTO sku); + } diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java index fca063c59..43c3151b8 100644 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java @@ -6,15 +6,22 @@ import cn.iocoder.mall.orderservice.rpc.cart.CartRpc; import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemAddReqDTO; import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemListReqDTO; import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemRespDTO; +import cn.iocoder.mall.productservice.enums.sku.ProductSkuDetailFieldEnum; +import cn.iocoder.mall.productservice.rpc.sku.ProductSkuRpc; +import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO; +import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; +import cn.iocoder.mall.promotion.api.rpc.activity.PromotionActivityRpc; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityListReqDTO; +import cn.iocoder.mall.promotion.api.rpc.activity.dto.PromotionActivityRespDTO; import cn.iocoder.mall.promotion.api.rpc.price.PriceRpc; import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcReqDTO; import cn.iocoder.mall.promotion.api.rpc.price.dto.PriceProductCalcRespDTO; import cn.iocoder.mall.shopweb.controller.order.vo.cart.CartDetailVO; +import cn.iocoder.mall.shopweb.convert.order.CartConvert; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Service; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -27,6 +34,10 @@ public class CartManager { private CartRpc cartRpc; @DubboReference(version = "${dubbo.consumer.PriceRpc.version}") private PriceRpc priceRpc; + @DubboReference(version = "${dubbo.consumer.PromotionActivityRpc.version}") + private PromotionActivityRpc promotionActivityRpc; + @DubboReference(version = "${dubbo.consumer.ProductSkuRpc.version}") + private ProductSkuRpc productSkuRpc; /** * 添加商品到购物车 @@ -72,14 +83,63 @@ public class CartManager { // 计算选中的商品价格 CommonResult calcProductPriceResult = priceRpc.calcProductPrice(new PriceProductCalcReqDTO().setUserId(userId) .setItems(listCartItemsResult.getData().stream() - .filter(CartItemRespDTO::getSelected) - .map(cartItem -> new PriceProductCalcReqDTO.Item(cartItem.getSkuId(), cartItem.getQuantity())) + .map(cartItem -> new PriceProductCalcReqDTO.Item(cartItem.getSkuId(), cartItem.getQuantity(), cartItem.getSelected())) .collect(Collectors.toList()))); calcProductPriceResult.checkError(); + // 获得促销活动信息 + Map promotionActivityMap = this.getPromotionActivityMap(calcProductPriceResult.getData()); + // 获得商品 SKU 信息 + Map productSkuMap = this.getProductSkuMap(listCartItemsResult.getData()); // 拼接结果 + CartDetailVO cartDetailVO = new CartDetailVO(); + cartDetailVO.setFee(CartConvert.INSTANCE.convert(calcProductPriceResult.getData().getFee())); + cartDetailVO.setItemGroups(new ArrayList<>()); + calcProductPriceResult.getData().getItemGroups().forEach(itemGroupDTO -> { + CartDetailVO.ItemGroup itemGroupVO = new CartDetailVO.ItemGroup(); + cartDetailVO.getItemGroups().add(itemGroupVO); + // 活动信息 + if (itemGroupDTO.getActivityId() != null) { + itemGroupVO.setActivity(promotionActivityMap.get(itemGroupDTO.getActivityId())) + .setActivityDiscountTotal(itemGroupDTO.getActivityDiscountTotal()); + } + // 商品 SKU 信息 + itemGroupVO.setItems(new ArrayList<>()); + itemGroupDTO.getItems().forEach(item -> { + itemGroupVO.getItems().add(CartConvert.INSTANCE.convert(item, productSkuMap.get(item.getSkuId()))); + }); + }); + return cartDetailVO; + } - // 执行数据拼装 - return null; + private Map getPromotionActivityMap(PriceProductCalcRespDTO calcRespDTO) { + // 获得所有促销活动编号 + Set activeIds = new HashSet<>(); + calcRespDTO.getItemGroups().forEach(itemGroup -> { + if (itemGroup.getActivityId() != null) { + activeIds.add(itemGroup.getActivityId()); + } + itemGroup.getItems().forEach(item -> { + if (item.getActivityId() != null) { + activeIds.add(item.getActivityId()); + } + }); + }); + if (!CollectionUtils.isEmpty(activeIds)) { + return Collections.emptyMap(); + } + // 查询促销活动列表 + CommonResult> listPromotionActivitiesResult = + promotionActivityRpc.listPromotionActivities(new PromotionActivityListReqDTO().setActiveIds(activeIds)); + listPromotionActivitiesResult.checkError(); + return CollectionUtils.convertMap(listPromotionActivitiesResult.getData(), PromotionActivityRespDTO::getId); + } + + private Map getProductSkuMap(List itemRespDTOs) { + CommonResult> listProductSkusResult = productSkuRpc.listProductSkus(new ProductSkuListQueryReqDTO() + .setProductSkuIds(CollectionUtils.convertSet(itemRespDTOs, CartItemRespDTO::getSkuId)) + .setFields(Arrays.asList(ProductSkuDetailFieldEnum.SPU.getField(), ProductSkuDetailFieldEnum.ATTR.getField()))); + listProductSkusResult.checkError(); + return CollectionUtils.convertMap(listProductSkusResult.getData(), ProductSkuRespDTO::getId); } } diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/package-info.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/package-info.java deleted file mode 100644 index 5ea6db8cb..000000000 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.mall.shopweb.manager.order; diff --git a/shop-web-app/src/main/resources/application.yml b/shop-web-app/src/main/resources/application.yml index 884a02a0e..4ba879ab2 100644 --- a/shop-web-app/src/main/resources/application.yml +++ b/shop-web-app/src/main/resources/application.yml @@ -41,6 +41,8 @@ dubbo: version: 1.0.0 PriceRpc: version: 1.0.0 + PromotionActivityRpc: + version: 1.0.0 # Swagger 配置项 swagger: