Commit 5f9184904a9312c9346778c173b765bc8fd14e12

Authored by puhui999
1 parent afaef0df

fix: 完善拼团、秒杀、砍价活动管理

Showing 32 changed files with 1284 additions and 247 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.framework.common.util.collection;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.collection.CollectionUtil;
5   -import cn.hutool.core.map.MapUtil;
6 5 import com.google.common.collect.ImmutableMap;
7 6  
8 7 import java.util.*;
... ... @@ -26,8 +25,7 @@ public class CollectionUtils {
26 25 return Arrays.stream(collections).anyMatch(CollectionUtil::isEmpty);
27 26 }
28 27  
29   - // TODO @puhui999:anyMatch 更统一点
30   - public static <T> boolean isAny(Collection<T> from, Predicate<T> predicate) {
  28 + public static <T> boolean anyMatch(Collection<T> from, Predicate<T> predicate) {
31 29 return from.stream().anyMatch(predicate);
32 30 }
33 31  
... ... @@ -155,41 +153,6 @@ public class CollectionUtils {
155 153 }
156 154  
157 155 /**
158   - * 数据划分为需要新增的、还是删除的、还是更新的。
159   - *
160   - * @param list1 需要处理的数据的相关编号列表
161   - * @param list2 数据库中存在的数据的相关编号列表
162   - * @param func 比较出哪些记录是新增,还是修改,还是删除
163   - * @return 包含需要新增、修改、删除的数据 Map 对象
164   - */
165   - public static <D> Map<String, List<D>> convertCDUMap(Collection<Long> list1, Collection<Long> list2,
166   - Function<Map<String, List<Long>>, Map<String, List<D>>> func) {
167   - HashMap<String, List<Long>> mapData = MapUtil.newHashMap(3);
168   - if (CollUtil.isEmpty(list1)) {
169   - return func.apply(mapData);
170   - }
171   - if (CollUtil.isEmpty(list2)) {
172   - return func.apply(mapData);
173   - }
174   - // 后台存在的前端不存在的
175   - List<Long> d = CollectionUtils.filterList(list2, item -> !list1.contains(item));
176   - if (CollUtil.isNotEmpty(d)) {
177   - mapData.put("delete", d);
178   - }
179   - // 前端存在的后端不存在的
180   - List<Long> c = CollectionUtils.filterList(list1, item -> !list2.contains(item));
181   - if (CollUtil.isNotEmpty(c)) {
182   - mapData.put("create", c);
183   - }
184   - // 更新已存在的
185   - List<Long> u = CollectionUtils.filterList(list1, list2::contains);
186   - if (CollUtil.isNotEmpty(u)) {
187   - mapData.put("update", u);
188   - }
189   - return func.apply(mapData);
190   - }
191   -
192   - /**
193 156 * 对比老、新两个列表,找出新增、修改、删除的数据
194 157 *
195 158 * @param oldList 老列表
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
... ... @@ -69,4 +69,14 @@ public interface ErrorCodeConstants {
69 69 ErrorCode COMBINATION_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1013010006, "拼团失败,父拼团不存在");
70 70 ErrorCode COMBINATION_RECORD_USER_FULL = new ErrorCode(1013010006, "拼团失败,拼团人数已满");
71 71  
  72 + // ========== 砍价活动 1013011000 ==========
  73 + ErrorCode BARGAIN_ACTIVITY_NOT_EXISTS = new ErrorCode(1013011000, "砍价活动不存在");
  74 + ErrorCode BARGAIN_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013011001, "存在商品参加了其它砍价活动");
  75 + ErrorCode BARGAIN_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013011002, "砍价活动已关闭不能修改");
  76 + ErrorCode BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013011003, "砍价活动未关闭或未结束,不能删除");
  77 + ErrorCode BARGAIN_RECORD_NOT_EXISTS = new ErrorCode(1013011004, "砍价不存在");
  78 + ErrorCode BARGAIN_RECORD_EXISTS = new ErrorCode(1013011005, "砍价失败,已参与过该砍价");
  79 + ErrorCode BARGAIN_RECORD_HEAD_NOT_EXISTS = new ErrorCode(1013011006, "砍价失败,父砍价不存在");
  80 + ErrorCode BARGAIN_RECORD_USER_FULL = new ErrorCode(1013011007, "砍价失败,砍价人数已满");
  81 +
72 82 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityRespVO;
  9 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
  10 +import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
  11 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
  12 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
  13 +import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
  14 +import io.swagger.v3.oas.annotations.Operation;
  15 +import io.swagger.v3.oas.annotations.Parameter;
  16 +import io.swagger.v3.oas.annotations.tags.Tag;
  17 +import org.springframework.security.access.prepost.PreAuthorize;
  18 +import org.springframework.validation.annotation.Validated;
  19 +import org.springframework.web.bind.annotation.*;
  20 +
  21 +import javax.annotation.Resource;
  22 +import javax.validation.Valid;
  23 +import java.util.List;
  24 +import java.util.Set;
  25 +
  26 +import static cn.hutool.core.collection.CollectionUtil.newArrayList;
  27 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
  29 +
  30 +@Tag(name = "管理后台 - 砍价活动")
  31 +@RestController
  32 +@RequestMapping("/promotion/bargain-activity")
  33 +@Validated
  34 +public class BargainActivityController {
  35 +
  36 + @Resource
  37 + private BargainActivityService activityService;
  38 +
  39 + @Resource
  40 + private ProductSpuApi spuApi;
  41 +
  42 + @PostMapping("/create")
  43 + @Operation(summary = "创建砍价活动")
  44 + @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:create')")
  45 + public CommonResult<Long> createBargainActivity(@Valid @RequestBody BargainActivityCreateReqVO createReqVO) {
  46 + return success(activityService.createBargainActivity(createReqVO));
  47 + }
  48 +
  49 + @PutMapping("/update")
  50 + @Operation(summary = "更新砍价活动")
  51 + @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:update')")
  52 + public CommonResult<Boolean> updateBargainActivity(@Valid @RequestBody BargainActivityUpdateReqVO updateReqVO) {
  53 + activityService.updateBargainActivity(updateReqVO);
  54 + return success(true);
  55 + }
  56 +
  57 + @DeleteMapping("/delete")
  58 + @Operation(summary = "删除砍价活动")
  59 + @Parameter(name = "id", description = "编号", required = true)
  60 + @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:delete')")
  61 + public CommonResult<Boolean> deleteBargainActivity(@RequestParam("id") Long id) {
  62 + activityService.deleteBargainActivity(id);
  63 + return success(true);
  64 + }
  65 +
  66 + @GetMapping("/get")
  67 + @Operation(summary = "获得砍价活动")
  68 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  69 + @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:query')")
  70 + public CommonResult<BargainActivityRespVO> getBargainActivity(@RequestParam("id") Long id) {
  71 + BargainActivityDO activity = activityService.getBargainActivity(id);
  72 + List<BargainProductDO> products = activityService.getBargainProductsByActivityIds(newArrayList(id));
  73 + return success(BargainActivityConvert.INSTANCE.convert(activity, products));
  74 + }
  75 +
  76 + @GetMapping("/page")
  77 + @Operation(summary = "获得砍价活动分页")
  78 + @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:query')")
  79 + public CommonResult<PageResult<BargainActivityRespVO>> getBargainActivityPage(
  80 + @Valid BargainActivityPageReqVO pageVO) {
  81 + // 查询砍价活动
  82 + PageResult<BargainActivityDO> pageResult = activityService.getBargainActivityPage(pageVO);
  83 + // 拼接数据
  84 + Set<Long> activityIds = convertSet(pageResult.getList(), BargainActivityDO::getId);
  85 + Set<Long> spuIds = convertSet(pageResult.getList(), BargainActivityDO::getSpuId);
  86 + return success(BargainActivityConvert.INSTANCE.convertPage(pageResult,
  87 + activityService.getBargainProductsByActivityIds(activityIds),
  88 + spuApi.getSpuList(spuIds)));
  89 + }
  90 +
  91 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 + * 砍价活动 Base VO,提供给添加、修改、详细的子 VO 使用
  14 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 + *
  16 + * @author HUIHUI
  17 + */
  18 +@Data
  19 +public class BargainActivityBaseVO {
  20 +
  21 + @Schema(description = "砍价活动名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "越拼越省钱")
  22 + @NotNull(message = "砍价名称不能为空")
  23 + private String name;
  24 +
  25 + @Schema(description = "商品 SPU 编号,关联 ProductSpuDO 的 id", example = "[1,2,3]")
  26 + @NotNull(message = "砍价商品不能为空")
  27 + private Long spuId;
  28 +
  29 + @Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
  30 + @NotNull(message = "总限购数量不能为空")
  31 + private Integer totalLimitCount;
  32 +
  33 + @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
  34 + @NotNull(message = "活动开始时间不能为空")
  35 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  36 + private LocalDateTime startTime;
  37 +
  38 + @Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
  39 + @NotNull(message = "活动结束时间不能为空")
  40 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  41 + private LocalDateTime endTime;
  42 +
  43 + @Schema(description = "砍价人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
  44 + @NotNull(message = "砍价人数不能为空")
  45 + private Integer userSize;
  46 +
  47 + @Schema(description = "最大帮砍次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
  48 + @NotNull(message = "最大帮砍次数不能为空")
  49 + private Integer bargainCount;
  50 +
  51 + @Schema(description = "用户每次砍价的最小金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
  52 + @NotNull(message = "用户每次砍价的最小金额不能为空")
  53 + private Integer randomMinPrice;
  54 +
  55 + @Schema(description = "用户每次砍价的最大金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
  56 + @NotNull(message = "用户每次砍价的最大金额不能为空")
  57 + private Integer randomMaxPrice;
  58 +
  59 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductCreateReqVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import java.util.List;
  11 +
  12 +@Schema(description = "管理后台 - 砍价活动创建 Request VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class BargainActivityCreateReqVO extends BargainActivityBaseVO {
  17 +
  18 + @Schema(description = "砍价商品", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + @Valid
  20 + private List<BargainProductCreateReqVO> products;
  21 +
  22 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
  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 BargainActivityPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "砍价名称", example = "赵六")
  21 + private String name;
  22 +
  23 + @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "14016")
  24 + private Long spuId;
  25 +
  26 + @Schema(description = "总限购数量", example = "16218")
  27 + private Integer totalLimitCount;
  28 +
  29 + @Schema(description = "单次限购数量", example = "28265")
  30 + private Integer singleLimitCount;
  31 +
  32 + @Schema(description = "开始时间")
  33 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  34 + private LocalDateTime[] startTime;
  35 +
  36 + @Schema(description = "结束时间")
  37 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  38 + private LocalDateTime[] endTime;
  39 +
  40 + @Schema(description = "开团人数")
  41 + private Integer userSize;
  42 +
  43 + @Schema(description = "开团组数")
  44 + private Integer totalNum;
  45 +
  46 + @Schema(description = "成团组数")
  47 + private Integer successNum;
  48 +
  49 + @Schema(description = "参与人数", example = "25222")
  50 + private Integer orderUserCount;
  51 +
  52 + @Schema(description = "虚拟成团")
  53 + private Integer virtualGroup;
  54 +
  55 + @Schema(description = "活动状态:0开启 1关闭", example = "0")
  56 + private Integer status;
  57 +
  58 + @Schema(description = "限制时长(小时)")
  59 + private Integer limitDuration;
  60 +
  61 + @Schema(description = "创建时间")
  62 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  63 + private LocalDateTime[] createTime;
  64 +
  65 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductRespVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import javax.validation.constraints.NotNull;
  11 +import java.time.LocalDateTime;
  12 +import java.util.List;
  13 +
  14 +@Schema(description = "管理后台 - 砍价活动 Response VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class BargainActivityRespVO extends BargainActivityBaseVO {
  19 +
  20 + @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促")
  21 + private String spuName;
  22 +
  23 + @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
  24 + private String picUrl;
  25 +
  26 + @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
  27 + private Long id;
  28 +
  29 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  30 + private LocalDateTime createTime;
  31 +
  32 + @Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED)
  33 + @NotNull(message = "开团人数不能为空")
  34 + private Integer userSize;
  35 +
  36 + @Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED)
  37 + @NotNull(message = "开团组数不能为空")
  38 + private Integer totalNum;
  39 +
  40 + @Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED)
  41 + @NotNull(message = "成团组数不能为空")
  42 + private Integer successNum;
  43 +
  44 + @Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED)
  45 + @NotNull(message = "虚拟成团不能为空")
  46 + private Integer virtualGroup;
  47 +
  48 + @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  49 + @NotNull(message = "活动状态不能为空")
  50 + private Integer status;
  51 +
  52 + @Schema(description = "砍价商品", requiredMode = Schema.RequiredMode.REQUIRED)
  53 + @Valid
  54 + private List<BargainProductRespVO> products;
  55 +
  56 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductUpdateReqVO;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import javax.validation.Valid;
  10 +import javax.validation.constraints.NotNull;
  11 +import java.util.List;
  12 +
  13 +@Schema(description = "管理后台 - 砍价活动更新 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class BargainActivityUpdateReqVO extends BargainActivityBaseVO {
  18 +
  19 + @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
  20 + @NotNull(message = "活动编号不能为空")
  21 + private Long id;
  22 +
  23 + @Schema(description = "砍价商品", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @Valid
  25 + private List<BargainProductUpdateReqVO> products;
  26 +
  27 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.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 BargainProductBaseVO {
  14 +
  15 + @Schema(description = "商品 spuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "123")
  16 + @NotNull(message = "商品 spuId 不能为空")
  17 + private Long spuId;
  18 +
  19 + @Schema(description = "商品 skuId", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
  20 + @NotNull(message = "商品 skuId 不能为空")
  21 + private Long skuId;
  22 +
  23 + @Schema(description = "砍价起始价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
  24 + @NotNull(message = "砍价起始价格不能为空")
  25 + private Integer bargainFirstPrice;
  26 +
  27 + @Schema(description = "砍价底价", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
  28 + @NotNull(message = "砍价底价不能为空")
  29 + private Integer bargainPrice;
  30 +
  31 + @Schema(description = "活动库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "23")
  32 + @NotNull(message = "活动库存不能为空")
  33 + private Integer stock;
  34 +
  35 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.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 +@Schema(description = "管理后台 - 砍价商品创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class BargainProductCreateReqVO extends BargainProductBaseVO {
  13 +
  14 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.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 BargainProductPageReqVO 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/bargain/vo/product/BargainProductRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.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 java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 砍价商品 Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class BargainProductRespVO extends BargainProductBaseVO {
  15 +
  16 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private LocalDateTime createTime;
  21 +
  22 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.bargain.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 +@Schema(description = "管理后台 - 砍价商品更新 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class BargainProductUpdateReqVO extends BargainProductBaseVO {
  13 +
  14 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
... ... @@ -20,7 +20,6 @@ import org.springframework.web.bind.annotation.*;
20 20  
21 21 import javax.annotation.Resource;
22 22 import javax.validation.Valid;
23   -import java.util.Collection;
24 23 import java.util.List;
25 24 import java.util.Set;
26 25  
... ... @@ -74,16 +73,6 @@ public class CombinationActivityController {
74 73 return success(CombinationActivityConvert.INSTANCE.convert(activity, products));
75 74 }
76 75  
77   - // TODO @puhui999:是不是可以删掉,貌似没用?
78   - @GetMapping("/list")
79   - @Operation(summary = "获得拼团活动列表")
80   - @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
81   - @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
82   - public CommonResult<List<CombinationActivityRespVO>> getCombinationActivityList(@RequestParam("ids") Collection<Long> ids) {
83   - List<CombinationActivityDO> list = combinationActivityService.getCombinationActivityList(ids);
84   - return success(CombinationActivityConvert.INSTANCE.convertList(list));
85   - }
86   -
87 76 @GetMapping("/page")
88 77 @Operation(summary = "获得拼团活动分页")
89 78 @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
... ... @@ -12,6 +12,8 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
12 12 /**
13 13 * 拼团活动 Base VO,提供给添加、修改、详细的子 VO 使用
14 14 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 + *
  16 + * @author HUIHUI
15 17 */
16 18 @Data
17 19 public class CombinationActivityBaseVO {
... ... @@ -32,11 +34,15 @@ public class CombinationActivityBaseVO {
32 34 @NotNull(message = "单次限购数量不能为空")
33 35 private Integer singleLimitCount;
34 36  
35   - // TODO @puhui999:是不是弄成 2 个字段会好点哈。开始、结束
36   - @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
  37 + @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
37 38 @NotNull(message = "活动时间不能为空")
38 39 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
39   - private LocalDateTime[] activityTime;
  40 + private LocalDateTime startTime;
  41 +
  42 + @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 23:59:59]")
  43 + @NotNull(message = "活动时间不能为空")
  44 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  45 + private LocalDateTime endTime;
40 46  
41 47 @Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "25222")
42 48 @NotNull(message = "开团人数不能为空")
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java
... ... @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.controller.admin.seckill;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 5 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
7 6 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
8 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*;
... ... @@ -19,11 +18,11 @@ import org.springframework.web.bind.annotation.*;
19 18  
20 19 import javax.annotation.Resource;
21 20 import javax.validation.Valid;
22   -import java.util.Collection;
23 21 import java.util.List;
24 22 import java.util.Set;
25 23  
26 24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  25 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
27 26  
28 27 @Tag(name = "管理后台 - 秒杀活动")
29 28 @RestController
... ... @@ -79,24 +78,14 @@ public class SeckillActivityController {
79 78 return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity, seckillProducts));
80 79 }
81 80  
82   - // TODO @puhui999:是不是可以删掉,貌似没用?
83   - @GetMapping("/list")
84   - @Operation(summary = "获得秒杀活动列表")
85   - @Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
86   - @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
87   - public CommonResult<List<SeckillActivityRespVO>> getSeckillActivityList(@RequestParam("ids") Collection<Long> ids) {
88   - List<SeckillActivityDO> list = seckillActivityService.getSeckillActivityList(ids);
89   - return success(SeckillActivityConvert.INSTANCE.complementList(list));
90   - }
91   -
92 81 @GetMapping("/page")
93 82 @Operation(summary = "获得秒杀活动分页")
94 83 @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
95 84 public CommonResult<PageResult<SeckillActivityRespVO>> getSeckillActivityPage(@Valid SeckillActivityPageReqVO pageVO) {
96 85 PageResult<SeckillActivityDO> pageResult = seckillActivityService.getSeckillActivityPage(pageVO);
97   - Set<Long> aIds = CollectionUtils.convertSet(pageResult.getList(), SeckillActivityDO::getId);
  86 + Set<Long> aIds = convertSet(pageResult.getList(), SeckillActivityDO::getId);
98 87 List<SeckillProductDO> seckillProducts = seckillActivityService.getSeckillProductListByActivityId(aIds);
99   - Set<Long> spuIds = CollectionUtils.convertSet(pageResult.getList(), SeckillActivityDO::getSpuId);
  88 + Set<Long> spuIds = convertSet(pageResult.getList(), SeckillActivityDO::getSpuId);
100 89 List<ProductSpuRespDTO> spuList = spuApi.getSpuList(spuIds);
101 90 return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, seckillProducts, spuList));
102 91 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.convert.bargain;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
  6 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityRespVO;
  9 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
  10 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductBaseVO;
  11 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductRespVO;
  12 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductUpdateReqVO;
  13 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
  14 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
  15 +import org.mapstruct.Mapper;
  16 +import org.mapstruct.Mapping;
  17 +import org.mapstruct.Mappings;
  18 +import org.mapstruct.factory.Mappers;
  19 +
  20 +import java.util.List;
  21 +import java.util.Map;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  24 +
  25 +/**
  26 + * 拼团活动 Convert
  27 + *
  28 + * @author HUIHUI
  29 + */
  30 +@Mapper
  31 +public interface BargainActivityConvert {
  32 +
  33 + BargainActivityConvert INSTANCE = Mappers.getMapper(BargainActivityConvert.class);
  34 +
  35 + BargainActivityDO convert(BargainActivityCreateReqVO bean);
  36 +
  37 + BargainActivityDO convert(BargainActivityUpdateReqVO bean);
  38 +
  39 + BargainActivityRespVO convert(BargainActivityDO bean);
  40 +
  41 + BargainProductRespVO convert(BargainProductDO bean);
  42 +
  43 + default BargainActivityRespVO convert(BargainActivityDO bean, List<BargainProductDO> productDOs) {
  44 + return convert(bean).setProducts(convertList2(productDOs));
  45 + }
  46 +
  47 + List<BargainActivityRespVO> convertList(List<BargainActivityDO> list);
  48 +
  49 + PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page);
  50 +
  51 + default PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page,
  52 + List<BargainProductDO> productList,
  53 + List<ProductSpuRespDTO> spuList) {
  54 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
  55 + PageResult<BargainActivityRespVO> pageResult = convertPage(page);
  56 + pageResult.getList().forEach(item -> {
  57 + MapUtils.findAndThen(spuMap, item.getSpuId(), spu -> {
  58 + item.setSpuName(spu.getName());
  59 + item.setPicUrl(spu.getPicUrl());
  60 + });
  61 + item.setProducts(convertList2(productList));
  62 + });
  63 + return pageResult;
  64 + }
  65 +
  66 + List<BargainProductRespVO> convertList2(List<BargainProductDO> productDOs);
  67 +
  68 + @Mappings({
  69 + @Mapping(target = "id", ignore = true),
  70 + @Mapping(target = "activityId", source = "activityDO.id"),
  71 + @Mapping(target = "spuId", source = "activityDO.spuId"),
  72 + @Mapping(target = "skuId", source = "vo.skuId"),
  73 + @Mapping(target = "bargainFirstPrice", source = "vo.bargainFirstPrice"),
  74 + @Mapping(target = "bargainPrice", source = "vo.bargainPrice"),
  75 + @Mapping(target = "stock", source = "vo.stock"),
  76 + @Mapping(target = "activityStartTime", source = "activityDO.startTime"),
  77 + @Mapping(target = "activityEndTime", source = "activityDO.endTime")
  78 + })
  79 + BargainProductDO convert(BargainActivityDO activityDO, BargainProductBaseVO vo);
  80 +
  81 + default List<BargainProductDO> convertList(List<? extends BargainProductBaseVO> products, BargainActivityDO activityDO) {
  82 + return CollectionUtils.convertList(products, item -> convert(activityDO, item).setActivityStatus(activityDO.getStatus()));
  83 + }
  84 +
  85 + default List<BargainProductDO> convertList(List<BargainProductUpdateReqVO> updateProductVOs,
  86 + List<BargainProductDO> products, BargainActivityDO activity) {
  87 + Map<Long, Long> productMap = convertMap(products, BargainProductDO::getSkuId, BargainProductDO::getId);
  88 + return CollectionUtils.convertList(updateProductVOs, updateProductVO -> convert(activity, updateProductVO)
  89 + .setId(productMap.get(updateProductVO.getSkuId()))
  90 + .setActivityStatus(activity.getStatus()));
  91 + }
  92 +
  93 + //BargainRecordDO convert(BargainRecordCreateReqDTO reqDTO);
  94 +
  95 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
... ... @@ -17,11 +17,8 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationR
17 17 import org.mapstruct.Mapper;
18 18 import org.mapstruct.Mapping;
19 19 import org.mapstruct.Mappings;
20   -import org.mapstruct.Named;
21 20 import org.mapstruct.factory.Mappers;
22 21  
23   -import java.time.LocalDateTime;
24   -import java.util.ArrayList;
25 22 import java.util.List;
26 23 import java.util.Map;
27 24  
... ... @@ -37,38 +34,16 @@ public interface CombinationActivityConvert {
37 34  
38 35 CombinationActivityConvert INSTANCE = Mappers.getMapper(CombinationActivityConvert.class);
39 36  
40   - @Mappings({
41   - @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
42   - @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
43   - })
44 37 CombinationActivityDO convert(CombinationActivityCreateReqVO bean);
45 38  
46   - @Mappings({
47   - @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
48   - @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
49   - })
50 39 CombinationActivityDO convert(CombinationActivityUpdateReqVO bean);
51 40  
52   - @Named("mergeTime")
53   - default LocalDateTime[] mergeTime(LocalDateTime startTime, LocalDateTime endTime) {
54   - // TODO 有点怪第一次这样写 hh
55   - LocalDateTime[] localDateTime = new LocalDateTime[2];
56   - localDateTime[0] = startTime;
57   - localDateTime[1] = endTime;
58   - return localDateTime;
59   - }
60   -
61   - @Mappings({
62   - @Mapping(target = "activityTime", expression = "java(mergeTime(bean.getStartTime(),bean.getEndTime()))")
63   - })
64 41 CombinationActivityRespVO convert(CombinationActivityDO bean);
65 42  
66 43 CombinationProductRespVO convert(CombinationProductDO bean);
67 44  
68 45 default CombinationActivityRespVO convert(CombinationActivityDO bean, List<CombinationProductDO> productDOs) {
69   - CombinationActivityRespVO respVO = convert(bean);
70   - respVO.setProducts(convertList2(productDOs));
71   - return respVO;
  46 + return convert(bean).setProducts(convertList2(productDOs));
72 47 }
73 48  
74 49 List<CombinationActivityRespVO> convertList(List<CombinationActivityDO> list);
... ... @@ -104,21 +79,15 @@ public interface CombinationActivityConvert {
104 79 CombinationProductDO convert(CombinationActivityDO activityDO, CombinationProductBaseVO vo);
105 80  
106 81 default List<CombinationProductDO> convertList(List<? extends CombinationProductBaseVO> products, CombinationActivityDO activityDO) {
107   - List<CombinationProductDO> list = new ArrayList<>();
108   - products.forEach(sku -> {
109   - CombinationProductDO productDO = convert(activityDO, sku);
110   - productDO.setActivityStatus(activityDO.getStatus());
111   - list.add(productDO);
112   - });
113   - return list;
  82 + return CollectionUtils.convertList(products, item -> convert(activityDO, item).setActivityStatus(activityDO.getStatus()));
114 83 }
115 84  
116 85 default List<CombinationProductDO> convertList(List<CombinationProductUpdateReqVO> updateProductVOs,
117 86 List<CombinationProductDO> products, CombinationActivityDO activity) {
118 87 Map<Long, Long> productMap = convertMap(products, CombinationProductDO::getSkuId, CombinationProductDO::getId);
119 88 return CollectionUtils.convertList(updateProductVOs, updateProductVO -> convert(activity, updateProductVO)
120   - .setId(productMap.get(updateProductVO.getSkuId()))
121   - .setActivityStatus(activity.getStatus()));
  89 + .setId(productMap.get(updateProductVO.getSkuId()))
  90 + .setActivityStatus(activity.getStatus()));
122 91 }
123 92  
124 93 CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO);
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
... ... @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se
9 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
10 10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
11 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO;
12   -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO;
13 12 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
14 13 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
15 14 import org.mapstruct.Mapper;
... ... @@ -17,12 +16,9 @@ import org.mapstruct.Mapping;
17 16 import org.mapstruct.Mappings;
18 17 import org.mapstruct.factory.Mappers;
19 18  
20   -import java.util.ArrayList;
21 19 import java.util.List;
22 20 import java.util.Map;
23 21  
24   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
25   -
26 22 /**
27 23 * 秒杀活动 Convert
28 24 *
... ... @@ -39,8 +35,7 @@ public interface SeckillActivityConvert {
39 35  
40 36 SeckillActivityRespVO convert(SeckillActivityDO bean);
41 37  
42   - // TODO @puhui999:这个是不是还是 convertList 好点?
43   - List<SeckillActivityRespVO> complementList(List<SeckillActivityDO> list);
  38 + List<SeckillActivityRespVO> convertList(List<SeckillActivityDO> list);
44 39  
45 40 PageResult<SeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> page);
46 41  
... ... @@ -58,9 +53,7 @@ public interface SeckillActivityConvert {
58 53 SeckillActivityDetailRespVO convert1(SeckillActivityDO seckillActivity);
59 54  
60 55 default SeckillActivityDetailRespVO convert(SeckillActivityDO seckillActivity, List<SeckillProductDO> seckillProducts) {
61   - SeckillActivityDetailRespVO respVO = convert1(seckillActivity);
62   - respVO.setProducts(convertList2(seckillProducts));
63   - return respVO;
  56 + return convert1(seckillActivity).setProducts(convertList2(seckillProducts));
64 57 }
65 58  
66 59 @Mappings({
... ... @@ -77,21 +70,7 @@ public interface SeckillActivityConvert {
77 70 SeckillProductDO convert(SeckillActivityDO activityDO, SeckillProductBaseVO vo);
78 71  
79 72 default List<SeckillProductDO> convertList(List<? extends SeckillProductBaseVO> products, SeckillActivityDO activityDO) {
80   - List<SeckillProductDO> list = new ArrayList<>();
81   - products.forEach(sku -> {
82   - SeckillProductDO productDO = convert(activityDO, sku);
83   - productDO.setActivityStatus(activityDO.getStatus());
84   - list.add(productDO);
85   - });
86   - return list;
87   - }
88   -
89   - default List<SeckillProductDO> convertList(List<SeckillProductUpdateReqVO> updateProductVOs,
90   - List<SeckillProductDO> products, SeckillActivityDO activity) {
91   - Map<Long, Long> productMap = convertMap(products, SeckillProductDO::getSkuId, SeckillProductDO::getId);
92   - return CollectionUtils.convertList(updateProductVOs, updateProductVO -> convert(activity, updateProductVO)
93   - .setId(productMap.get(updateProductVO.getSkuId()))
94   - .setActivityStatus(activity.getStatus()));
  73 + return CollectionUtils.convertList(products, item -> convert(activityDO, item).setActivityStatus(activityDO.getStatus()));
95 74 }
96 75  
97 76 List<SeckillProductRespVO> convertList2(List<SeckillProductDO> productDOs);
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java
... ... @@ -55,21 +55,6 @@ public class BargainActivityDO extends BaseDO {
55 55 private Long spuId;
56 56  
57 57 /**
58   - * 商品 SKU 编号
59   - */
60   - private Long skuId;
61   -
62   - /**
63   - * 应付金额,单位分
64   - */
65   - private Integer bargainFirstPrice;
66   -
67   - /**
68   - * 砍价底价,单位:分
69   - */
70   - private Integer bargainPrice;
71   -
72   - /**
73 58 * 达到该人数,才能砍到低价
74 59 */
75 60 private Integer userSize;
... ... @@ -80,6 +65,11 @@ public class BargainActivityDO extends BaseDO {
80 65 private Integer bargainCount;
81 66  
82 67 /**
  68 + * 总限购数量
  69 + */
  70 + private Integer totalLimitCount;
  71 +
  72 + /**
83 73 * 砍价库存
84 74 */
85 75 private Integer stock;
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainProductDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.dataobject.bargain;
  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_bargain_product")
  17 +@KeySequence("promotion_bargain_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 BargainProductDO 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 + * 关联 {@link BargainActivityDO#getStatus()}
  47 + */
  48 + private Integer activityStatus;
  49 + /**
  50 + * 活动开始时间点
  51 + */
  52 + private LocalDateTime activityStartTime;
  53 + /**
  54 + * 活动结束时间点
  55 + */
  56 + private LocalDateTime activityEndTime;
  57 + /**
  58 + * 砍价起始价格,单位分
  59 + */
  60 + private Integer bargainFirstPrice;
  61 + /**
  62 + * 砍价底价,单位:分
  63 + */
  64 + private Integer bargainPrice;
  65 + /**
  66 + * 活动库存
  67 + */
  68 + private Integer stock;
  69 +
  70 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
  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.bargain.vo.activity.BargainActivityPageReqVO;
  7 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * 砍价活动 Mapper
  14 + *
  15 + * @author HUIHUI
  16 + */
  17 +@Mapper
  18 +public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
  19 +
  20 + default PageResult<BargainActivityDO> selectPage(BargainActivityPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<BargainActivityDO>()
  22 + .likeIfPresent(BargainActivityDO::getName, reqVO.getName())
  23 + .orderByDesc(BargainActivityDO::getId));
  24 + }
  25 +
  26 + default List<BargainActivityDO> selectListByStatus(Integer status) {
  27 + return selectList(BargainActivityDO::getStatus, status);
  28 + }
  29 +
  30 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainProductMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
  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.bargain.vo.product.BargainProductPageReqVO;
  7 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +import java.util.Collection;
  11 +import java.util.List;
  12 +
  13 +/**
  14 + * 砍价商品 Mapper
  15 + *
  16 + * @author HUIHUI
  17 + */
  18 +@Mapper
  19 +public interface BargainProductMapper extends BaseMapperX<BargainProductDO> {
  20 +
  21 + default PageResult<BargainProductDO> selectPage(BargainProductPageReqVO reqVO) {
  22 + return selectPage(reqVO, new LambdaQueryWrapperX<BargainProductDO>()
  23 + .eqIfPresent(BargainProductDO::getActivityId, reqVO.getActivityId())
  24 + .eqIfPresent(BargainProductDO::getSpuId, reqVO.getSpuId())
  25 + .eqIfPresent(BargainProductDO::getSkuId, reqVO.getSkuId())
  26 + .eqIfPresent(BargainProductDO::getActivityStatus, reqVO.getActivityStatus())
  27 + .betweenIfPresent(BargainProductDO::getActivityStartTime, reqVO.getActivityStartTime())
  28 + .betweenIfPresent(BargainProductDO::getActivityEndTime, reqVO.getActivityEndTime())
  29 + .betweenIfPresent(BargainProductDO::getCreateTime, reqVO.getCreateTime())
  30 + .orderByDesc(BargainProductDO::getId));
  31 + }
  32 +
  33 + default List<BargainProductDO> selectListByActivityIds(Collection<Long> ids) {
  34 + return selectList(BargainProductDO::getActivityId, ids);
  35 + }
  36 +
  37 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainRecordMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.dal.mysql.bargain;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  5 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
  6 +import org.apache.ibatis.annotations.Mapper;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 砍价记录 Mapper
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Mapper
  16 +public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> {
  17 +
  18 + // TODO @puhui999:selectByUserIdAndOrderId
  19 + default BargainRecordDO selectRecord(Long userId, Long orderId) {
  20 + return selectOne(BargainRecordDO::getUserId, userId,
  21 + BargainRecordDO::getOrderId, orderId);
  22 + }
  23 +
  24 + /**
  25 + * 查询砍价记录
  26 + *
  27 + * @param headId 团长编号
  28 + * @param activityId 活动编号
  29 + * @return 砍价记录
  30 + */
  31 + default BargainRecordDO selectRecordByHeadId(Long headId, Long activityId, Integer status) {
  32 + return selectOne(new LambdaQueryWrapperX<BargainRecordDO>()
  33 + .eq(BargainRecordDO::getUserId, headId)
  34 + .eq(BargainRecordDO::getActivityId, activityId)
  35 + .eq(BargainRecordDO::getStatus, status));
  36 + }
  37 +
  38 + default List<BargainRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) {
  39 + return selectList(new LambdaQueryWrapperX<BargainRecordDO>()
  40 + //.eq(BargainRecordDO::getHeadId, headId)
  41 + .eq(BargainRecordDO::getStatus, status));
  42 + }
  43 +
  44 + default List<BargainRecordDO> selectListByStatus(Integer status) {
  45 + return selectList(BargainRecordDO::getStatus, status);
  46 + }
  47 +
  48 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
... ... @@ -29,9 +29,10 @@ public interface CombinationRecordMapper extends BaseMapperX&lt;CombinationRecordDO
29 29 * @return 拼团记录
30 30 */
31 31 default CombinationRecordDO selectRecordByHeadId(Long headId, Long activityId, Integer status) {
32   - return selectOne(CombinationRecordDO::getHeadId, headId,
33   - CombinationRecordDO::getActivityId, activityId,
34   - CombinationRecordDO::getStatus, status);
  32 + return selectOne(new LambdaQueryWrapperX<CombinationRecordDO>()
  33 + .eq(CombinationRecordDO::getUserId, headId)
  34 + .eq(CombinationRecordDO::getActivityId, activityId)
  35 + .eq(CombinationRecordDO::getStatus, status));
35 36 }
36 37  
37 38 default List<CombinationRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) {
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.bargain;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
  7 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
  9 +
  10 +import javax.validation.Valid;
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 砍价活动 Service 接口
  16 + *
  17 + * @author HUIHUI
  18 + */
  19 +public interface BargainActivityService {
  20 +
  21 + /**
  22 + * 创建砍价活动
  23 + *
  24 + * @param createReqVO 创建信息
  25 + * @return 编号
  26 + */
  27 + Long createBargainActivity(@Valid BargainActivityCreateReqVO createReqVO);
  28 +
  29 + /**
  30 + * 更新砍价活动
  31 + *
  32 + * @param updateReqVO 更新信息
  33 + */
  34 + void updateBargainActivity(@Valid BargainActivityUpdateReqVO updateReqVO);
  35 +
  36 + /**
  37 + * 删除砍价活动
  38 + *
  39 + * @param id 编号
  40 + */
  41 + void deleteBargainActivity(Long id);
  42 +
  43 + /**
  44 + * 获得砍价活动
  45 + *
  46 + * @param id 编号
  47 + * @return 砍价活动
  48 + */
  49 + BargainActivityDO getBargainActivity(Long id);
  50 +
  51 + /**
  52 + * 获得砍价活动列表
  53 + *
  54 + * @param ids 编号
  55 + * @return 砍价活动列表
  56 + */
  57 + List<BargainActivityDO> getBargainActivityList(Collection<Long> ids);
  58 +
  59 + /**
  60 + * 获得砍价活动分页
  61 + *
  62 + * @param pageReqVO 分页查询
  63 + * @return 砍价活动分页
  64 + */
  65 + PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO);
  66 +
  67 + /**
  68 + * 获得砍价活动商品列表
  69 + *
  70 + * @param ids 砍价活动 ids
  71 + * @return 砍价活动的商品列表
  72 + */
  73 + List<BargainProductDO> getBargainProductsByActivityIds(Collection<Long> ids);
  74 +
  75 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.bargain;
  2 +
  3 +
  4 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * 商品活动记录 service
  10 + *
  11 + * @author HUIHUI
  12 + */
  13 +public interface BargainRecordService {
  14 +
  15 + /**
  16 + * 更新砍价状态
  17 + *
  18 + * @param userId 用户编号
  19 + * @param orderId 订单编号
  20 + * @param status 状态
  21 + */
  22 + void updateBargainRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status);
  23 +
  24 + ///**
  25 + // * 创建砍价记录
  26 + // *
  27 + // * @param reqDTO 创建信息
  28 + // */
  29 + //void createBargainRecord(BargainRecordCreateReqDTO reqDTO);
  30 +
  31 + /**
  32 + * 更新砍价状态和开始时间
  33 + *
  34 + * @param userId 用户编号
  35 + * @param orderId 订单编号
  36 + * @param status 状态
  37 + * @param startTime 开始时间
  38 + */
  39 + void updateBargainRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId,
  40 + Integer status, LocalDateTime startTime);
  41 +
  42 + /**
  43 + * 获得砍价状态
  44 + *
  45 + * @param userId 用户编号
  46 + * @param orderId 订单编号
  47 + * @return 砍价状态
  48 + */
  49 + BargainRecordDO getBargainRecord(Long userId, Long orderId);
  50 +
  51 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.bargain;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.collection.CollectionUtil;
  5 +import cn.hutool.core.util.ObjectUtil;
  6 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  9 +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
  10 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  11 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  12 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  13 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
  14 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
  16 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductCreateReqVO;
  17 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.product.BargainProductUpdateReqVO;
  18 +import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
  19 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
  20 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainProductDO;
  21 +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainRecordDO;
  22 +import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainActivityMapper;
  23 +import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainProductMapper;
  24 +import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper;
  25 +import org.springframework.stereotype.Service;
  26 +import org.springframework.transaction.annotation.Transactional;
  27 +import org.springframework.validation.annotation.Validated;
  28 +
  29 +import javax.annotation.Resource;
  30 +import java.time.LocalDateTime;
  31 +import java.util.Collection;
  32 +import java.util.List;
  33 +
  34 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  35 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
  36 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
  37 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
  38 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
  39 +import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuAllExists;
  40 +
  41 +/**
  42 + * 砍价活动 Service 实现类
  43 + *
  44 + * @author HUIHUI
  45 + */
  46 +@Service
  47 +@Validated
  48 +public class BargainServiceImpl implements BargainActivityService, BargainRecordService {
  49 +
  50 + @Resource
  51 + private BargainActivityMapper bargainActivityMapper;
  52 + @Resource
  53 + private BargainRecordMapper recordMapper;
  54 + @Resource
  55 + private BargainProductMapper bargainProductMapper;
  56 + @Resource
  57 + private ProductSpuApi productSpuApi;
  58 + @Resource
  59 + private ProductSkuApi productSkuApi;
  60 +
  61 + @Override
  62 + @Transactional(rollbackFor = Exception.class)
  63 + public Long createBargainActivity(BargainActivityCreateReqVO createReqVO) {
  64 + // 校验商品 SPU 是否存在是否参加的别的活动
  65 + validateProductBargainConflict(createReqVO.getSpuId(), null);
  66 + // 获取所选 spu下的所有 sku
  67 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId()));
  68 + // 校验商品 sku 是否存在
  69 + validateProductSkuAllExists(skus, createReqVO.getProducts(), BargainProductCreateReqVO::getSkuId);
  70 +
  71 + // 插入砍价活动
  72 + BargainActivityDO activityDO = BargainActivityConvert.INSTANCE.convert(createReqVO);
  73 + // TODO 营销相关属性初始化 砍价成功更新相关属性
  74 + activityDO.setSuccessCount(0);
  75 + // 活动总库存
  76 + activityDO.setStock(getSumValue(createReqVO.getProducts(), BargainProductCreateReqVO::getStock, Integer::sum));
  77 + activityDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  78 + bargainActivityMapper.insert(activityDO);
  79 + // 插入商品
  80 + List<BargainProductDO> productDOs = BargainActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activityDO);
  81 + bargainProductMapper.insertBatch(productDOs);
  82 + // 返回
  83 + return activityDO.getId();
  84 + }
  85 +
  86 + private void validateProductBargainConflict(Long spuId, Long activityId) {
  87 + // 校验商品 spu 是否存在
  88 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));
  89 + if (CollUtil.isEmpty(spuList)) {
  90 + throw exception(SPU_NOT_EXISTS);
  91 + }
  92 + // 查询所有开启的砍价活动
  93 + List<BargainActivityDO> activityDOs = bargainActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
  94 + // 更新时排除自己
  95 + if (activityId != null) {
  96 + activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
  97 + }
  98 + // 校验商品 spu 是否参加了其它活动
  99 + if (anyMatch(activityDOs, s -> ObjectUtil.equal(s.getId(), spuId))) {
  100 + throw exception(BARGAIN_ACTIVITY_SPU_CONFLICTS);
  101 + }
  102 + }
  103 +
  104 + @Override
  105 + @Transactional(rollbackFor = Exception.class)
  106 + public void updateBargainActivity(BargainActivityUpdateReqVO updateReqVO) {
  107 + // 校验存在
  108 + BargainActivityDO activityDO = validateBargainActivityExists(updateReqVO.getId());
  109 + // 校验状态
  110 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  111 + throw exception(BARGAIN_ACTIVITY_STATUS_DISABLE);
  112 + }
  113 + // 校验商品冲突
  114 + validateProductBargainConflict(updateReqVO.getSpuId(), updateReqVO.getId());
  115 + // 获取所选 spu下的所有 sku
  116 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId()));
  117 + // 校验商品 sku 是否存在
  118 + validateProductSkuAllExists(skus, updateReqVO.getProducts(), BargainProductUpdateReqVO::getSkuId);
  119 +
  120 + // 更新
  121 + BargainActivityDO updateObj = BargainActivityConvert.INSTANCE.convert(updateReqVO);
  122 + // 更新活动库存
  123 + updateObj.setStock(getSumValue(updateReqVO.getProducts(), BargainProductUpdateReqVO::getStock, Integer::sum));
  124 + bargainActivityMapper.updateById(updateObj);
  125 + // 更新商品
  126 + updateBargainProduct(updateObj, updateReqVO.getProducts());
  127 + }
  128 +
  129 + /**
  130 + * 更新砍价商品
  131 + *
  132 + * @param updateObj 更新的活动
  133 + * @param products 商品配置
  134 + */
  135 + private void updateBargainProduct(BargainActivityDO updateObj, List<BargainProductUpdateReqVO> products) {
  136 + // 默认全部新增
  137 + List<BargainProductDO> defaultNewList = BargainActivityConvert.INSTANCE.convertList(products, updateObj);
  138 + // 数据库中的老数据
  139 + List<BargainProductDO> oldList = bargainProductMapper.selectListByActivityIds(CollUtil.newArrayList(updateObj.getId()));
  140 + List<List<BargainProductDO>> lists = CollectionUtils.diffList(oldList, defaultNewList, (oldVal, newVal) -> {
  141 + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId());
  142 + if (same) {
  143 + newVal.setId(oldVal.getId());
  144 + }
  145 + return same;
  146 + });
  147 +
  148 + // create
  149 + if (CollUtil.isNotEmpty(lists.get(0))) {
  150 + bargainProductMapper.insertBatch(lists.get(0));
  151 + }
  152 + // update
  153 + if (CollUtil.isNotEmpty(lists.get(1))) {
  154 + bargainProductMapper.updateBatch(lists.get(1));
  155 + }
  156 + // delete
  157 + if (CollUtil.isNotEmpty(lists.get(2))) {
  158 + bargainProductMapper.deleteBatchIds(CollectionUtils.convertList(lists.get(2), BargainProductDO::getId));
  159 + }
  160 + }
  161 +
  162 + @Override
  163 + @Transactional(rollbackFor = Exception.class)
  164 + public void deleteBargainActivity(Long id) {
  165 + // 校验存在
  166 + BargainActivityDO activityDO = validateBargainActivityExists(id);
  167 + // 校验状态
  168 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  169 + throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
  170 + }
  171 +
  172 + // 删除
  173 + bargainActivityMapper.deleteById(id);
  174 + }
  175 +
  176 + private BargainActivityDO validateBargainActivityExists(Long id) {
  177 + BargainActivityDO activityDO = bargainActivityMapper.selectById(id);
  178 + if (activityDO == null) {
  179 + throw exception(BARGAIN_ACTIVITY_NOT_EXISTS);
  180 + }
  181 + return activityDO;
  182 + }
  183 +
  184 + @Override
  185 + public BargainActivityDO getBargainActivity(Long id) {
  186 + return validateBargainActivityExists(id);
  187 + }
  188 +
  189 + @Override
  190 + public List<BargainActivityDO> getBargainActivityList(Collection<Long> ids) {
  191 + return bargainActivityMapper.selectBatchIds(ids);
  192 + }
  193 +
  194 + @Override
  195 + public PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO) {
  196 + return bargainActivityMapper.selectPage(pageReqVO);
  197 + }
  198 +
  199 + @Override
  200 + public List<BargainProductDO> getBargainProductsByActivityIds(Collection<Long> ids) {
  201 + return bargainProductMapper.selectListByActivityIds(ids);
  202 + }
  203 +
  204 + @Override
  205 + public void updateBargainRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status) {
  206 + // 校验砍价是否存在
  207 + // 更新状态
  208 + recordMapper.updateById(validateBargainRecord(userId, orderId).setStatus(status));
  209 + }
  210 +
  211 + @Override
  212 + @Transactional(rollbackFor = Exception.class)
  213 + public void updateBargainRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime) {
  214 + BargainRecordDO recordDO = validateBargainRecord(userId, orderId);
  215 + // 更新状态
  216 + recordDO.setStatus(status);
  217 + // 更新开始时间
  218 + //recordDO.setStartTime(startTime);
  219 + //recordMapper.updateById(recordDO);
  220 + //
  221 + //// 更新砍价参入人数
  222 + //List<BargainRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status);
  223 + //if (CollUtil.isNotEmpty(recordDOs)) {
  224 + // recordDOs.forEach(item -> {
  225 + // item.setUserCount(recordDOs.size());
  226 + // // 校验砍价是否满足要求
  227 + // if (ObjectUtil.equal(recordDOs.size(), recordDO.getUserSize())) {
  228 + // item.setStatus(BargainRecordStatusEnum.SUCCESS.getStatus());
  229 + // }
  230 + // });
  231 + //}
  232 + //recordMapper.updateBatch(recordDOs);
  233 + }
  234 +
  235 + private BargainRecordDO validateBargainRecord(Long userId, Long orderId) {
  236 + // 校验砍价是否存在
  237 + BargainRecordDO recordDO = recordMapper.selectRecord(userId, orderId);
  238 + if (recordDO == null) {
  239 + throw exception(BARGAIN_RECORD_NOT_EXISTS);
  240 + }
  241 + return recordDO;
  242 + }
  243 +
  244 + //@Override
  245 + //public void createBargainRecord(BargainRecordCreateReqDTO reqDTO) {
  246 + // // 1.1 校验砍价活动
  247 + // BargainActivityDO activity = validateBargainActivityExists(reqDTO.getActivityId());
  248 + // // 1.2 需要校验下,他当前是不是已经参加了该砍价;
  249 + // BargainRecordDO recordDO = recordMapper.selectRecord(reqDTO.getUserId(), reqDTO.getOrderId());
  250 + // if (recordDO != null) {
  251 + // throw exception(BARGAIN_RECORD_EXISTS);
  252 + // }
  253 + // // 1.3 父砍价是否存在,是否已经满了
  254 + // if (reqDTO.getHeadId() != null) {
  255 + // BargainRecordDO recordDO1 = recordMapper.selectRecordByHeadId(reqDTO.getHeadId(), reqDTO.getActivityId(), BargainRecordStatusEnum.IN_PROGRESS.getStatus());
  256 + // if (recordDO1 == null) {
  257 + // throw exception(BARGAIN_RECORD_HEAD_NOT_EXISTS);
  258 + // }
  259 + // // 校验砍价是否满足要求
  260 + // if (ObjectUtil.equal(recordDO1.getUserCount(), recordDO1.getUserSize())) {
  261 + // throw exception(BARGAIN_RECORD_USER_FULL);
  262 + // }
  263 + // }
  264 + // // TODO @puhui999:应该还有一些校验,后续补噶;例如说,一个团,自己已经参与进去了,不能再参与进去;
  265 + //
  266 + // // 2. 创建砍价记录
  267 + // BargainRecordDO record = BargainActivityConvert.INSTANCE.convert(reqDTO);
  268 + // if (reqDTO.getHeadId() == null) {
  269 + // // TODO @puhui999:不是自己呀;headId 是父团长的 BargainRecordDO.id 哈
  270 + // record.setHeadId(reqDTO.getUserId());
  271 + // }
  272 + // record.setVirtualGroup(false);
  273 + // // TODO @puhui999:过期时间,应该是 Date 哈;
  274 + // record.setExpireTime(activity.getLimitDuration());
  275 + // record.setUserSize(activity.getUserSize());
  276 + // recordMapper.insert(record);
  277 + //}
  278 +
  279 + @Override
  280 + public BargainRecordDO getBargainRecord(Long userId, Long orderId) {
  281 + return validateBargainRecord(userId, orderId);
  282 + }
  283 +
  284 + /**
  285 + * APP 端获取开团记录
  286 + *
  287 + * @return 开团记录
  288 + */
  289 + public List<BargainRecordDO> getRecordListByStatus(Integer status) {
  290 + return recordMapper.selectListByStatus(status);
  291 + }
  292 +
  293 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationServiceImpl.java
