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 a256e90998ade2050d6b12bd2a78bc669ebcb295..e97cd0e21a408320f4a0841435813286e705ebf5 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<ProductAttrKeyValueRespDTO> 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 e91aec96fcfe7e6265a5efdf6de597e1ec9a8896..cafab548fa4b974944b134df54513a4ebbbcbfc4 100644
--- a/product-service-project/product-service-app/pom.xml
+++ b/product-service-project/product-service-app/pom.xml
@@ -70,6 +70,13 @@
             <artifactId>spring-boot-starter-actuator</artifactId>
         </dependency>
 
+        <!-- Test 相关 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
         <!-- 工具类相关 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
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 d2b22984d5d2d630295d371f5fd0a34d24459e21..8ac6df5b0c50335a1958774c9b2a3ba8557b7e45 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<ProductSkuRespDTO> convertList03(List<ProductSkuBO> list);
+    ProductSpuRespDTO convert(ProductSpuBO bean);
+
+    ProductAttrKeyValueRespDTO convert(ProductAttrKeyValueBO bean);
+
+    default List<ProductSkuRespDTO> convertList(List<ProductSkuBO> skuBOs, List<ProductSpuBO> spuBOs,
+                                                List<ProductAttrKeyValueBO> attrBOs) {
+        // 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
+        Map<Integer, ProductAttrKeyValueBO> attrDetailBOMap = CollectionUtils.convertMap(attrBOs,
+                ProductAttrKeyValueBO::getAttrValueId);
+        // 构建 ProductSpuBO 的映射。
+        Map<Integer, ProductSpuBO> spuBOMap = CollectionUtils.convertMap(spuBOs, ProductSpuBO::getId);
+        // 拼接数据
+        List<ProductSkuRespDTO> 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<Integer> 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 bbde45c1b9f0317649f335f4c8fff9414945b8c3..4f694ba7b98669a560be33d26376f30ddf0b44d0 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<ProductSkuBO> skuBOs, List<ProductAttrKeyValueBO> attrBOs,
-                                            ProductCategoryBO categoryBO) {
+    default ProductSpuDetailRespDTO convert(ProductSpuBO spuBO, List<ProductSkuBO> skuBOs,
+                                            List<ProductAttrKeyValueBO> attrBOs, ProductCategoryBO categoryBO) {
         // 创建并转换 ProductSpuDetailBO 对象
         ProductSpuDetailRespDTO spuDetailDTO = this.convert2(spuBO);
         // 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
-        Map<Integer, ProductAttrKeyValueBO> productAttrDetailBOMap = attrBOs.stream().collect(
+        Map<Integer, ProductAttrKeyValueBO> 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 bafa60ffe5685589e795e1156ab85a1cb975f1da..7a54adfa7d7f8cd6ce6a4aa8fb518069178e9994 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<ProductSkuRespDTO> listProductSkus(ProductSkuListQueryReqDTO queryReqDTO) {
         // 获得商品 SKU 列表
-        List<ProductSkuBO> productSkuBOs = productSkuService.listProductSkus(
+        List<ProductSkuBO> 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<ProductSpuBO> spuBOs = Collections.emptyList();
+        if (queryReqDTO.getFields().contains(ProductSkuDetailFieldEnum.SPU.getField())) {
+            spuBOs = productSpuService.listProductSpus(
+                    CollectionUtils.convertSet(skuBOs, ProductSkuBO::getSpuId));
+        }
+        // 获取商品 SKU 的规格数组
+        List<ProductAttrKeyValueBO> attrBOs = Collections.emptyList();
+        if (queryReqDTO.getFields().contains(ProductSkuDetailFieldEnum.ATTR.getField())) {
+            Set<Integer> 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 8b848420e88a2d052b9a61ed65c61381e96a00d5..2007f3658096624ffa498d0ff268bd8f02a7ed11 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<ProductAttrKeyValueBO> attrBOs = Collections.emptyList();
         if (fields.contains(ProductSpuDetailFieldEnum.ATTR.getField()) && !CollectionUtils.isEmpty(skuBOs)) {
-            Set<Integer> productAttrValueIds = new HashSet<>();
-            skuBOs.forEach(sku -> productAttrValueIds.addAll(sku.getAttrValueIds()));
-            attrBOs = productAttrService.validProductAttr(productAttrValueIds, false); // 读取规格时,不考虑规格是否被禁用
+            Set<Integer> 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 0000000000000000000000000000000000000000..0a4993742b6d46add85831e1bf218a12b957c331
--- /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<ProductSkuRespDTO> 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 0000000000000000000000000000000000000000..80135f6ed1bb891a470df52c48855fda64f555c7
--- /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 744340e3ea5f320d071a8c6c88e9ce39277f7bec..620718821445ef7c3578f23a7d445377ad38af33 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<PromotionActivityRespDTO> getPromotionActivityListBySpuId(Integer spuId,
-                                                                   Collection<Integer> activityStatuses);
-
-    List<PromotionActivityRespDTO> getPromotionActivityListBySpuIds(Collection<Integer> spuIds,
-                                                                    Collection<Integer> activityStatuses);
+//    List<PromotionActivityRespDTO> getPromotionActivityListBySpuId(Integer spuId,
+//                                                                   Collection<Integer> activityStatuses);
+//
+//    List<PromotionActivityRespDTO> getPromotionActivityListBySpuIds(Collection<Integer> spuIds,
+//                                                                    Collection<Integer> activityStatuses);
+//
+//    PromotionActivityPageReqDTO getPromotionActivityPage(PromotionActivityPageRespDTO promotionActivityPageDTO);
 
-    PromotionActivityPageReqDTO getPromotionActivityPage(PromotionActivityPageRespDTO promotionActivityPageDTO);
+    CommonResult<List<PromotionActivityRespDTO>> 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 0000000000000000000000000000000000000000..dce76f1d33486976f34b9c2f6292bedcc9af0ca9
--- /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<Integer> 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 6d2978fd51310cf596ab88cd562dd22c2c25d8cb..26154270a29f2b5b0fd83aac9a44150dde636a12 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 88372df54f4f88efd6da50079518e2a6b4a4983e..2796491732e5c92f9b9166c6dfdddabaf0afae2a 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 b748c17bd40565aa01c70c4da87c2ddd1246be48..ee2f314da690ff332a69206a62523d1608aaf448 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 e987a11de88006b968e046e2afa569ea36ddafd4..86d6fc18d6ad18a4dff0d6dfc6b765ac7cf47c15 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<PromotionActivityDO>
                               @Param("activityType") Integer activityType,
                               @Param("statuses") Collection<Integer> statuses);
 
+    default List<PromotionActivityDO> selectList(PromotionActivityListReqDTO listReqDTO) {
+        return selectList(new QueryWrapperX<PromotionActivityDO>().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 0000000000000000000000000000000000000000..ec016a31fffc71d109a9cc55801d594db24a8489
--- /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<PromotionActivityRespDTO> 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 d21a6c1f31278676fa7c04316a0d1847c0772714..0000000000000000000000000000000000000000
--- 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 9ca8206cf07c86d5faec70898b2e027397284416..9d895a084586cd94d291f19d5c4eb037ef292ef9 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<PriceProductCalcRespDTO.Item> iterator = items.iterator(); iterator.hasNext(); ) {
@@ -208,8 +208,9 @@ public class PriceManager {
             itemGroups.add(new PriceProductCalcRespDTO.ItemGroup().setItems(items));
         }
         // 计算每个分组的价格
+        Map<Integer, PromotionActivityRespDTO> 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 0000000000000000000000000000000000000000..3103e905ac1529fa3d22641e96a5cb996ebad7f5
--- /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<List<PromotionActivityRespDTO>> 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 f7ddc97c231c9f0c05469df19d84c62ba50a30b7..0000000000000000000000000000000000000000
--- 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 5f5f597952b78c02e93f6289e64ef5b5685b387f..011a8a7b7f1a8ae06d6ef1d093b260d7474190cb 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<PromotionActivityRespDTO> listPromotionActivities(PromotionActivityListReqDTO listReqDTO) {
+        List<PromotionActivityDO> activityList = promotionActivityMapper.selectList(listReqDTO);
+        return PromotionActivityConvert.INSTANCE.convertList(activityList);
+    }
+
     public List<PromotionActivityRespDTO> listPromotionActivitiesBySpuId(Integer spuId, Collection<Integer> activityStatuses) {
         return this.listPromotionActivitiesBySpuIds(Collections.singleton(spuId), activityStatuses);
     }
 
-    /**
-     *
-     *
-     * @param spuIds
-     * @param activityStatuses
-     * @return
-     */
     public List<PromotionActivityRespDTO> listPromotionActivitiesBySpuIds(Collection<Integer> spuIds, Collection<Integer> 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 b8bb37102e006d7e964ee06e1f12f65aab7266ad..42f49ad936f2bdd87c7ff5b5842ca07bdbb36e27 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 39448331ac8edc1d179dc150d0fafc0e43f69f04..a6d05afd2dcf593ce62bc1e60cad9b4afd7a0b08 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<CartDetailVO> 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 7f99e5ec317cc60e03204012ea319deb7de0a739..26c94e3e2e2e0bd38d09b047a378382a50efb6bc 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 fca063c59de80fcfa378b859c9938ee0abad8f51..43c3151b851ad2dc9c3d22c505e772ca441d776e 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<PriceProductCalcRespDTO> 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<Integer, PromotionActivityRespDTO> promotionActivityMap = this.getPromotionActivityMap(calcProductPriceResult.getData());
+        // 获得商品 SKU 信息
+        Map<Integer, ProductSkuRespDTO> 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;
+    }
+
+    private Map<Integer, PromotionActivityRespDTO> getPromotionActivityMap(PriceProductCalcRespDTO calcRespDTO) {
+        // 获得所有促销活动编号
+        Set<Integer> 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<List<PromotionActivityRespDTO>> listPromotionActivitiesResult =
+                promotionActivityRpc.listPromotionActivities(new PromotionActivityListReqDTO().setActiveIds(activeIds));
+        listPromotionActivitiesResult.checkError();
+        return CollectionUtils.convertMap(listPromotionActivitiesResult.getData(), PromotionActivityRespDTO::getId);
+    }
 
-        // 执行数据拼装
-        return null;
+    private Map<Integer, ProductSkuRespDTO> getProductSkuMap(List<CartItemRespDTO> itemRespDTOs) {
+        CommonResult<List<ProductSkuRespDTO>> 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 5ea6db8cbe3cd598a2826465c9164c4267161e4f..0000000000000000000000000000000000000000
--- 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 884a02a0e426d3d2dcfe212d6ea1a2a11c00574d..4ba879ab2a1927b030d923b16ddd4569c6f9cd50 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: