Commit 41d996f7f3d940b3bba2bd63d457a3f4c8fe8c8c

Authored by puhui999
1 parent c5630518

feat:mall promotion CombinationProduct

Showing 28 changed files with 531 additions and 136 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
... ... @@ -61,4 +61,5 @@ public interface ErrorCodeConstants {
61 61  
62 62 // ========== 拼团活动 1013010000 ==========
63 63 ErrorCode COMBINATION_ACTIVITY_NOT_EXISTS = new ErrorCode(1013010000, "拼团活动不存在");
  64 + ErrorCode COMBINATION_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013010000, "存在商品参加了其它拼团活动");
64 65 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
... ... @@ -4,9 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
6 6 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
7   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.*;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.*;
8 8 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
9   -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
  9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
10 10 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
11 11 import io.swagger.v3.oas.annotations.Operation;
12 12 import io.swagger.v3.oas.annotations.Parameter;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/CombinationActivityBaseVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
1   -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo;
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
... ... @@ -6,6 +6,7 @@ import org.springframework.format.annotation.DateTimeFormat;
6 6  
7 7 import javax.validation.constraints.NotNull;
8 8 import java.time.LocalDateTime;
  9 +import java.util.List;
9 10  
10 11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
11 12  
... ... @@ -16,12 +17,13 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
16 17 @Data
17 18 public class CombinationActivityBaseVO {
18 19  
19   - @Schema(description = "拼团名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
  20 + @Schema(description = "拼团名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "越拼越省钱")
20 21 @NotNull(message = "拼团名称不能为空")
21 22 private String name;
22 23  
23   - @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "14016")
24   - private Long spuId;
  24 + @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "[1,2,3]")
  25 + @NotNull(message = "拼团商品不能为空")
  26 + private List<Long> spuIds;
25 27  
26 28 @Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
27 29 @NotNull(message = "总限购数量不能为空")
... ... @@ -31,40 +33,15 @@ public class CombinationActivityBaseVO {
31 33 @NotNull(message = "单次限购数量不能为空")
32 34 private Integer singleLimitCount;
33 35  
34   - @Schema(description = "开始时间", requiredMode = Schema.RequiredMode.REQUIRED)
35   - @NotNull(message = "开始时间不能为空")
  36 + @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
  37 + @NotNull(message = "活动时间不能为空")
36 38 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
37   - private LocalDateTime startTime;
38   -
39   - @Schema(description = "结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
40   - @NotNull(message = "结束时间不能为空")
41   - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
42   - private LocalDateTime endTime;
43   -
44   - @Schema(description = "购买人数", requiredMode = Schema.RequiredMode.REQUIRED)
45   - @NotNull(message = "购买人数不能为空")
46   - private Integer userSize;
47   -
48   - @Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED)
49   - @NotNull(message = "开团组数不能为空")
50   - private Integer totalNum;
51   -
52   - @Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED)
53   - @NotNull(message = "成团组数不能为空")
54   - private Integer successNum;
  39 + private LocalDateTime[] activityTime;
55 40  
56 41 @Schema(description = "参与人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
57 42 @NotNull(message = "参与人数不能为空")
58 43 private Integer orderUserCount;
59 44  
60   - @Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED)
61   - @NotNull(message = "虚拟成团不能为空")
62   - private Integer virtualGroup;
63   -
64   - @Schema(description = "活动状态:0开启 1关闭", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
65   - @NotNull(message = "活动状态:0开启 1关闭不能为空")
66   - private Integer status;
67   -
68 45 @Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED)
69 46 @NotNull(message = "限制时长(小时)不能为空")
70 47 private Integer limitDuration;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.List;
  10 +
  11 +@Schema(description = "管理后台 - 拼团活动创建 Request VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
  16 +
  17 + @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
  18 + private List<CombinationProductCreateReqVO> products;
  19 +
  20 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/CombinationActivityExcelVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExcelVO.java
1   -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo;
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
2 2  
3 3 import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
4 4 import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/CombinationActivityExportReqVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExportReqVO.java
1   -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo;
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/CombinationActivityPageReqVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityPageReqVO.java
1   -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo;
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 4 import io.swagger.v3.oas.annotations.media.Schema;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +import java.time.LocalDateTime;
  10 +
  11 +@Schema(description = "管理后台 - 拼团活动 Response VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class CombinationActivityRespVO extends CombinationActivityBaseVO {
  16 +
  17 + @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
  18 + private Long id;
  19 +
  20 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  21 + private LocalDateTime createTime;
  22 +
  23 + @Schema(description = "购买人数", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @NotNull(message = "购买人数不能为空")
  25 + private Integer userSize;
  26 +
  27 + @Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + @NotNull(message = "开团组数不能为空")
  29 + private Integer totalNum;
  30 +
  31 + @Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED)
  32 + @NotNull(message = "成团组数不能为空")
  33 + private Integer successNum;
  34 +
  35 + @Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED)
  36 + @NotNull(message = "虚拟成团不能为空")
  37 + private Integer virtualGroup;
  38 +
  39 + @Schema(description = "活动状态:0开启 1关闭", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  40 + @NotNull(message = "活动状态:0开启 1关闭不能为空")
  41 + private Integer status;
  42 +
  43 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/CombinationActivityUpdateReqVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java
1   -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo;
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +/**
  9 + * 拼团商品 Base VO,提供给添加、修改、详细的子 VO 使用
  10 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 + */
  12 +@Data
  13 +public class CombinationProductBaseVO {
  14 +
  15 + @Schema(description = "商品 spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
  16 + @NotNull(message = "商品 spuId 不能为空")
  17 + private Long spuId;
  18 +
  19 + @Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "30563")
  20 + @NotNull(message = "商品 skuId 不能为空")
  21 + private Long skuId;
  22 +
  23 + @Schema(description = "拼团价格,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "27682")
  24 + @NotNull(message = "拼团价格,单位分不能为空")
  25 + private Integer activePrice;
  26 +
  27 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/CombinationActivityCreateReqVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductCreateReqVO.java
1   -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo;
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5 import lombok.EqualsAndHashCode;
6 6 import lombok.ToString;
7 7  
8   -@Schema(description = "管理后台 - 拼团活动创建 Request VO")
  8 +@Schema(description = "管理后台 - 拼团商品创建 Request VO")
9 9 @Data
10 10 @EqualsAndHashCode(callSuper = true)
11 11 @ToString(callSuper = true)
12   -public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
  12 +public class CombinationProductCreateReqVO extends CombinationProductBaseVO {
13 13  
14 14 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import com.alibaba.excel.annotation.ExcelProperty;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * 拼团商品 Excel VO
  10 + *
  11 + * @author HUIHUI
  12 + */
  13 +@Data
  14 +public class CombinationProductExcelVO {
  15 +
  16 + @ExcelProperty("编号")
  17 + private Long id;
  18 +
  19 + @ExcelProperty("拼团活动编号")
  20 + private Long activityId;
  21 +
  22 + @ExcelProperty("商品 SPU 编号")
  23 + private Long spuId;
  24 +
  25 + @ExcelProperty("商品 SKU 编号")
  26 + private Long skuId;
  27 +
  28 + @ExcelProperty("拼团商品状态")
  29 + private Integer activityStatus;
  30 +
  31 + @ExcelProperty("活动开始时间点")
  32 + private LocalDateTime activityStartTime;
  33 +
  34 + @ExcelProperty("活动结束时间点")
  35 + private LocalDateTime activityEndTime;
  36 +
  37 + @ExcelProperty("拼团价格,单位分")
  38 + private Integer activePrice;
  39 +
  40 + @ExcelProperty("创建时间")
  41 + private LocalDateTime createTime;
  42 +
  43 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import java.time.LocalDateTime;
  8 +
  9 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  10 +
  11 +@Schema(description = "管理后台 - 拼团商品 Excel 导出 Request VO,参数和 CombinationProductPageReqVO 是一致的")
  12 +@Data
  13 +public class CombinationProductExportReqVO {
  14 +
  15 + @Schema(description = "拼团活动编号", example = "6829")
  16 + private Long activityId;
  17 +
  18 + @Schema(description = "商品 SPU 编号", example = "18731")
  19 + private Long spuId;
  20 +
  21 + @Schema(description = "商品 SKU 编号", example = "31675")
  22 + private Long skuId;
  23 +
  24 + @Schema(description = "拼团商品状态", example = "2")
  25 + private Integer activityStatus;
  26 +
  27 + @Schema(description = "活动开始时间点")
  28 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  29 + private LocalDateTime[] activityStartTime;
  30 +
  31 + @Schema(description = "活动结束时间点")
  32 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  33 + private LocalDateTime[] activityEndTime;
  34 +
  35 + @Schema(description = "拼团价格,单位分", example = "27682")
  36 + private Integer activePrice;
  37 +
  38 + @Schema(description = "创建时间")
  39 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  40 + private LocalDateTime[] createTime;
  41 +
  42 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 拼团商品分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class CombinationProductPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "拼团活动编号", example = "6829")
  21 + private Long activityId;
  22 +
  23 + @Schema(description = "商品 SPU 编号", example = "18731")
  24 + private Long spuId;
  25 +
  26 + @Schema(description = "商品 SKU 编号", example = "31675")
  27 + private Long skuId;
  28 +
  29 + @Schema(description = "拼团商品状态", example = "2")
  30 + private Integer activityStatus;
  31 +
  32 + @Schema(description = "活动开始时间点")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] activityStartTime;
  35 +
  36 + @Schema(description = "活动结束时间点")
  37 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  38 + private LocalDateTime[] activityEndTime;
  39 +
  40 + @Schema(description = "拼团价格,单位分", example = "27682")
  41 + private Integer activePrice;
  42 +
  43 + @Schema(description = "创建时间")
  44 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  45 + private LocalDateTime[] createTime;
  46 +
  47 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/CombinationActivityRespVO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductRespVO.java
1   -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo;
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
... ... @@ -7,13 +7,13 @@ import lombok.ToString;
7 7  
8 8 import java.time.LocalDateTime;
9 9  
10   -@Schema(description = "管理后台 - 拼团活动 Response VO")
  10 +@Schema(description = "管理后台 - 拼团商品 Response VO")
11 11 @Data
12 12 @EqualsAndHashCode(callSuper = true)
13 13 @ToString(callSuper = true)
14   -public class CombinationActivityRespVO extends CombinationActivityBaseVO {
  14 +public class CombinationProductRespVO extends CombinationProductBaseVO {
15 15  
16   - @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
  16 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
17 17 private Long id;
18 18  
19 19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "管理后台 - 拼团商品更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class CombinationProductUpdateReqVO extends CombinationProductBaseVO {
  15 +
  16 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
  17 + @NotNull(message = "编号不能为空")
  18 + private Long id;
  19 +
  20 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
1 1 package cn.iocoder.yudao.module.promotion.convert.combination;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityCreateReqVO;
5   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityExcelVO;
6   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityRespVO;
7   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityUpdateReqVO;
8   -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
  4 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExcelVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
  9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  10 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
9 11 import org.mapstruct.Mapper;
  12 +import org.mapstruct.Mapping;
10 13 import org.mapstruct.factory.Mappers;
11 14  
  15 +import java.util.ArrayList;
12 16 import java.util.List;
13 17  
14 18 /**
... ... @@ -21,6 +25,8 @@ public interface CombinationActivityConvert {
21 25  
22 26 CombinationActivityConvert INSTANCE = Mappers.getMapper(CombinationActivityConvert.class);
23 27  
  28 + @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])")
  29 + @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
24 30 CombinationActivityDO convert(CombinationActivityCreateReqVO bean);
25 31  
26 32 CombinationActivityDO convert(CombinationActivityUpdateReqVO bean);
... ... @@ -33,4 +39,19 @@ public interface CombinationActivityConvert {
33 39  
34 40 List<CombinationActivityExcelVO> convertList02(List<CombinationActivityDO> list);
35 41  
  42 + default List<CombinationProductDO> convertList(CombinationActivityDO activityDO, List<CombinationProductCreateReqVO> products) {
  43 + ArrayList<CombinationProductDO> productDOs = new ArrayList<>();
  44 + products.forEach(item -> {
  45 + CombinationProductDO productDO = new CombinationProductDO();
  46 + productDO.setActivityId(activityDO.getId());
  47 + productDO.setSpuId(item.getSpuId());
  48 + productDO.setSkuId(item.getSkuId());
  49 + productDO.setActivityStatus(0); // TODO 拼团状态枚举未定义不确定有些什么状态
  50 + productDO.setActivityStartTime(activityDO.getStartTime());
  51 + productDO.setActivityEndTime(activityDO.getEndTime());
  52 + productDO.setActivePrice(item.getActivePrice());
  53 + productDOs.add(productDO);
  54 + });
  55 + return productDOs;
  56 + }
36 57 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationActivityDO.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationActivityDO.java
1   -package cn.iocoder.yudao.module.promotion.dal.dataobject.combination;
  1 +package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
4 6 import com.baomidou.mybatisplus.annotation.KeySequence;
  7 +import com.baomidou.mybatisplus.annotation.TableField;
5 8 import com.baomidou.mybatisplus.annotation.TableId;
6 9 import com.baomidou.mybatisplus.annotation.TableName;
7   -import com.sun.xml.internal.bind.v2.TODO;
8 10 import lombok.*;
9 11  
10 12 import java.time.LocalDateTime;
  13 +import java.util.List;
11 14  
12 15 /**
13 16 * 拼团活动 DO
... ... @@ -36,7 +39,8 @@ public class CombinationActivityDO extends BaseDO {
36 39 /**
37 40 * 商品 SPU 编号关联 ProductSpuDO 的 id
38 41 */
39   - private Long spuId;
  42 + @TableField(typeHandler = LongListTypeHandler.class)
  43 + private List<Long> spuIds;
40 44 /**
41 45 * 总限购数量
42 46 */
... ... @@ -76,7 +80,7 @@ public class CombinationActivityDO extends BaseDO {
76 80 /**
77 81 * 活动状态:0开启 1关闭
78 82 * <p>
79   - * 枚举 {@link TODO common_status 对应的类}
  83 + * 枚举 {@link CommonStatusEnum}
80 84 */
81 85 private Integer status;
82 86 /**
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationProductDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +/**
  12 + * 拼团商品 DO
  13 + *
  14 + * @author HUIHUI
  15 + */
  16 +@TableName("promotion_combination_product")
  17 +@KeySequence("promotion_combination_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  18 +@Data
  19 +@EqualsAndHashCode(callSuper = true)
  20 +@ToString(callSuper = true)
  21 +@Builder
  22 +@NoArgsConstructor
  23 +@AllArgsConstructor
  24 +public class CombinationProductDO extends BaseDO {
  25 +
  26 + /**
  27 + * 编号
  28 + */
  29 + @TableId
  30 + private Long id;
  31 + /**
  32 + * 拼团活动编号
  33 + */
  34 + private Long activityId;
  35 + /**
  36 + * 商品 SPU 编号
  37 + */
  38 + private Long spuId;
  39 + /**
  40 + * 商品 SKU 编号
  41 + */
  42 + private Long skuId;
  43 + /**
  44 + * 拼团商品状态
  45 + */
  46 + private Integer activityStatus;
  47 + /**
  48 + * 活动开始时间点
  49 + */
  50 + private LocalDateTime activityStartTime;
  51 + /**
  52 + * 活动结束时间点
  53 + */
  54 + private LocalDateTime activityEndTime;
  55 + /**
  56 + * 拼团价格,单位分
  57 + */
  58 + private Integer activePrice;
  59 +
  60 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.dataobject.combination;
0 2 \ No newline at end of file
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationActivityMapper.java
1   -package cn.iocoder.yudao.module.promotion.dal.mysql.combination;
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityExportReqVO;
7   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityPageReqVO;
8   -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
9 9 import org.apache.ibatis.annotations.Mapper;
10 10  
11 11 import java.util.List;
... ... @@ -21,39 +21,17 @@ public interface CombinationActivityMapper extends BaseMapperX&lt;CombinationActivi
21 21 default PageResult<CombinationActivityDO> selectPage(CombinationActivityPageReqVO reqVO) {
22 22 return selectPage(reqVO, new LambdaQueryWrapperX<CombinationActivityDO>()
23 23 .likeIfPresent(CombinationActivityDO::getName, reqVO.getName())
24   - .eqIfPresent(CombinationActivityDO::getSpuId, reqVO.getSpuId())
25   - .eqIfPresent(CombinationActivityDO::getTotalLimitCount, reqVO.getTotalLimitCount())
26   - .eqIfPresent(CombinationActivityDO::getSingleLimitCount, reqVO.getSingleLimitCount())
27   - .betweenIfPresent(CombinationActivityDO::getStartTime, reqVO.getStartTime())
28   - .betweenIfPresent(CombinationActivityDO::getEndTime, reqVO.getEndTime())
29   - .eqIfPresent(CombinationActivityDO::getUserSize, reqVO.getUserSize())
30   - .eqIfPresent(CombinationActivityDO::getTotalNum, reqVO.getTotalNum())
31   - .eqIfPresent(CombinationActivityDO::getSuccessNum, reqVO.getSuccessNum())
32   - .eqIfPresent(CombinationActivityDO::getOrderUserCount, reqVO.getOrderUserCount())
33   - .eqIfPresent(CombinationActivityDO::getVirtualGroup, reqVO.getVirtualGroup())
34   - .eqIfPresent(CombinationActivityDO::getStatus, reqVO.getStatus())
35   - .eqIfPresent(CombinationActivityDO::getLimitDuration, reqVO.getLimitDuration())
36   - .betweenIfPresent(CombinationActivityDO::getCreateTime, reqVO.getCreateTime())
37 24 .orderByDesc(CombinationActivityDO::getId));
38 25 }
39 26  
40 27 default List<CombinationActivityDO> selectList(CombinationActivityExportReqVO reqVO) {
41 28 return selectList(new LambdaQueryWrapperX<CombinationActivityDO>()
42 29 .likeIfPresent(CombinationActivityDO::getName, reqVO.getName())
43   - .eqIfPresent(CombinationActivityDO::getSpuId, reqVO.getSpuId())
44   - .eqIfPresent(CombinationActivityDO::getTotalLimitCount, reqVO.getTotalLimitCount())
45   - .eqIfPresent(CombinationActivityDO::getSingleLimitCount, reqVO.getSingleLimitCount())
46   - .betweenIfPresent(CombinationActivityDO::getStartTime, reqVO.getStartTime())
47   - .betweenIfPresent(CombinationActivityDO::getEndTime, reqVO.getEndTime())
48   - .eqIfPresent(CombinationActivityDO::getUserSize, reqVO.getUserSize())
49   - .eqIfPresent(CombinationActivityDO::getTotalNum, reqVO.getTotalNum())
50   - .eqIfPresent(CombinationActivityDO::getSuccessNum, reqVO.getSuccessNum())
51   - .eqIfPresent(CombinationActivityDO::getOrderUserCount, reqVO.getOrderUserCount())
52   - .eqIfPresent(CombinationActivityDO::getVirtualGroup, reqVO.getVirtualGroup())
53 30 .eqIfPresent(CombinationActivityDO::getStatus, reqVO.getStatus())
54   - .eqIfPresent(CombinationActivityDO::getLimitDuration, reqVO.getLimitDuration())
55   - .betweenIfPresent(CombinationActivityDO::getCreateTime, reqVO.getCreateTime())
56 31 .orderByDesc(CombinationActivityDO::getId));
57 32 }
58 33  
  34 + default List<CombinationActivityDO> selectListByStatus(Integer status) {
  35 + return selectList(CombinationActivityDO::getStatus, status);
  36 + }
59 37 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationProductMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductExportReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 拼团商品 Mapper
  15 + *
  16 + * @author HUIHUI
  17 + */
  18 +@Mapper
  19 +public interface CombinationProductMapper extends BaseMapperX<CombinationProductDO> {
  20 +
  21 + default PageResult<CombinationProductDO> selectPage(CombinationProductPageReqVO reqVO) {
  22 + return selectPage(reqVO, new LambdaQueryWrapperX<CombinationProductDO>()
  23 + .eqIfPresent(CombinationProductDO::getActivityId, reqVO.getActivityId())
  24 + .eqIfPresent(CombinationProductDO::getSpuId, reqVO.getSpuId())
  25 + .eqIfPresent(CombinationProductDO::getSkuId, reqVO.getSkuId())
  26 + .eqIfPresent(CombinationProductDO::getActivityStatus, reqVO.getActivityStatus())
  27 + .betweenIfPresent(CombinationProductDO::getActivityStartTime, reqVO.getActivityStartTime())
  28 + .betweenIfPresent(CombinationProductDO::getActivityEndTime, reqVO.getActivityEndTime())
  29 + .eqIfPresent(CombinationProductDO::getActivePrice, reqVO.getActivePrice())
  30 + .betweenIfPresent(CombinationProductDO::getCreateTime, reqVO.getCreateTime())
  31 + .orderByDesc(CombinationProductDO::getId));
  32 + }
  33 +
  34 + default List<CombinationProductDO> selectList(CombinationProductExportReqVO reqVO) {
  35 + return selectList(new LambdaQueryWrapperX<CombinationProductDO>()
  36 + .eqIfPresent(CombinationProductDO::getActivityId, reqVO.getActivityId())
  37 + .eqIfPresent(CombinationProductDO::getSpuId, reqVO.getSpuId())
  38 + .eqIfPresent(CombinationProductDO::getSkuId, reqVO.getSkuId())
  39 + .eqIfPresent(CombinationProductDO::getActivityStatus, reqVO.getActivityStatus())
  40 + .betweenIfPresent(CombinationProductDO::getActivityStartTime, reqVO.getActivityStartTime())
  41 + .betweenIfPresent(CombinationProductDO::getActivityEndTime, reqVO.getActivityEndTime())
  42 + .eqIfPresent(CombinationProductDO::getActivePrice, reqVO.getActivePrice())
  43 + .betweenIfPresent(CombinationProductDO::getCreateTime, reqVO.getCreateTime())
  44 + .orderByDesc(CombinationProductDO::getId));
  45 + }
  46 +
  47 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.combination;
0 2 \ No newline at end of file
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
1 1 package cn.iocoder.yudao.module.promotion.service.combination;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityCreateReqVO;
5   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityExportReqVO;
6   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityPageReqVO;
7   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityUpdateReqVO;
8   -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
  4 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
9 9  
10 10 import javax.validation.Valid;
11 11 import java.util.Collection;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
1 1 package cn.iocoder.yudao.module.promotion.service.combination;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityCreateReqVO;
5   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityExportReqVO;
6   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityPageReqVO;
7   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityUpdateReqVO;
  7 +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
  8 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  9 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  10 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  11 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  12 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  13 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  14 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
8 16 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
9   -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
10   -import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationActivityMapper;
  17 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  18 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
  19 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationActivityMapper;
  20 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationProductMapper;
11 21 import org.springframework.stereotype.Service;
12 22 import org.springframework.validation.annotation.Validated;
13 23  
14 24 import javax.annotation.Resource;
  25 +import java.util.ArrayList;
15 26 import java.util.Collection;
16 27 import java.util.List;
  28 +import java.util.stream.Collectors;
17 29  
18 30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  31 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
19 32 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_NOT_EXISTS;
  33 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_SPU_CONFLICTS;
  34 +import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuExistence;
20 35  
21 36 /**
22 37 * 拼团活动 Service 实现类
... ... @@ -29,14 +44,59 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
29 44  
30 45 @Resource
31 46 private CombinationActivityMapper combinationActivityMapper;
  47 + @Resource
  48 + private CombinationProductMapper combinationProductMapper;
  49 + @Resource
  50 + private ProductSpuApi productSpuApi;
  51 + @Resource
  52 + private ProductSkuApi productSkuApi;
32 53  
33 54 @Override
34 55 public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) {
35   - // 插入
36   - CombinationActivityDO combinationActivity = CombinationActivityConvert.INSTANCE.convert(createReqVO);
37   - combinationActivityMapper.insert(combinationActivity);
  56 + // 校验商品 SPU 是否存在是否参加的别的活动
  57 + validateProductCombinationConflict(createReqVO.getSpuIds());
  58 + // 获取所选 spu下的所有 sku
  59 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(createReqVO.getSpuIds());
  60 + // 校验商品 sku 是否存在
  61 + validateProductSkuExistence(skus, createReqVO.getProducts(), CombinationProductCreateReqVO::getSkuId);
  62 +
  63 + // TODO 艿艿 有个小问题:现在有活动时间和限制时长,活动时间的结束时间早于设置的限制时间怎么算状态比如:
  64 + // 活动时间 2023-08-05 15:00:00 - 2023-08-05 15:20:00 限制时长 2小时,那么活动时间结束就结束还是加时到满两小时
  65 + // 插入拼团活动
  66 + CombinationActivityDO activityDO = CombinationActivityConvert.INSTANCE.convert(createReqVO);
  67 + // TODO 营销相关属性初始化
  68 + activityDO.setUserSize(0);
  69 + activityDO.setTotalNum(0);
  70 + activityDO.setSuccessNum(0);
  71 + activityDO.setOrderUserCount(0);
  72 + activityDO.setVirtualGroup(0);
  73 + activityDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  74 + combinationActivityMapper.insert(activityDO);
  75 + // 插入商品
  76 + List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList(activityDO, createReqVO.getProducts());
  77 + combinationProductMapper.insertBatch(productDOs);
38 78 // 返回
39   - return combinationActivity.getId();
  79 + return activityDO.getId();
  80 + }
  81 +
  82 + private void validateProductCombinationConflict(List<Long> spuIds) {
  83 + // 校验商品 spu 是否存在
  84 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);
  85 + if (ObjectUtil.notEqual(spuIds.size(), spuList.size())) {
  86 + throw exception(SPU_NOT_EXISTS);
  87 + }
  88 + // 查询所有开启的秒杀活动
  89 + List<CombinationActivityDO> activityDOs = combinationActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
  90 + // 过滤出所有 spuIds 有交集的活动
  91 + List<CombinationActivityDO> doList = activityDOs.stream().filter(s -> {
  92 + // 判断 spu 是否有交集
  93 + ArrayList<Long> spuIdsClone = CollUtil.newArrayList(s.getSpuIds());
  94 + spuIdsClone.retainAll(spuIds);
  95 + return CollUtil.isNotEmpty(spuIdsClone);
  96 + }).collect(Collectors.toList());
  97 + if (CollUtil.isNotEmpty(doList)) {
  98 + throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS);
  99 + }
40 100 }
41 101  
42 102 @Override
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
... ... @@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjectUtil;
5 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
9 8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
10 9 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
... ... @@ -12,7 +11,8 @@ import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
12 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
13 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
14 13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
15   -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
  14 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductCreateReqVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO;
16 16 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
17 17 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
18 18 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
... ... @@ -28,13 +28,12 @@ import javax.annotation.Resource;
28 28 import java.util.ArrayList;
29 29 import java.util.Collection;
30 30 import java.util.List;
31   -import java.util.Set;
32 31 import java.util.stream.Collectors;
33 32  
34 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
35   -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
36 34 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
37 35 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
  36 +import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuExistence;
38 37 import static java.util.Arrays.asList;
39 38  
40 39 /**
... ... @@ -61,8 +60,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
61 60 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
62 61 // 校验商品秒秒杀时段是否冲突
63 62 validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuIds());
  63 + // 获取所选 spu下的所有 sku
  64 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(createReqVO.getSpuIds());
64 65 // 校验商品 sku 是否存在
65   - validateProductSkuExistence(createReqVO.getSpuIds(), createReqVO.getProducts());
  66 + validateProductSkuExistence(skus, createReqVO.getProducts(), SeckillProductCreateReqVO::getSkuId);
66 67  
67 68 // 插入秒杀活动
68 69 SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
... ... @@ -74,28 +75,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
74 75 return activity.getId();
75 76 }
76 77  
77   - private <T extends SeckillProductBaseVO> void validateProductSkuExistence(List<Long> spuIds, List<T> products) {
78   - // 校验 spu 个数是否相等
79   - // TODO @puhui999:不用校验 SPU 哈,只校验 sku 对应的 spuId 是否一致;
80   - Set<Long> convertedSpuIds = CollectionUtils.convertSet(products, T::getSpuId);
81   - if (ObjectUtil.notEqual(spuIds.size(), convertedSpuIds.size())) {
82   - throw exception(SKU_NOT_EXISTS);
83   - }
84   - // 获取所选 spu下的所有 sku
85   - // TODO @puhui999:变量可以简单一点;skus
86   - List<ProductSkuRespDTO> skuRespDTOs = productSkuApi.getSkuListBySpuId(spuIds);
87   - // 校验 sku 个数是否一致
88   - Set<Long> skuIdsSet = CollectionUtils.convertSet(products, T::getSkuId);
89   - Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skuRespDTOs, ProductSkuRespDTO::getId);
90   - if (ObjectUtil.notEqual(skuIdsSet.size(), skuIdsSet1.size())) {
91   - throw exception(SKU_NOT_EXISTS);
92   - }
93   - // 校验 skuId 是否存在
94   - if (!skuIdsSet1.containsAll(skuIdsSet) || !skuIdsSet.containsAll(skuIdsSet1)) {
95   - throw exception(SKU_NOT_EXISTS);
96   - }
97   - }
98   -
99 78 private void validateProductSpuSeckillConflict(List<Long> configIds, List<Long> spuIds) {
100 79 // 校验秒杀时段是否存在
101 80 seckillConfigService.validateSeckillConfigExists(configIds);
... ... @@ -133,8 +112,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
133 112 }
134 113 // 校验商品是否冲突
135 114 validateProductSpuSeckillConflict(updateReqVO.getConfigIds(), updateReqVO.getSpuIds());
  115 + // 获取所选 spu下的所有 sku
  116 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(updateReqVO.getSpuIds());
136 117 // 校验商品 sku 是否存在
137   - validateProductSkuExistence(updateReqVO.getSpuIds(), updateReqVO.getProducts());
  118 + validateProductSkuExistence(skus, updateReqVO.getProducts(), SeckillProductUpdateReqVO::getSkuId);
138 119  
139 120 // 更新活动
140 121 SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java
1 1 package cn.iocoder.yudao.module.promotion.util;
2 2  
  3 +import cn.hutool.core.util.ObjectUtil;
3 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 6 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
  7 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
5 8  
6 9 import java.time.LocalDateTime;
  10 +import java.util.List;
  11 +import java.util.Set;
  12 +import java.util.function.Function;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  15 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
7 16  
8 17 /**
9 18 * 活动工具类
... ... @@ -22,4 +31,17 @@ public class PromotionUtils {
22 31 return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus();
23 32 }
24 33  
  34 + public static <T> void validateProductSkuExistence(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) {
  35 + // 校验 sku 个数是否一致
  36 + Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func);
  37 + Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skus, ProductSkuRespDTO::getId);
  38 + if (ObjectUtil.notEqual(skuIdsSet.size(), skuIdsSet1.size())) {
  39 + throw exception(SKU_NOT_EXISTS);
  40 + }
  41 + // 校验 skuId 是否存在
  42 + if (!skuIdsSet1.containsAll(skuIdsSet) || !skuIdsSet.containsAll(skuIdsSet1)) {
  43 + throw exception(SKU_NOT_EXISTS);
  44 + }
  45 + }
  46 +
25 47 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java
... ... @@ -2,12 +2,12 @@ package cn.iocoder.yudao.module.promotion.service.combination;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityCreateReqVO;
6   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityExportReqVO;
7   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityPageReqVO;
8   -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.CombinationActivityUpdateReqVO;
9   -import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
10   -import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationActivityMapper;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExportReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  10 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.combinationactivity.CombinationActivityMapper;
11 11 import org.junit.jupiter.api.Disabled;
12 12 import org.junit.jupiter.api.Test;
13 13 import org.springframework.context.annotation.Import;
... ... @@ -107,7 +107,7 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest {
107 107 // mock 数据
108 108 CombinationActivityDO dbCombinationActivity = randomPojo(CombinationActivityDO.class, o -> { // 等会查询到
109 109 o.setName(null);
110   - o.setSpuId(null);
  110 + //o.setSpuId(null);
111 111 o.setTotalLimitCount(null);
112 112 o.setSingleLimitCount(null);
113 113 o.setStartTime(null);
... ... @@ -125,7 +125,7 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest {
125 125 // 测试 name 不匹配
126 126 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setName(null)));
127 127 // 测试 spuId 不匹配
128   - combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSpuId(null)));
  128 + //combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSpuId(null)));
129 129 // 测试 totalLimitCount 不匹配
130 130 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalLimitCount(null)));
131 131 // 测试 singleLimitCount 不匹配
... ... @@ -181,7 +181,7 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest {
181 181 // mock 数据
182 182 CombinationActivityDO dbCombinationActivity = randomPojo(CombinationActivityDO.class, o -> { // 等会查询到
183 183 o.setName(null);
184   - o.setSpuId(null);
  184 + //o.setSpuId(null);
185 185 o.setTotalLimitCount(null);
186 186 o.setSingleLimitCount(null);
187 187 o.setStartTime(null);
... ... @@ -199,7 +199,7 @@ public class CombinationActivityServiceImplTest extends BaseDbUnitTest {
199 199 // 测试 name 不匹配
200 200 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setName(null)));
201 201 // 测试 spuId 不匹配
202   - combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSpuId(null)));
  202 + //combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setSpuId(null)));
203 203 // 测试 totalLimitCount 不匹配
204 204 combinationActivityMapper.insert(cloneIgnoreId(dbCombinationActivity, o -> o.setTotalLimitCount(null)));
205 205 // 测试 singleLimitCount 不匹配
... ...