... ... @@ -2,12 +2,10 @@ package cn.iocoder.yudao.module.promotion.service.combination;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.collection.CollectionUtil;
5   -import cn.hutool.core.map.MapUtil;
6 5 import cn.hutool.core.util.ObjectUtil;
7 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
8 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 8 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
10   -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
11 9 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
12 10 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
13 11 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
... ... @@ -32,7 +30,8 @@ import org.springframework.validation.annotation.Validated;
32 30  
33 31 import javax.annotation.Resource;
34 32 import java.time.LocalDateTime;
35   -import java.util.*;
  33 +import java.util.Collection;
  34 +import java.util.List;
36 35  
37 36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
38 37 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
... ... @@ -60,19 +59,20 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
60 59 private ProductSkuApi productSkuApi;
61 60  
62 61 @Override
  62 + @Transactional(rollbackFor = Exception.class)
63 63 public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) {
64 64 // 校验商品 SPU 是否存在是否参加的别的活动
65 65 validateProductCombinationConflict(createReqVO.getSpuId(), null);
66 66 // 获取所选 spu下的所有 sku
67 67 List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId()));
68 68 // 校验商品 sku 是否存在
69   - validateProductSkuAllExists(createReqVO.getProducts(), skus, CombinationProductCreateReqVO::getSkuId);
  69 + validateProductSkuAllExists(skus, createReqVO.getProducts(), CombinationProductCreateReqVO::getSkuId);
