Explorar o código

mall + promotion:增加营销活动的 mock 接口

YunaiV %!s(int64=2) %!d(string=hai) anos
pai
achega
4f5ac0edbb
Modificáronse 14 ficheiros con 186 adicións e 68 borrados
  1. 0 1
      yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java
  2. 16 5
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java
  3. 5 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java
  4. 2 1
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java
  5. 7 2
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java
  6. 12 19
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
  7. 28 8
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
  8. 9 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
  9. 5 0
      yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
  10. 8 4
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java
  11. 0 24
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java
  12. 65 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java
  13. 27 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/vo/AppActivityRespVO.java
  14. 2 4
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java

+ 0 - 1
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.mybatis.core.query;
 
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

+ 16 - 5
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/AppProductSpuController.java

@@ -3,17 +3,17 @@ package cn.iocoder.yudao.module.product.controller.app.spu;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
-import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
+import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
-import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -40,12 +40,23 @@ public class AppProductSpuController {
     private ProductSpuService productSpuService;
     @Resource
     private ProductSkuService productSkuService;
-    @Resource
-    private ProductPropertyValueService productPropertyValueService;
+
+    @GetMapping("/list")
+    @Operation(summary = "获得商品 SPU 列表")
+    @Parameters({
+            @Parameter(name = "recommendType", description = "推荐类型", required = true), // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常量
+            @Parameter(name = "count", description = "数量", required = true)
+    })
+    public CommonResult<List<AppProductSpuPageRespVO>> getSpuList(
+            @RequestParam("recommendType") String recommendType,
+            @RequestParam(value = "count", defaultValue = "10") Integer count) {
+        List<ProductSpuDO> list = productSpuService.getSpuList(recommendType, count);
+        return success(ProductSpuConvert.INSTANCE.convertListForGetSpuList(list));
+    }
 
     @GetMapping("/page")
     @Operation(summary = "获得商品 SPU 分页")
-    public CommonResult<PageResult<AppProductSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
+    public CommonResult<PageResult<AppProductSpuPageRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
         PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO);
         return success(ProductSpuConvert.INSTANCE.convertPageForGetSpuPage(pageResult));
     }

+ 5 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuDetailRespVO.java