70 70  
71 71 // TODO 艿艿 有个小问题:现在有活动时间和限制时长,活动时间的结束时间早于设置的限制时间怎么算状态比如:
72 72 // 活动时间 2023-08-05 15:00:00 - 2023-08-05 15:20:00 限制时长 2小时,那么活动时间结束就结束还是加时到满两小时
73 73 // 插入拼团活动
74 74 CombinationActivityDO activityDO = CombinationActivityConvert.INSTANCE.convert(createReqVO);
75   - // TODO 营销相关属性初始化
  75 + // TODO 营销相关属性初始化 拼团成功更新相关属性
76 76 activityDO.setTotalNum(0);
77 77 activityDO.setSuccessNum(0);
78 78 activityDO.setOrderUserCount(0);
... ... @@ -106,6 +106,7 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
106 106 }
107 107  
108 108 @Override
  109 + @Transactional(rollbackFor = Exception.class)
109 110 public void updateCombinationActivity(CombinationActivityUpdateReqVO updateReqVO) {
110 111 // 校验存在
111 112 CombinationActivityDO activityDO = validateCombinationActivityExists(updateReqVO.getId());
... ... @@ -118,7 +119,7 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
118 119 // 获取所选 spu下的所有 sku
119 120 List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId()));
120 121 // 校验商品 sku 是否存在
121   - validateProductSkuAllExists(updateReqVO.getProducts(), skus, CombinationProductUpdateReqVO::getSkuId);
  122 + validateProductSkuAllExists(skus, updateReqVO.getProducts(), CombinationProductUpdateReqVO::getSkuId);
122 123  
123 124 // 更新
124 125 CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO);
... ... @@ -128,44 +129,40 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
128 129 }
129 130  
130 131 /**
131   - * 更新秒杀商品
  132 + * 更新拼团商品
132 133 *
133   - * @param updateObj DO
  134 + * @param updateObj 更新的活动
134 135 * @param products 商品配置
135 136 */
136 137 private void updateCombinationProduct(CombinationActivityDO updateObj, List<CombinationProductUpdateReqVO> products) {
137   - List<CombinationProductDO> combinationProductDOs = combinationProductMapper.selectListByActivityIds(CollUtil.newArrayList(updateObj.getId()));
138   - // 数据库中的活动商品
139   - Set<Long> convertSet = CollectionUtils.convertSet(combinationProductDOs, CombinationProductDO::getSkuId);
140   - // 前端传过来的活动商品
141   - Set<Long> convertSet1 = CollectionUtils.convertSet(products, CombinationProductUpdateReqVO::getSkuId);
142   - // 分化数据
143   - // TODO @芋艿:看下这个实现
144   - Map<String, List<CombinationProductDO>> data = CollectionUtils.convertCDUMap(convertSet1, convertSet, mapData -> {
145   - HashMap<String, List<CombinationProductDO>> cdu = MapUtil.newHashMap(3);
146   - MapUtils.findAndThen(mapData, "create", list -> {
147   - cdu.put("create", CombinationActivityConvert.INSTANCE.convertList(CollectionUtils.filterList(products, item -> list.contains(item.getSkuId())), updateObj));
148   - });
149   - MapUtils.findAndThen(mapData, "delete", list -> {
150   - cdu.put("create", CollectionUtils.filterList(combinationProductDOs, item -> list.contains(item.getSkuId())));
151   - });
152   - // TODO @芋艿:临时注释,避免有问题
153   -// MapUtils.findAndThen(mapData, "update", list -> {
154   -// cdu.put("update", CombinationActivityConvert.INSTANCE.convertList(
155   -// combinationProductDOs,
156   -// CollectionUtils.filterList(products, item -> list.contains(item.getSkuId())), updateObj));
157   -// });
158   - return cdu;
  138 + // 默认全部新增
  139 + List<CombinationProductDO> defaultNewList = CombinationActivityConvert.INSTANCE.convertList(products, updateObj);
  140 + // 数据库中的老数据
  141 + List<CombinationProductDO> oldList = combinationProductMapper.selectListByActivityIds(CollUtil.newArrayList(updateObj.getId()));
  142 + List<List<CombinationProductDO>> lists = CollectionUtils.diffList(oldList, defaultNewList, (oldVal, newVal) -> {
  143 + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId());
  144 + if (same) {
  145 + newVal.setId(oldVal.getId());
  146 + }
  147 + return same;
159 148 });
160 149  
161   - // 执行增删改
162   - MapUtils.findAndThen(data, "create", item -> combinationProductMapper.insertBatch(item));
163   - MapUtils.findAndThen(data, "delete", item -> combinationProductMapper.deleteBatchIds(
164   - CollectionUtils.convertSet(item, CombinationProductDO::getId)));
165   - MapUtils.findAndThen(data, "update", item -> combinationProductMapper.updateBatch(item));
  150 + // create
  151 + if (CollUtil.isNotEmpty(lists.get(0))) {
  152 + combinationProductMapper.insertBatch(lists.get(0));
  153 + }
  154 + // update
  155 + if (CollUtil.isNotEmpty(lists.get(1))) {
  156 + combinationProductMapper.updateBatch(lists.get(1));
  157 + }
  158 + // delete
  159 + if (CollUtil.isNotEmpty(lists.get(2))) {
  160 + combinationProductMapper.deleteBatchIds(CollectionUtils.convertList(lists.get(2), CombinationProductDO::getId));
  161 + }
166 162 }
167 163  
168 164 @Override
  165 + @Transactional(rollbackFor = Exception.class)
169 166 public void deleteCombinationActivity(Long id) {
170 167 // 校验存在
171 168 CombinationActivityDO activityDO = validateCombinationActivityExists(id);
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
1 1 package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4   -import cn.hutool.core.map.MapUtil;
5 4 import cn.hutool.core.util.ObjectUtil;
6 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
9   -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
10 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
11 8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
12 9 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
... ... @@ -28,9 +25,13 @@ import org.springframework.transaction.annotation.Transactional;
28 25 import org.springframework.validation.annotation.Validated;
29 26  
30 27 import javax.annotation.Resource;
31   -import java.util.*;
  28 +import java.util.Collection;
  29 +import java.util.List;
  30 +import java.util.Set;
32 31  
  32 +import static cn.hutool.core.collection.CollUtil.isNotEmpty;
33 33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
34 35 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
35 36 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
36 37 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
... ... @@ -71,7 +72,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
71 72 // 插入秒杀活动
72 73 SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
73 74 .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()))
74   - .setTotalStock(CollectionUtils.getSumValue(createReqVO.getProducts(), SeckillProductCreateReqVO::getStock, Integer::sum));
  75 + .setTotalStock(getSumValue(createReqVO.getProducts(), SeckillProductCreateReqVO::getStock, Integer::sum));