@@ -39,6 +39,11 @@ public class AppProductSpuDetailRespVO {
     @Schema(description = "单位名", required = true, example = "个")
     private String unitName;
 
+    // ========== 营销相关字段 =========
+
+    @Schema(description = "活动排序数组", required = true, example = "1024")
+    private List<Integer> activityOrders;
+
     // ========== SKU 相关字段 =========
 
     @Schema(description = "规格类型", required = true, example = "true")

+ 2 - 1
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageReqVO.java

@@ -20,6 +20,7 @@ public class AppProductSpuPageReqVO extends PageParam {
     public static final String SORT_FIELD_SALES_COUNT = "salesCount";
 
     public static final String RECOMMEND_TYPE_HOT = "hot";
+    public static final String RECOMMEND_TYPE_GOOD = "good";
 
     @Schema(description = "分类编号", example = "1")
     private Long categoryId;
@@ -33,7 +34,7 @@ public class AppProductSpuPageReqVO extends PageParam {
     @Schema(description = "排序方式", example = "true")
     private Boolean sortAsc;
 
-    @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常
+    @Schema(description = "推荐类型", example = "hot") // 参见 AppProductSpuPageReqVO.RECOMMEND_TYPE_XXX 常
     private String recommendType;
 
     @AssertTrue(message = "排序字段不合法")

+ 7 - 2
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageItemRespVO.java → yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/spu/vo/AppProductSpuPageRespVO.java

@@ -5,9 +5,9 @@ import lombok.Data;
 
 import java.util.List;
 
-@Schema(description = "用户 App - 商品 SPU 分页项 Response VO")
+@Schema(description = "用户 App - 商品 SPU Response VO")
 @Data
-public class AppProductSpuPageItemRespVO {
+public class AppProductSpuPageRespVO {
 
     @Schema(description = "商品 SPU 编号", required = true, example = "1")
     private Long id;
@@ -35,6 +35,11 @@ public class AppProductSpuPageItemRespVO {
     @Schema(description = "库存", required = true, example = "666")
     private Integer stock;
 
+    // ========== 营销相关字段 =========
+
+    @Schema(description = "活动排序数组", required = true, example = "1024")
+    private List<Integer> activityOrders;
+
     // ========== 统计相关字段 =========
 
     @Schema(description = "商品销量", required = true, example = "1024")

+ 12 - 19
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java

@@ -1,14 +1,12 @@
 package cn.iocoder.yudao.module.product.convert.spu;
 
-import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
-import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
-import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
+import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageRespVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
@@ -80,14 +78,15 @@ public interface ProductSpuConvert {
 
     // ========== 用户 App 相关 ==========
 
-    default PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage(PageResult<ProductSpuDO> page) {
-        // 累加虚拟销量
-        page.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
-        // 然后进行转换
-        return convertPageForGetSpuPage0(page);
-    }
+    PageResult<AppProductSpuPageRespVO> convertPageForGetSpuPage(PageResult<ProductSpuDO> page);
 
-    PageResult<AppProductSpuPageItemRespVO> convertPageForGetSpuPage0(PageResult<ProductSpuDO> page);
+    default List<AppProductSpuPageRespVO> convertListForGetSpuList(List<ProductSpuDO> list) {
+        // 处理虚拟销量
+        list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
+        return convertListForGetSpuList0(list);
+    }
+    @Named("convertListForGetSpuList0")
+    List<AppProductSpuPageRespVO> convertListForGetSpuList0(List<ProductSpuDO> list);
 
     default AppProductSpuDetailRespVO convertForGetSpuDetail(ProductSpuDO spu, List<ProductSkuDO> skus) {
         // 处理 SPU
@@ -109,15 +108,9 @@ public interface ProductSpuConvert {
     List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus);
 
     default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) {
-        ProductSpuDetailRespVO productSpuDetailRespVO = convert03(spu);
-        // skus 为空直接返回
-        if (CollUtil.isEmpty(skus)) {
-            return productSpuDetailRespVO;
-        }
-        List<ProductSkuRespVO> skuVOs = ProductSkuConvert.INSTANCE.convertList(skus);
-        // fix: 因为现在已改为 sku 属性列表 属性 已包含 属性名字 属性值名字 所以不需要再额外处理,属性更新时更新 sku 中的属性相关冗余即可
-        productSpuDetailRespVO.setSkus(skuVOs);
-        return productSpuDetailRespVO;
+        ProductSpuDetailRespVO detailRespVO = convert03(spu);
+        detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skus));
+        return detailRespVO;
     }
 
 }

+ 28 - 8
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java

@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuExportReqVO;
 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
 import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
@@ -66,7 +67,10 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
         // 推荐类型的过滤条件
         if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) {
             query.eq(ProductSpuDO::getRecommendHot, true);
+        } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) {
+            query.eq(ProductSpuDO::getRecommendGood, true);
         }
+
         // 排序逻辑
         if (Objects.equals(pageReqVO.getSortField(), AppProductSpuPageReqVO.SORT_FIELD_SALES_COUNT)) {
             query.last(String.format(" ORDER BY (sales_count + virtual_sales_count) %s, sort DESC, id DESC",
@@ -80,6 +84,21 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
         return selectPage(pageReqVO, query);
     }
 
+    default List<ProductSpuDO> selectListByRecommendType(String recommendType, Integer count) {
+        QueryWrapperX<ProductSpuDO> query = new QueryWrapperX<>();
+        // 上架状态 且有库存
+        query.eq("status", ProductSpuStatusEnum.ENABLE.getStatus()).gt("stock", 0);
+        // 推荐类型的过滤条件
+        if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_HOT)) {
+            query.eq("recommend_hot", true);
+        } else if (ObjUtil.equal(recommendType, AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) {
+            query.eq("recommend_good", true);
+        }
+        // 设置最大长度
+        query.limitN(count);
+        return selectList(query);
+    }
+
     /**
      * 更新商品 SPU 库存
      *
@@ -111,33 +130,34 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
     }
 
     /**
-     * 验证选项卡类型构建条件
+     * 添加后台 Tab 选项的查询条件
      *
      * @param tabType      标签类型
-     * @param queryWrapper 查询条件
+     * @param query 查询条件
      */
-    static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> queryWrapper) {
+    static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> query) {
         // 出售中商品
         if (ObjectUtil.equals(ProductSpuPageReqVO.FOR_SALE, tabType)) {
-            queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus());
+            query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus());
         }
         // 仓储中商品
         if (ObjectUtil.equals(ProductSpuPageReqVO.IN_WAREHOUSE, tabType)) {
-            queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus());
+            query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus());
         }
         // 已售空商品
         if (ObjectUtil.equals(ProductSpuPageReqVO.SOLD_OUT, tabType)) {
-            queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0);
+            query.eqIfPresent(ProductSpuDO::getStock, 0);
         }
         // 警戒库存
         if (ObjectUtil.equals(ProductSpuPageReqVO.ALERT_STOCK, tabType)) {
-            queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK)
+            query.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK)
                     // 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示
                     .notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
         }
         // 回收站
         if (ObjectUtil.equals(ProductSpuPageReqVO.RECYCLE_BIN, tabType)) {
-            queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
+            query.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
         }
     }