75 76 seckillActivityMapper.insert(activity);
76 77 // 插入商品
77 78 List<SeckillProductDO> products = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activity);
... ... @@ -94,16 +95,16 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
94 95 activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
95 96 }
96 97 // 过滤出所有 spuId 有交集的活动
97   - List<SeckillActivityDO> activityDOs1 = CollectionUtils.convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getSpuId(), spuId));
98   - if (CollUtil.isNotEmpty(activityDOs1)) {
  98 + List<SeckillActivityDO> activityDOs1 = convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getSpuId(), spuId));
  99 + if (isNotEmpty(activityDOs1)) {
99 100 throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
100 101 }
101   - List<SeckillActivityDO> activityDOs2 = CollectionUtils.convertList(activityDOs, c -> c, s -> {
  102 + List<SeckillActivityDO> activityDOs2 = convertList(activityDOs, c -> c, s -> {
102 103 // 判断秒杀时段是否有交集
103   - return CollectionUtils.containsAny(s.getConfigIds(), configIds);
  104 + return containsAny(s.getConfigIds(), configIds);
104 105 });
105 106  
106   - if (CollUtil.isNotEmpty(activityDOs2)) {
  107 + if (isNotEmpty(activityDOs2)) {
107 108 throw exception(SECKILL_TIME_CONFLICTS);
108 109 }
109 110 }
... ... @@ -121,12 +122,12 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
121 122 // 获取所选 spu下的所有 sku
122 123 List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(updateReqVO.getSpuId()));
123 124 // 校验商品 sku 是否存在
124   - validateProductSkuAllExists(updateReqVO.getProducts(), skus, SeckillProductUpdateReqVO::getSkuId);
  125 + validateProductSkuAllExists(skus, updateReqVO.getProducts(), SeckillProductUpdateReqVO::getSkuId);
125 126  
126 127 // 更新活动
127 128 SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
128 129 .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()))
129   - .setTotalStock(CollectionUtils.getSumValue(updateReqVO.getProducts(), SeckillProductUpdateReqVO::getStock, Integer::sum));
  130 + .setTotalStock(getSumValue(updateReqVO.getProducts(), SeckillProductUpdateReqVO::getStock, Integer::sum));
130 131 seckillActivityMapper.updateById(updateObj);
131 132 // 更新商品
132 133 updateSeckillProduct(updateObj, updateReqVO.getProducts());
... ... @@ -139,36 +140,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
139 140 * @param updateObj 更新的活动
140 141 * @param products 商品配置
141 142 */
142   - // TODO @puhui999:我在想,我们是不是可以封装一个 CollUtil 的方法,传入两个数组,判断出哪些是新增、哪些是修改、哪些是删除;
143   - // 例如说,products 先转化成 SeckillProductDO;然后,基于一个 func(key1, key2) 做比对;
144   - // 如果可以跑通,所有涉及到这种逻辑的,都可以服用哈。
145 143 private void updateSeckillProduct(SeckillActivityDO updateObj, List<SeckillProductUpdateReqVO> products) {
  144 + // 默认全部新增
  145 + List<SeckillProductDO> defaultNewList = SeckillActivityConvert.INSTANCE.convertList(products, updateObj);
146 146 // 数据库中的活动商品
147   - List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateObj.getId());
148   - Set<Long> dbSkuIds = CollectionUtils.convertSet(seckillProductDOs, SeckillProductDO::getSkuId);
149   - Set<Long> voSkuIds = CollectionUtils.convertSet(products, SeckillProductUpdateReqVO::getSkuId);
150   - Map<String, List<SeckillProductDO>> data = CollectionUtils.convertCDUMap(voSkuIds, dbSkuIds, mapData -> {
151   - HashMap<String, List<SeckillProductDO>> cdu = MapUtil.newHashMap(3);
152   - MapUtils.findAndThen(mapData, "create", list -> {
153   - cdu.put("create", SeckillActivityConvert.INSTANCE.convertList(
154   - CollectionUtils.filterList(products, item -> list.contains(item.getSkuId())), updateObj));
155   - });
156   - MapUtils.findAndThen(mapData, "delete", list -> {
157   - cdu.put("create", CollectionUtils.filterList(seckillProductDOs, item -> list.contains(item.getSkuId())));
158   - });
159   - // TODO @芋艿:临时注释
160   -// MapUtils.findAndThen(mapData, "update", list -> {
161   -// cdu.put("update", SeckillActivityConvert.INSTANCE.convertList(seckillProductDOs,
162   -// CollectionUtils.filterList(products, item -> list.contains(item.getSkuId())), updateObj));
163   -// });
164   - return cdu;
  147 + List<SeckillProductDO> oldList = seckillProductMapper.selectListByActivityId(updateObj.getId());
  148 + // 对比老、新两个列表,找出新增、修改、删除的数据
  149 + List<List<SeckillProductDO>> lists = diffList(oldList, defaultNewList, (oldVal, newVal) -> {
  150 + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId());
  151 + if (same) {
  152 + newVal.setId(oldVal.getId());
  153 + }
  154 + return same;
165 155 });
166 156  
167   - // 执行增删改
168   - MapUtils.findAndThen(data, "create", item -> seckillProductMapper.insertBatch(item));
169   - MapUtils.findAndThen(data, "delete", item -> seckillProductMapper.deleteBatchIds(
170   - CollectionUtils.convertSet(item, SeckillProductDO::getId)));
171   - MapUtils.findAndThen(data, "update", item -> seckillProductMapper.updateBatch(item));
  157 + // create
  158 + if (isNotEmpty(lists.get(0))) {
  159 + seckillProductMapper.insertBatch(lists.get(0));
  160 + }
  161 + // update
  162 + if (isNotEmpty(lists.get(1))) {
  163 + seckillProductMapper.updateBatch(lists.get(1));
  164 + }
  165 + // delete
  166 + if (isNotEmpty(lists.get(2))) {
  167 + seckillProductMapper.deleteBatchIds(convertList(lists.get(2), SeckillProductDO::getId));
  168 + }
172 169 }
173 170  
174 171 @Override
... ... @@ -198,7 +195,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
198 195 seckillActivityMapper.deleteById(id);
199 196 // 删除活动商品
200 197 List<SeckillProductDO> productDOs = seckillProductMapper.selectListByActivityId(id);
201   - Set<Long> convertSet = CollectionUtils.convertSet(productDOs, SeckillProductDO::getSkuId);
  198 + Set<Long> convertSet = convertSet(productDOs, SeckillProductDO::getSkuId);