+
 }

+ 9 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java

@@ -98,6 +98,15 @@ public interface ProductSpuService {
      */
     PageResult<ProductSpuDO> getSpuPage(AppProductSpuPageReqVO pageReqVO);
 
+    /**
+     * 获得商品 SPU 列表,提供给用户 App 使用
+     *
+     * @param recommendType 推荐类型
+     * @param count 数量
+     * @return 商品 SPU 列表
+     */
+    List<ProductSpuDO> getSpuList(String recommendType, Integer count);
+
     /**
      * 更新商品 SPU 库存(增量)
      *

+ 5 - 0
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java

@@ -201,6 +201,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
         return productSpuMapper.selectPage(pageReqVO, categoryIds);
     }
 
+    @Override
+    public List<ProductSpuDO> getSpuList(String recommendType, Integer count) {
+        return productSpuMapper.selectListByRecommendType(recommendType, count);
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateSpuStock(Map<Long, Integer> stockIncrCounts) {

+ 8 - 4
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java

@@ -15,11 +15,15 @@ import java.util.Arrays;
 @AllArgsConstructor
 public enum PromotionTypeEnum implements IntArrayValuable {
 
-    DISCOUNT_ACTIVITY(1, "限时折扣"),
-    REWARD_ACTIVITY(2, "满减送"),
+    SECKILL_ACTIVITY(1, "秒杀活动"),
+    BARGAIN_ACTIVITY(2, "拼团活动"),
+    COMBINATION_ACTIVITY(3, "砍价活动"),
 
-    MEMBER(3, "会员折扣"), // TODO 芋艿:待实现 StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice)
-    COUPON(4, "优惠劵")
+    DISCOUNT_ACTIVITY(4, "限时折扣"),
+    REWARD_ACTIVITY(5, "满减送"),
+
+    MEMBER(6, "会员折扣"),
+    COUPON(7, "优惠劵")
     ;
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray();

+ 0 - 24
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java

@@ -1,24 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.app;
-
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-@Tag(name = "用户 App - 营销")
-@RestController
-@RequestMapping("/market/test")
-@Validated
-public class AppMarketTestController {
-
-    @GetMapping("/get")
-    @Operation(summary = "获取 market 信息")
-    public CommonResult<String> get() {
-        return success("true");
-    }
-}

+ 65 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java

@@ -0,0 +1,65 @@
+package cn.iocoder.yudao.module.promotion.controller.app.activity;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.promotion.controller.app.activity.vo.AppActivityRespVO;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDateTime;
+import java.util.*;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "用户 APP - 营销活动") // 用于提供跨多个活动的 HTTP 接口
+@RestController
+@RequestMapping("/promotion/activity")
+@Validated
+public class AppActivityController {
+
+    @GetMapping("/list-by-spu-id")
+    @Operation(summary = "获得单个商品,近期参与的每个活动") // 每种活动,只返回一个
+    @Parameter(name = "spuId", description = "商品编号", required = true)
+    public CommonResult<List<AppActivityRespVO>> getActivityListBySpuId(@RequestParam("spuId") Long spuId) {
+        // TODO 芋艿,实现
+        List<AppActivityRespVO> randomList = new ArrayList<>();
+        Random random = new Random();
+        for (int i = 0; i < 3; i++) { // 生成5个随机对象
+            AppActivityRespVO vo = new AppActivityRespVO();
+            vo.setId(random.nextLong()); // 随机生成一个长整型 ID
+            vo.setType(i + 1); // 随机生成一个介于0到2之间的整数,对应枚举类型的三种类型之一
+            vo.setName(String.format("活动%d", random.nextInt(100))); // 随机生成一个类似于“活动XX”的活动名称,XX为0到99之间的随机整数
+            vo.setStartTime(LocalDateTime.now()); // 随机生成一个在过去的一年内的开始时间(以毫秒为单位)
+            vo.setEndTime(LocalDateTime.now()); // 随机生成一个在未来的一年内的结束时间(以毫秒为单位)
+            randomList.add(vo);
+        }
+        return success(randomList);
+    }
+
+    @GetMapping("/list-by-spu-ids")
+    @Operation(summary = "获得多个商品,近期参与的每个活动") // 每种活动,只返回一个;key 为 SPU 编号
+    @Parameter(name = "spuIds", description = "商品编号数组", required = true)
+    public CommonResult<Map<Long, List<AppActivityRespVO>>> getActivityListBySpuIds(@RequestParam("spuIds") List<Long> spuIds) {
+        // TODO 芋艿,实现
+        List<AppActivityRespVO> randomList = new ArrayList<>();
+        Random random = new Random();
+        for (int i = 0; i < 5; i++) { // 生成5个随机对象
+            AppActivityRespVO vo = new AppActivityRespVO();
+            vo.setId(random.nextLong()); // 随机生成一个长整型 ID
+            vo.setType(random.nextInt(3)); // 随机生成一个介于0到2之间的整数,对应枚举类型的三种类型之一
+            vo.setName(String.format("活动%d", random.nextInt(100))); // 随机生成一个类似于“活动XX”的活动名称,XX为0到99之间的随机整数
+            vo.setStartTime(LocalDateTime.now()); // 随机生成一个在过去的一年内的开始时间(以毫秒为单位)
+            vo.setEndTime(LocalDateTime.now()); // 随机生成一个在未来的一年内的结束时间(以毫秒为单位)
+            randomList.add(vo);
+        }
+        Map<Long, List<AppActivityRespVO>> map = new HashMap<>();
+        map.put(109L, randomList);
+        return success(map);
+    }
+
+}

+ 27 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/vo/AppActivityRespVO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.promotion.controller.app.activity.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "用户 App - 营销活动 Response VO")
+@Data
+public class AppActivityRespVO {
+
+    @Schema(description = "活动编号", required = true, example = "1024")
+    private Long id;
+
+    @Schema(description = "活动类型", required = true, example = "1") // 对应 PromotionTypeEnum 枚举
+    private Integer type;
+
+    @Schema(description = "活动名称", required = true, example = "618 大促")
+    private String name;
+
+    @Schema(description = "活动开始时间", required = true)
+    private LocalDateTime startTime;
+
+    @Schema(description = "活动结束时间", required = true)
+    private LocalDateTime endTime;
+
+}

+ 2 - 4
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderTypeEnum.java

@@ -17,10 +17,8 @@ public enum TradeOrderTypeEnum implements IntArrayValuable {
 
     NORMAL(0, "普通订单"),
     SECKILL(1, "秒杀订单"),
-    // TODO 芋艿:如下三个字段,名字需要改下,等后面表设计完成后。
-    KANJIA(2, "砍价订单"),
-    PINTUAN(3, "拼团订单"),
-    YUSHOU(4, "预售订单"),
+    BARGAIN(2, "砍价订单"),
+    COMBINATION(3, "拼团订单"),
     ;
 
     public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TradeOrderTypeEnum::getType).toArray();