202 199 seckillProductMapper.deleteBatchIds(convertSet);
203 200 }
204 201  
... ...
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.collection.CollUtil;
4 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 5 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
... ... @@ -12,6 +11,7 @@ import java.util.Set;
12 11 import java.util.function.Function;
13 12  
14 13 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  14 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
15 15 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
16 16  
17 17 /**
... ... @@ -31,22 +31,19 @@ public class PromotionUtils {
31 31 return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus();
32 32 }
33 33  
34   - // TODO @puhui999:是不是第一个参数是 sku;然后是 products;这样关联性好点;
35 34 /**
36 35 * 校验商品 sku 是否都存在
37 36 *
38   - * @param products 需要校验的商品
39 37 * @param skus 数据库中的商品 skus
  38 + * @param products 需要校验的商品
40 39 * @param func 获取需要校验的商品的 skuId
41 40 */
42   - public static <T> void validateProductSkuAllExists(List<T> products, List<ProductSkuRespDTO> skus, Function<T, Long> func) {
  41 + public static <T> void validateProductSkuAllExists(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) {
43 42 // 校验 sku 个数是否一致
44 43 Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func);
45 44 Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skus, ProductSkuRespDTO::getId);
46 45 // 校验 skuId 是否存在
47   - // TODO @puhui999:findFirst
48   - List<Long> f = CollectionUtils.filterList(skuIdsSet, s -> !skuIdsSet1.contains(s));
49   - if (CollUtil.isNotEmpty(f)) {
  46 + if (anyMatch(skuIdsSet, s -> !skuIdsSet1.contains(s))) {
50 47 throw exception(SKU_NOT_EXISTS);
51 48 }
52 49 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
... ... @@ -3,12 +3,10 @@ package cn.iocoder.yudao.module.trade.service.order;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.lang.Assert;
5 5 import cn.hutool.core.util.IdUtil;
6   -import cn.hutool.core.util.ObjectUtil;
7 6 import cn.hutool.core.util.StrUtil;
8 7 import cn.iocoder.yudao.framework.common.core.KeyValue;
9 8 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
10 9 import cn.iocoder.yudao.framework.common.pojo.PageResult;
11   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
12 10 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
13 11 import cn.iocoder.yudao.module.member.api.address.AddressApi;
14 12 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
... ... @@ -59,9 +57,10 @@ import javax.annotation.Resource;
59 57 import java.time.LocalDateTime;
60 58 import java.util.*;
61 59  
  60 +import static cn.hutool.core.util.ObjectUtil.equal;
  61 +import static cn.hutool.core.util.ObjectUtil.notEqual;
62 62 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
63   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
64   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
  63 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
65 64 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
66 65 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
67 66 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
... ... @@ -171,7 +170,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
171 170 afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO);
172 171 // 3.3 校验订单类型
173 172 // 拼团
174   - if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  173 + if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
175 174 MemberUserRespDTO user = memberUserApi.getUser(userId);
176 175 // TODO 拼团一次应该只能选择一种规格的商品
177 176 // TODO @puhui999:应该是前置校验哈;然后不应该设置状态,而是交给拼团记录那处理;
... ... @@ -179,7 +178,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
179 178 .setStatus(CombinationRecordStatusEnum.WAITING.getStatus()));
180 179 }
181 180 // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
182   - if (ObjectUtil.equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
  181 + if (equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
183 182  
184 183 }
185 184  
... ... @@ -206,7 +205,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
206 205 TradePriceCalculateRespBO calculateRespBO) {
207 206 // 用户选择物流配送的时候才需要填写收货地址
208 207 AddressRespDTO address = new AddressRespDTO();
209   - if (ObjectUtil.equal(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getMode())) {
  208 + if (equal(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getMode())) {
210 209 // 用户收件地址的校验
211 210 address = validateAddress(userId, createReqVO.getAddressId());
212 211 }
... ... @@ -310,7 +309,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
310 309 }
311 310 // 校验活动
312 311 // 1、拼团活动
313   - if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  312 + if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
314 313 // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
315 314 combinationRecordApi.updateCombinationRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
316 315 }
... ... @@ -344,7 +343,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
344 343 throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
345 344 }
346 345 // 校验支付订单匹配
347   - if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号
  346 + if (notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号
348 347 log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
349 348 id, payOrderId, JsonUtils.toJsonString(order));
350 349 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
... ... @@ -363,13 +362,13 @@ public class TradeOrderServiceImpl implements TradeOrderService {
363 362 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
364 363 }
365 364 // 校验支付金额一致
366   - if (ObjectUtil.notEqual(payOrder.getPrice(), order.getPayPrice())) {
  365 + if (notEqual(payOrder.getPrice(), order.getPayPrice())) {
367 366 log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
368 367 id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder));
369 368 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
370 369 }
371 370 // 校验支付订单匹配(二次)
372   - if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) {
  371 + if (notEqual(payOrder.getMerchantOrderId(), id.toString())) {
373 372 log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
374 373 id, payOrderId, JsonUtils.toJsonString(payOrder));
375 374 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
... ... @@ -393,7 +392,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
393 392 TradeOrderDO updateOrderObj = new TradeOrderDO();
394 393 // 判断发货类型
395 394 // 2.1 快递发货
396   - if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
  395 + if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
397 396 // 校验快递公司
398 397 // TODO @puhui999:getDeliveryExpress 直接封装一个校验的,会不会好点;因为还有开启关闭啥的;
399 398 DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
... ... @@ -403,13 +402,13 @@ public class TradeOrderServiceImpl implements TradeOrderService {
403 402 updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo());
404 403 }
405 404 // 2.2 用户自提
406   - if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.PICK_UP.getMode())) {
  405 + if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.PICK_UP.getMode())) {
407 406 // TODO 校验自提门店是否存在
408 407 // 重置一下确保快递公司和快递单号为空
409 408 updateOrderObj.setLogisticsId(null).setLogisticsNo("");
410 409 }
411 410 // 2.3 TODO 芋艿:如果无需发货,需要怎么存储?回复:需要把 deliverType 设置为 DeliveryTypeEnum.NULL
412   - if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.NULL.getMode())) {
  411 + if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.NULL.getMode())) {
413 412 // TODO 情况一:正常走发货逻辑和用户自提有点像 不同点:不需要自提门店只需要用户确认收货
414 413 // TODO 情况二:用户下单付款后直接确认收货或等待用户确认收货
415 414 // 重置一下确保快递公司和快递单号为空
... ... @@ -449,15 +448,15 @@ public class TradeOrderServiceImpl implements TradeOrderService {
449 448 }
450 449 // 校验订单是否是待发货状态
451 450 if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())
452   - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) {
  451 + || notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) {
453 452 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
454 453 }
455 454 // 校验订单是否退款
456   - if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
  455 + if (notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
457 456 throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE);
458 457 }
459 458 // 订单类型:拼团
460   - if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  459 + if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
461 460 // 校验订单拼团是否成功
462 461 // TODO 用户 ID 使用当前登录用户的还是订单保存的?
463 462 if (combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) {
... ... @@ -510,7 +509,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
510 509 }
511 510 // 校验订单是否是待收货状态
512 511 if (!TradeOrderStatusEnum.isDelivered(order.getStatus())
513   - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus())) {
  512 + || notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus())) {
514 513 throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
515 514 }
516 515 return order;
... ... @@ -520,7 +519,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
520 519 public TradeOrderDO getOrder(Long userId, Long id) {
521 520 TradeOrderDO order = tradeOrderMapper.selectById(id);
522 521 if (order != null
523   - && ObjectUtil.notEqual(order.getUserId(), userId)) {
  522 + && notEqual(order.getUserId(), userId)) {
524 523 return null;
525 524 }
526 525 return order;
... ... @@ -564,7 +563,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
564 563 public TradeOrderItemDO getOrderItem(Long userId, Long itemId) {
565 564 TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(itemId);
566 565 if (orderItem != null
567   - && ObjectUtil.notEqual(orderItem.getUserId(), userId)) {
  566 + && notEqual(orderItem.getUserId(), userId)) {
568 567 return null;
569 568 }
570 569 return orderItem;
... ... @@ -644,10 +643,10 @@ public class TradeOrderServiceImpl implements TradeOrderService {
644 643 if (order == null) {
645 644 throw exception(ORDER_NOT_FOUND);
646 645 }
647   - if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
  646 + if (notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
648 647 throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);
649 648 }
650   - if (ObjectUtil.notEqual(order.getCommentStatus(), Boolean.FALSE)) {
  649 + if (notEqual(order.getCommentStatus(), Boolean.FALSE)) {
651 650 throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
652 651 }
653 652  
... ... @@ -657,7 +656,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
657 656 // 更新订单项评价状态
658 657 tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE));
659 658 List<TradeOrderItemDO> orderItems = getOrderItemListByOrderId(CollUtil.newArrayList(order.getId()));
660   - if (!CollectionUtils.isAny(orderItems, item -> ObjectUtil.equal(item.getCommentStatus(), Boolean.FALSE))) {
  659 + if (!anyMatch(orderItems, item -> equal(item.getCommentStatus(), Boolean.FALSE))) {
661 660 // 对于 order 来说,就是评论完,把 order 更新完合理的 status 等字段。
662 661 tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE));
663 662 }
... ...