Commit 0219e6d907ad6fa5a75172bfac37fae109a089ef

Authored by 芋道源码
Committed by Gitee
2 parents 222d1cf6 384359c9

!555 完善拼团、秒杀、砍价活动管理

Merge pull request !555 from puhui999/feature/mall_product
Showing 50 changed files with 1331 additions and 349 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-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
... ... @@ -82,14 +82,20 @@ public class LocalDateTimeUtils {
82 82 || startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
83 83 }
84 84  
  85 + /**
  86 + * 判断时间段是否重叠
  87 + *
  88 + * @param startTime1 开始 time1
  89 + * @param endTime1 结束 time1
  90 + * @param startTime2 开始 time2
  91 + * @param endTime2 结束 time2
  92 + * @return 重叠:true 不重叠:false
  93 + */
85 94 public static boolean isOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) {
86 95 // 日期部分使用了当前日期LocalDate.now()
87   - // TODO @puhui999:LocalDate.now() 抽一个变量,啊哈;然后注释写下;之后 4 个变量不用,直接调方法的时候,直接计算作为入参;
88   - LocalDateTime startDateTime1 = LocalDateTime.of(LocalDate.now(), startTime1);
89   - LocalDateTime endDateTime1 = LocalDateTime.of(LocalDate.now(), endTime1);
90   - LocalDateTime startDateTime2 = LocalDateTime.of(LocalDate.now(), startTime2);
91   - LocalDateTime endDateTime2 = LocalDateTime.of(LocalDate.now(), endTime2);
92   - return LocalDateTimeUtil.isOverlap(startDateTime1, endDateTime1, startDateTime2, endDateTime2);
  96 + LocalDate nowDate = LocalDate.now();
  97 + return LocalDateTimeUtil.isOverlap(LocalDateTime.of(nowDate, startTime1), LocalDateTime.of(nowDate, endTime1),
  98 + LocalDateTime.of(nowDate, startTime2), LocalDateTime.of(nowDate, endTime2));
93 99 }
94 100  
95 101 }
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.bargain;
  2 +
  3 +import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainRecordCreateReqDTO;
  4 +
  5 +import javax.validation.Valid;
  6 +
  7 +// TODO @芋艿:后面也再撸撸这几个接口
  8 +
  9 +/**
  10 + * 砍价记录 API 接口
  11 + *
  12 + * @author HUIHUI
  13 + */
  14 +public interface BargainRecordApi {
  15 +
  16 + /**
  17 + * 创建开团记录
  18 + *
  19 + * @param reqDTO 请求 DTO
  20 + */
  21 + void createRecord(@Valid BargainRecordCreateReqDTO reqDTO);
  22 +
  23 +}
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainRecordCreateReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.bargain.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.validation.constraints.NotEmpty;
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +// TODO @芋艿:这块要在看看
  9 +
  10 +/**
  11 + * 砍价记录的创建 Request DTO
  12 + *
  13 + * @author HUIHUI
  14 + */
  15 +@Data
  16 +public class BargainRecordCreateReqDTO {
  17 +
  18 + /**
  19 + * 砍价活动编号
  20 + */
  21 + @NotNull(message = "砍价活动编号不能为空")
  22 + private Long activityId;
  23 + /**
  24 + * spu 编号
  25 + */
  26 + @NotNull(message = "spu 编号不能为空")
  27 + private Long spuId;
  28 + /**
  29 + * sku 编号
  30 + */
  31 + @NotNull(message = "sku 编号不能为空")
  32 + private Long skuId;
  33 + /**
  34 + * 用户编号
  35 + */
  36 + @NotNull(message = "用户编号不能为空")
  37 + private Long userId;
  38 + /**
  39 + * 订单编号
  40 + */
  41 + @NotNull(message = "订单编号不能为空")
  42 + private Long orderId;
  43 + /**
  44 + * 商品名字
  45 + */
  46 + @NotEmpty(message = "商品名字不能为空")
  47 + private String spuName;
  48 + /**
  49 + * 商品图片
  50 + */
  51 + @NotEmpty(message = "商品图片不能为空")
  52 + private String picUrl;
  53 + /**
  54 + * 砍价商品单价
  55 + */
  56 + @NotNull(message = "砍价底价不能为空")
  57 + private Integer bargainPrice;
  58 + /**
  59 + * 商品原价,单位分
  60 + */
  61 + @NotNull(message = "商品原价不能为空")
  62 + private Integer price;
  63 + /**
  64 + * 用户昵称
  65 + */
  66 + @NotEmpty(message = "用户昵称不能为空")
  67 + private String nickname;
  68 + /**
  69 + * 用户头像
  70 + */
  71 + @NotEmpty(message = "用户头像不能为空")
  72 + private String avatar;
  73 + /**
  74 + * 开团状态:进行中 砍价成功 砍价失败
  75 + */
  76 + @NotNull(message = "开团状态不能为空")
  77 + private Integer status;
  78 +
  79 +}
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
1 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
  4 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
4 5  
5 6 import javax.validation.Valid;
6 7  
... ... @@ -17,7 +18,7 @@ public interface CombinationRecordApi {
17 18 *
18 19 * @param reqDTO 请求 DTO
19 20 */
20   - void createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
  21 + void createRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
21 22  
22 23 /**
23 24 * 查询拼团记录是否成功
... ... @@ -26,25 +27,13 @@ public interface CombinationRecordApi {
26 27 * @param orderId 订单编号
27 28 * @return 拼团是否成功
28 29 */
29   - boolean isCombinationRecordSuccess(Long userId, Long orderId);
  30 + boolean isRecordSuccess(Long userId, Long orderId);
30 31  
31   - // TODO @puhui999:updateRecordStatus 和 updateRecordStatusAndStartTime 看看后续是不是可以统一掉;
32 32 /**
33 33 * 更新开团记录状态
34 34 *
35   - * @param userId 用户编号
36   - * @param orderId 订单编号
37   - * @param status 状态值
38   - */
39   - void updateCombinationRecordStatus(Long userId, Long orderId, Integer status);
40   -
41   - /**
42   - * 更新开团记录状态和开始时间
43   - *
44   - * @param userId 用户编号
45   - * @param orderId 订单编号
46   - * @param status 状态值
  35 + * @param reqDTO 请求 DTO
47 36 */
48   - void updateCombinationRecordStatusAndStartTime(Long userId, Long orderId, Integer status);
  37 + void updateRecordStatus(CombinationRecordUpdateReqDTO reqDTO);
49 38  
50 39 }
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateReqDTO.java
... ... @@ -70,7 +70,7 @@ public class CombinationRecordCreateReqDTO {
70 70 @NotEmpty(message = "用户头像不能为空")
71 71 private String avatar;
72 72 /**
73   - * 开团状态:正在开团 拼团成功 拼团失败 TODO 等待支付
  73 + * 开团状态:正在开团 拼团成功 拼团失败
74 74 */
75 75 @NotNull(message = "开团状态不能为空")
76 76 private Integer status;
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordUpdateReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.combination.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.validation.constraints.NotNull;
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 + * 拼团记录的更新 Request DTO
  10 + *
  11 + * @author HUIHUI
  12 + */
  13 +@Data
  14 +public class CombinationRecordUpdateReqDTO {
  15 +
  16 + /**
  17 + * 用户编号
  18 + */
  19 + @NotNull(message = "用户编号不能为空")
  20 + private Long userId;
  21 +
  22 + /**
  23 + * 订单编号
  24 + */
  25 + @NotNull(message = "订单编号不能为空")
  26 + private Long orderId;
  27 +
  28 + /**
  29 + * 开团状态:正在开团 拼团成功 拼团失败
  30 + */
  31 + @NotNull(message = "开团状态不能为空")
  32 + private Integer status;
  33 +
  34 + /**
  35 + * 团开始时间
  36 + */
  37 + private LocalDateTime startTime;
  38 +
  39 +}
... ...
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-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/combination/CombinationRecordStatusEnum.java
... ... @@ -16,10 +16,9 @@ import java.util.Arrays;
16 16 @Getter
17 17 public enum CombinationRecordStatusEnum implements IntArrayValuable {
18 18  
19   - WAITING(0, "未付款"),
20   - IN_PROGRESS(1, "进行中"),
21   - SUCCESS(2, "拼团成功"),
22   - FAILED(3, "拼团失败");
  19 + IN_PROGRESS(0, "进行中"),
  20 + SUCCESS(1, "拼团成功"),
  21 + FAILED(2, "拼团失败");
23 22  
24 23 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CombinationRecordStatusEnum::getStatus).toArray();
25 24  
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
1 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
  4 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
4 5 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
5 6 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
6 7 import org.springframework.stereotype.Service;
7 8  
8 9 import javax.annotation.Resource;
9   -import java.time.LocalDateTime;
10 10  
11 11 /**
12 12 * 拼团活动 API 实现类
... ... @@ -20,23 +20,22 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
20 20 private CombinationRecordService recordService;
21 21  
22 22 @Override
23   - public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
  23 + public void createRecord(CombinationRecordCreateReqDTO reqDTO) {
24 24 recordService.createCombinationRecord(reqDTO);
25 25 }
26 26  
27 27 @Override
28   - public boolean isCombinationRecordSuccess(Long userId, Long orderId) {
  28 + public boolean isRecordSuccess(Long userId, Long orderId) {
29 29 return CombinationRecordStatusEnum.isSuccess(recordService.getCombinationRecord(userId, orderId).getStatus());
30 30 }
31 31  
32 32 @Override
33   - public void updateCombinationRecordStatus(Long userId, Long orderId, Integer status) {
34   - recordService.updateCombinationRecordStatusByUserIdAndOrderId(userId, orderId, status);
35   - }
36   -
37   - @Override
38   - public void updateCombinationRecordStatusAndStartTime(Long userId, Long orderId, Integer status) {
39   - recordService.updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(userId, orderId, status, LocalDateTime.now());
  33 + public void updateRecordStatus(CombinationRecordUpdateReqDTO reqDTO) {
  34 + if (null == reqDTO.getStartTime()) {
  35 + recordService.updateCombinationRecordStatusByUserIdAndOrderId(reqDTO);
  36 + } else {
  37 + recordService.updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(reqDTO);
  38 + }
40 39 }
41 40  
42 41 }
... ...
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 + private Integer successCount;
  34 +
  35 + @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  36 + @NotNull(message = "活动状态不能为空")
  37 + private Integer status;
  38 +
  39 + @Schema(description = "砍价商品", requiredMode = Schema.RequiredMode.REQUIRED)
  40 + @Valid
  41 + private List<BargainProductRespVO> products;
  42 +
  43 +}
... ...
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/BargainAssistDO.java
... ... @@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
7 7 import lombok.*;
8 8  
9 9 /**
10   - * 砍价助力 DO
  10 + * 砍价助力 DO TODO
11 11 *
12 12 * @author HUIHUI
13 13 */
... ...
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/dataobject/bargain/BargainRecordDO.java
... ... @@ -9,7 +9,7 @@ import lombok.*;
9 9 import java.time.LocalDateTime;
10 10  
11 11 /**
12   - * 砍价记录 DO
  12 + * 砍价记录 DO TODO
13 13 *
14 14 * @author HUIHUI
15 15 */
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java
... ... @@ -52,7 +52,7 @@ public class CombinationRecordDO extends BaseDO {
52 52 /**
53 53 * 团长编号
54 54 *
55   - * 关联 {@link CombinationRecordDO#getUserId()}
  55 + * 关联 {@link CombinationRecordDO#getId()}
56 56 */
57 57 private Long headId;
58 58 /**
... ...
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.module.promotion.dal.dataobject.bargain.BargainRecordDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +/**
  8 + * 砍价记录 Mapper
  9 + *
  10 + * @author HUIHUI
  11 + */
  12 +@Mapper
  13 +public interface BargainRecordMapper extends BaseMapperX<BargainRecordDO> {
  14 +
  15 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationRecordMapper.java
... ... @@ -15,8 +15,7 @@ import java.util.List;
15 15 @Mapper
16 16 public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO> {
17 17  
18   - // TODO @puhui999:selectByUserIdAndOrderId
19   - default CombinationRecordDO selectRecord(Long userId, Long orderId) {
  18 + default CombinationRecordDO selectByUserIdAndOrderId(Long userId, Long orderId) {
20 19 return selectOne(CombinationRecordDO::getUserId, userId,
21 20 CombinationRecordDO::getOrderId, orderId);
22 21 }
... ... @@ -29,9 +28,10 @@ public interface CombinationRecordMapper extends BaseMapperX&lt;CombinationRecordDO
29 28 * @return 拼团记录
30 29 */
31 30 default CombinationRecordDO selectRecordByHeadId(Long headId, Long activityId, Integer status) {
32   - return selectOne(CombinationRecordDO::getHeadId, headId,
33   - CombinationRecordDO::getActivityId, activityId,
34   - CombinationRecordDO::getStatus, status);
  31 + return selectOne(new LambdaQueryWrapperX<CombinationRecordDO>()
  32 + .eq(CombinationRecordDO::getUserId, headId)
  33 + .eq(CombinationRecordDO::getActivityId, activityId)
  34 + .eq(CombinationRecordDO::getStatus, status));
35 35 }
36 36  
37 37 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 pageReqVO 分页查询
  55 + * @return 砍价活动分页
  56 + */
  57 + PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO);
  58 +
  59 + /**
  60 + * 获得砍价活动商品列表
  61 + *
  62 + * @param ids 砍价活动 ids
  63 + * @return 砍价活动的商品列表
  64 + */
  65 + List<BargainProductDO> getBargainProductsByActivityIds(Collection<Long> ids);
  66 +
  67 +}
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApi.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainRecordService.java
1   -package cn.iocoder.yudao.module.promotion.api.combination;
  1 +package cn.iocoder.yudao.module.promotion.service.bargain;
  2 +
2 3  
3 4 /**
4   - * 拼团活动 API 接口
  5 + * 商品活动记录 service
5 6 *
6 7 * @author HUIHUI
7 8 */
8   -public interface CombinationActivityApi {
  9 +public interface BargainRecordService {
  10 +
  11 +// TODO
9 12  
10 13 }
... ...
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.mysql.bargain.BargainActivityMapper;
  22 +import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainProductMapper;
  23 +import cn.iocoder.yudao.module.promotion.dal.mysql.bargain.BargainRecordMapper;
  24 +import org.springframework.stereotype.Service;
  25 +import org.springframework.transaction.annotation.Transactional;
  26 +import org.springframework.validation.annotation.Validated;
  27 +
  28 +import javax.annotation.Resource;
  29 +import java.util.Collection;
  30 +import java.util.List;
  31 +
  32 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  33 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
  34 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
  35 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
  36 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
  37 +import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuAllExists;
  38 +
  39 +/**
  40 + * 砍价活动 Service 实现类
  41 + *
  42 + * @author HUIHUI
  43 + */
  44 +@Service
  45 +@Validated
  46 +public class BargainServiceImpl implements BargainActivityService, BargainRecordService {
  47 +
  48 + @Resource
  49 + private BargainActivityMapper bargainActivityMapper;
  50 + @Resource
  51 + private BargainRecordMapper recordMapper;
  52 + @Resource
  53 + private BargainProductMapper bargainProductMapper;
  54 + @Resource
  55 + private ProductSpuApi productSpuApi;
  56 + @Resource
  57 + private ProductSkuApi productSkuApi;
  58 +
  59 + @Override
  60 + @Transactional(rollbackFor = Exception.class)
  61 + public Long createBargainActivity(BargainActivityCreateReqVO createReqVO) {
  62 + // 校验商品 SPU 是否存在是否参加的别的活动
  63 + validateProductBargainConflict(createReqVO.getSpuId(), null);
  64 + // 获取所选 spu下的所有 sku
  65 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId()));
  66 + // 校验商品 sku 是否存在
  67 + validateProductSkuAllExists(skus, createReqVO.getProducts(), BargainProductCreateReqVO::getSkuId);
  68 +
  69 + // 插入砍价活动
  70 + BargainActivityDO activityDO = BargainActivityConvert.INSTANCE.convert(createReqVO);
  71 + // TODO 营销相关属性初始化 砍价成功更新相关属性
  72 + activityDO.setSuccessCount(0);
  73 + // 活动总库存
  74 + activityDO.setStock(getSumValue(createReqVO.getProducts(), BargainProductCreateReqVO::getStock, Integer::sum));
  75 + activityDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  76 + bargainActivityMapper.insert(activityDO);
  77 + // 插入商品
  78 + List<BargainProductDO> productDOs = BargainActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activityDO);
  79 + bargainProductMapper.insertBatch(productDOs);
  80 + // 返回
  81 + return activityDO.getId();
  82 + }
  83 +
  84 + private void validateProductBargainConflict(Long spuId, Long activityId) {
  85 + // 校验商品 spu 是否存在
  86 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));
  87 + if (CollUtil.isEmpty(spuList)) {
  88 + throw exception(SPU_NOT_EXISTS);
  89 + }
  90 + // 查询所有开启的砍价活动
  91 + List<BargainActivityDO> activityDOs = bargainActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
  92 + // 更新时排除自己
  93 + if (activityId != null) {
  94 + activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
  95 + }
  96 + // 校验商品 spu 是否参加了其它活动
  97 + if (anyMatch(activityDOs, s -> ObjectUtil.equal(s.getId(), spuId))) {
  98 + throw exception(BARGAIN_ACTIVITY_SPU_CONFLICTS);
  99 + }
  100 + }
  101 +
  102 + @Override
  103 + @Transactional(rollbackFor = Exception.class)
  104 + public void updateBargainActivity(BargainActivityUpdateReqVO updateReqVO) {
  105 + // 校验存在
  106 + BargainActivityDO activityDO = validateBargainActivityExists(updateReqVO.getId());
  107 + // 校验状态
  108 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  109 + throw exception(BARGAIN_ACTIVITY_STATUS_DISABLE);
  110 + }
  111 + // 校验商品冲突
  112 + validateProductBargainConflict(updateReqVO.getSpuId(), updateReqVO.getId());
  113 + // 获取所选 spu下的所有 sku
  114 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId()));
  115 + // 校验商品 sku 是否存在
  116 + validateProductSkuAllExists(skus, updateReqVO.getProducts(), BargainProductUpdateReqVO::getSkuId);
  117 +
  118 + // 更新
  119 + BargainActivityDO updateObj = BargainActivityConvert.INSTANCE.convert(updateReqVO);
  120 + // 更新活动库存
  121 + updateObj.setStock(getSumValue(updateReqVO.getProducts(), BargainProductUpdateReqVO::getStock, Integer::sum));
  122 + bargainActivityMapper.updateById(updateObj);
  123 + // 更新商品
  124 + updateBargainProduct(updateObj, updateReqVO.getProducts());
  125 + }
  126 +
  127 + /**
  128 + * 更新砍价商品
  129 + *
  130 + * @param updateObj 更新的活动
  131 + * @param products 商品配置
  132 + */
  133 + private void updateBargainProduct(BargainActivityDO updateObj, List<BargainProductUpdateReqVO> products) {
  134 + // 默认全部新增
  135 + List<BargainProductDO> defaultNewList = BargainActivityConvert.INSTANCE.convertList(products, updateObj);
  136 + // 数据库中的老数据
  137 + List<BargainProductDO> oldList = bargainProductMapper.selectListByActivityIds(CollUtil.newArrayList(updateObj.getId()));
  138 + List<List<BargainProductDO>> lists = CollectionUtils.diffList(oldList, defaultNewList, (oldVal, newVal) -> {
  139 + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId());
  140 + if (same) {
  141 + newVal.setId(oldVal.getId());
  142 + }
  143 + return same;
  144 + });
  145 +
  146 + // create
  147 + if (CollUtil.isNotEmpty(lists.get(0))) {
  148 + bargainProductMapper.insertBatch(lists.get(0));
  149 + }
  150 + // update
  151 + if (CollUtil.isNotEmpty(lists.get(1))) {
  152 + bargainProductMapper.updateBatch(lists.get(1));
  153 + }
  154 + // delete
  155 + if (CollUtil.isNotEmpty(lists.get(2))) {
  156 + bargainProductMapper.deleteBatchIds(CollectionUtils.convertList(lists.get(2), BargainProductDO::getId));
  157 + }
  158 + }
  159 +
  160 + @Override
  161 + @Transactional(rollbackFor = Exception.class)
  162 + public void deleteBargainActivity(Long id) {
  163 + // 校验存在
  164 + BargainActivityDO activityDO = validateBargainActivityExists(id);
  165 + // 校验状态
  166 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  167 + throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
  168 + }
  169 +
  170 + // 删除
  171 + bargainActivityMapper.deleteById(id);
  172 + }
  173 +
  174 + private BargainActivityDO validateBargainActivityExists(Long id) {
  175 + BargainActivityDO activityDO = bargainActivityMapper.selectById(id);
  176 + if (activityDO == null) {
  177 + throw exception(BARGAIN_ACTIVITY_NOT_EXISTS);
  178 + }
  179 + return activityDO;
  180 + }
  181 +
  182 + @Override
  183 + public BargainActivityDO getBargainActivity(Long id) {
  184 + return validateBargainActivityExists(id);
  185 + }
  186 +
  187 + @Override
  188 + public PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO) {
  189 + return bargainActivityMapper.selectPage(pageReqVO);
  190 + }
  191 +
  192 + @Override
  193 + public List<BargainProductDO> getBargainProductsByActivityIds(Collection<Long> ids) {
  194 + return bargainProductMapper.selectListByActivityIds(ids);
  195 + }
  196 +
  197 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
1 1 package cn.iocoder.yudao.module.promotion.service.combination;
2 2  
3 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
  4 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
4 5 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
5 6  
6   -import java.time.LocalDateTime;
7   -
8 7 /**
9 8 * 商品活动记录 service
10 9 *
... ... @@ -15,11 +14,9 @@ public interface CombinationRecordService {
15 14 /**
16 15 * 更新拼团状态
17 16 *
18   - * @param userId 用户编号
19   - * @param orderId 订单编号
20   - * @param status 状态
  17 + * @param reqDTO 请求 DTO
21 18 */
22   - void updateCombinationRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status);
  19 + void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO);
23 20  
24 21 /**
25 22 * 创建拼团记录
... ... @@ -31,13 +28,9 @@ public interface CombinationRecordService {
31 28 /**
32 29 * 更新拼团状态和开始时间
33 30 *
34   - * @param userId 用户编号
35   - * @param orderId 订单编号
36   - * @param status 状态
37   - * @param startTime 开始时间
  31 + * @param reqDTO 请求 DTO
38 32 */
39   - void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId,
40   - Integer status, LocalDateTime startTime);
  33 + void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO);
41 34  
42 35 /**
43 36 * 获得拼团状态
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationServiceImpl.java
... ... @@ -2,17 +2,16 @@ 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;
14 12 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
15 13 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
  14 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
16 15 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
17 16 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
18 17 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
... ... @@ -31,8 +30,8 @@ import org.springframework.transaction.annotation.Transactional;
31 30 import org.springframework.validation.annotation.Validated;
32 31  
33 32 import javax.annotation.Resource;
34   -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);
... ... @@ -207,27 +204,27 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
207 204 }
208 205  
209 206 @Override
210   - public void updateCombinationRecordStatusByUserIdAndOrderId(Long userId, Long orderId, Integer status) {
  207 + public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO) {
211 208 // 校验拼团是否存在
212   - CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
  209 + CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
213 210  
214 211 // 更新状态
215   - recordDO.setStatus(status);
  212 + recordDO.setStatus(reqDTO.getStatus());
216 213 recordMapper.updateById(recordDO);
217 214 }
218 215  
219 216 @Override
220 217 @Transactional(rollbackFor = Exception.class)
221   - public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime) {
222   - CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
  218 + public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateReqDTO reqDTO) {
  219 + CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
223 220 // 更新状态
224   - recordDO.setStatus(status);
  221 + recordDO.setStatus(reqDTO.getStatus());
225 222 // 更新开始时间
226   - recordDO.setStartTime(startTime);
  223 + recordDO.setStartTime(reqDTO.getStartTime());
227 224 recordMapper.updateById(recordDO);
228 225  
229 226 // 更新拼团参入人数
230   - List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status);
  227 + List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), reqDTO.getStatus());
231 228 if (CollUtil.isNotEmpty(recordDOs)) {
232 229 recordDOs.forEach(item -> {
233 230 item.setUserCount(recordDOs.size());
... ... @@ -242,7 +239,7 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
242 239  
243 240 private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) {
244 241 // 校验拼团是否存在
245   - CombinationRecordDO recordDO = recordMapper.selectRecord(userId, orderId);
  242 + CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(userId, orderId);
246 243 if (recordDO == null) {
247 244 throw exception(COMBINATION_RECORD_NOT_EXISTS);
248 245 }
... ... @@ -254,7 +251,7 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
254 251 // 1.1 校验拼团活动
255 252 CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId());
256 253 // 1.2 需要校验下,他当前是不是已经参加了该拼团;
257   - CombinationRecordDO recordDO = recordMapper.selectRecord(reqDTO.getUserId(), reqDTO.getOrderId());
  254 + CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(reqDTO.getUserId(), reqDTO.getOrderId());
258 255 if (recordDO != null) {
259 256 throw exception(COMBINATION_RECORD_EXISTS);
260 257 }
... ... @@ -273,10 +270,6 @@ public class CombinationServiceImpl implements CombinationActivityService, Combi
273 270  
274 271 // 2. 创建拼团记录
275 272 CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
276   - if (reqDTO.getHeadId() == null) {
277   - // TODO @puhui999:不是自己呀;headId 是父团长的 CombinationRecordDO.id 哈
278   - record.setHeadId(reqDTO.getUserId());
279   - }
280 273 record.setVirtualGroup(false);
281 274 // TODO @puhui999:过期时间,应该是 Date 哈;
282 275 record.setExpireTime(activity.getLimitDuration());
... ...
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-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
... ... @@ -62,6 +62,7 @@ public interface ErrorCodeConstants {
62 62 ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在");
63 63 ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011004001, "已经存在该编码的快递公司");
64 64 ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004002, "需要接入快递服务商,比如【快递100】");
  65 + ErrorCode EXPRESS_STATUS_NOT_ENABLE = new ErrorCode(1011004003, "快递公司未启用");
65 66  
66 67 ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004101, "快递查询接口异常");
67 68 ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004102, "快递查询返回失败,原因:{}");
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/MessageTemplateConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums;
  2 +
  3 +/**
  4 + * 通知模板枚举类
  5 + *
  6 + * @author HUIHUI
  7 + */
  8 +public interface MessageTemplateConstants {
  9 +
  10 + String ORDER_DELIVERY = "order_delivery"; // 短信模版编号
  11 +
  12 +}
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/notify/TradeNotifyEnums.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums.notify;
  2 +
  3 +public interface TradeNotifyEnums {
  4 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/message/TradeMessageService.java
1 1 package cn.iocoder.yudao.module.trade.service.message;
2 2  
3   -import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDeliveryOrderReqDTO;
  3 +import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
4 4  
5 5 /**
6 6 * Trade 消息 service 接口
... ... @@ -10,10 +10,10 @@ import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDe
10 10 public interface TradeMessageService {
11 11  
12 12 /**
13   - * 订单发货时发送消息
  13 + * 订单发货时发送通知
14 14 *
15   - * @param reqDTO 发送消息
  15 + * @param reqBO 发送消息
16 16 */
17   - void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqDTO reqDTO);
  17 + void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqBO reqBO);
18 18  
19 19 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/message/TradeMessageServiceImpl.java
... ... @@ -2,7 +2,8 @@ package cn.iocoder.yudao.module.trade.service.message;
2 2  
3 3 import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
4 4 import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
5   -import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDeliveryOrderReqDTO;
  5 +import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants;
  6 +import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
6 7 import org.springframework.stereotype.Service;
7 8 import org.springframework.validation.annotation.Validated;
8 9  
... ... @@ -23,18 +24,16 @@ public class TradeMessageServiceImpl implements TradeMessageService {
23 24 private NotifyMessageSendApi notifyMessageSendApi;
24 25  
25 26 @Override
26   - public void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqDTO reqDTO) {
  27 + public void sendMessageWhenDeliveryOrder(TradeOrderMessageWhenDeliveryOrderReqBO reqBO) {
27 28 // 1、构造消息
28   - Map<String, Object> msgMap = new HashMap<>();
29   - msgMap.put("orderId", reqDTO.getOrderId());
30   - // TODO puhui999:应该不是 msg 哇,应该是涉及到的模版参数哈;msg 太大了
31   - msgMap.put("msg", reqDTO.getMessage());
  29 + Map<String, Object> msgMap = new HashMap<>(2);
  30 + msgMap.put("orderId", reqBO.getOrderId());
  31 + msgMap.put("deliveryMessage", reqBO.getMessage());
32 32 // 2、发送站内信
33 33 notifyMessageSendApi.sendSingleMessageToMember(
34 34 new NotifySendSingleToUserReqDTO()
35   - .setUserId(reqDTO.getUserId())
36   - // TODO puhui999:短信模版编号,枚举起来;
37   - .setTemplateCode("order_delivery")
  35 + .setUserId(reqBO.getUserId())
  36 + .setTemplateCode(MessageTemplateConstants.ORDER_DELIVERY)
38 37 .setTemplateParams(msgMap));
39 38 }
40 39  
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/message/dto/TradeOrderMessageWhenDeliveryOrderReqDTO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/message/bo/TradeOrderMessageWhenDeliveryOrderReqBO.java
1   -package cn.iocoder.yudao.module.trade.service.message.dto;
  1 +package cn.iocoder.yudao.module.trade.service.message.bo;
2 2  
3 3 import lombok.Data;
4 4  
5 5 import javax.validation.constraints.NotEmpty;
6 6 import javax.validation.constraints.NotNull;
7 7  
8   -// TODO @puhui999:改成 ReqBO 哈;包名也换了;service 我们还是同一用 bo 对象
9 8 /**
10   - * 订单发货时 Req DTO
  9 + * 订单发货时通知创建 Req BO
11 10 *
12 11 * @author HUIHUI
13 12 */
14 13 @Data
15   -public class TradeOrderMessageWhenDeliveryOrderReqDTO {
  14 +public class TradeOrderMessageWhenDeliveryOrderReqBO {
16 15  
17 16 /**
18 17 * 订单编号
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
... ... @@ -3,12 +3,11 @@ 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;
  8 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
9 9 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
10 10 import cn.iocoder.yudao.framework.common.pojo.PageResult;
11   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
12 11 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
13 12 import cn.iocoder.yudao.module.member.api.address.AddressApi;
14 13 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
... ... @@ -23,6 +22,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT
23 22 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
24 23 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
25 24 import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
  25 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateReqDTO;
26 26 import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
27 27 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
28 28 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
... ... @@ -47,7 +47,7 @@ import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties
47 47 import cn.iocoder.yudao.module.trade.service.cart.TradeCartService;
48 48 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
49 49 import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
50   -import cn.iocoder.yudao.module.trade.service.message.dto.TradeOrderMessageWhenDeliveryOrderReqDTO;
  50 +import cn.iocoder.yudao.module.trade.service.message.bo.TradeOrderMessageWhenDeliveryOrderReqBO;
51 51 import cn.iocoder.yudao.module.trade.service.price.TradePriceService;
52 52 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
53 53 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
... ... @@ -59,9 +59,10 @@ import javax.annotation.Resource;
59 59 import java.time.LocalDateTime;
60 60 import java.util.*;
61 61  
  62 +import static cn.hutool.core.util.ObjectUtil.equal;
  63 +import static cn.hutool.core.util.ObjectUtil.notEqual;
62 64 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;
  65 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
65 66 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
66 67 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
67 68 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
... ... @@ -171,15 +172,13 @@ public class TradeOrderServiceImpl implements TradeOrderService {
171 172 afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO);
172 173 // 3.3 校验订单类型
173 174 // 拼团
174   - if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  175 + if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
175 176 MemberUserRespDTO user = memberUserApi.getUser(userId);
176 177 // TODO 拼团一次应该只能选择一种规格的商品
177   - // TODO @puhui999:应该是前置校验哈;然后不应该设置状态,而是交给拼团记录那处理;
178   - combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user)
179   - .setStatus(CombinationRecordStatusEnum.WAITING.getStatus()));
  178 + combinationRecordApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user));
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,9 +309,10 @@ 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   - combinationRecordApi.updateCombinationRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
  314 + combinationRecordApi.updateRecordStatus(new CombinationRecordUpdateReqDTO().setUserId(order.getUserId())
  315 + .setOrderId(order.getId()).setStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus()).setStartTime(LocalDateTime.now()));
316 316 }
317 317 // TODO 芋艿:发送订单变化的消息
318 318  
... ... @@ -344,7 +344,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
344 344 throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
345 345 }
346 346 // 校验支付订单匹配
347   - if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号
  347 + if (notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号
348 348 log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
349 349 id, payOrderId, JsonUtils.toJsonString(order));
350 350 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
... ... @@ -363,13 +363,13 @@ public class TradeOrderServiceImpl implements TradeOrderService {
363 363 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
364 364 }
365 365 // 校验支付金额一致
366   - if (ObjectUtil.notEqual(payOrder.getPrice(), order.getPayPrice())) {
  366 + if (notEqual(payOrder.getPrice(), order.getPayPrice())) {
367 367 log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
368 368 id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder));
369 369 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
370 370 }
371 371 // 校验支付订单匹配(二次)
372   - if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) {
  372 + if (notEqual(payOrder.getMerchantOrderId(), id.toString())) {
373 373 log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
374 374 id, payOrderId, JsonUtils.toJsonString(payOrder));
375 375 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
... ... @@ -393,23 +393,19 @@ public class TradeOrderServiceImpl implements TradeOrderService {
393 393 TradeOrderDO updateOrderObj = new TradeOrderDO();
394 394 // 判断发货类型
395 395 // 2.1 快递发货
396   - if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
  396 + if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.EXPRESS.getMode())) {
397 397 // 校验快递公司
398   - // TODO @puhui999:getDeliveryExpress 直接封装一个校验的,会不会好点;因为还有开启关闭啥的;
399   - DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
400   - if (deliveryExpress == null) {
401   - throw exception(EXPRESS_NOT_EXISTS);
402   - }
  398 + validateDeliveryExpress(deliveryReqVO);
403 399 updateOrderObj.setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo());
404 400 }
405 401 // 2.2 用户自提
406   - if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.PICK_UP.getMode())) {
  402 + if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.PICK_UP.getMode())) {
407 403 // TODO 校验自提门店是否存在
408 404 // 重置一下确保快递公司和快递单号为空
409 405 updateOrderObj.setLogisticsId(null).setLogisticsNo("");
410 406 }
411 407 // 2.3 TODO 芋艿:如果无需发货,需要怎么存储?回复:需要把 deliverType 设置为 DeliveryTypeEnum.NULL
412   - if (ObjectUtil.equal(deliveryReqVO.getType(), DeliveryTypeEnum.NULL.getMode())) {
  408 + if (equal(deliveryReqVO.getType(), DeliveryTypeEnum.NULL.getMode())) {
413 409 // TODO 情况一:正常走发货逻辑和用户自提有点像 不同点:不需要自提门店只需要用户确认收货
414 410 // TODO 情况二:用户下单付款后直接确认收货或等待用户确认收货
415 411 // 重置一下确保快递公司和快递单号为空
... ... @@ -426,13 +422,23 @@ public class TradeOrderServiceImpl implements TradeOrderService {
426 422 // TODO 芋艿:发送订单变化的消息
427 423  
428 424 // 发送站内信
429   - tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqDTO().setOrderId(order.getId())
  425 + tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO().setOrderId(order.getId())
430 426 .setUserId(userId).setMessage(TradeOrderDeliveryStatusEnum.DELIVERED.getName()));
431 427  
432 428 // TODO 芋艿:OrderLog
433 429 // TODO 设计:lili:是不是发货后,才支持售后?
434 430 }
435 431  
  432 + private void validateDeliveryExpress(TradeOrderDeliveryReqVO deliveryReqVO) {
  433 + DeliveryExpressDO deliveryExpress = deliveryExpressService.getDeliveryExpress(deliveryReqVO.getLogisticsId());
  434 + if (deliveryExpress == null) {
  435 + throw exception(EXPRESS_NOT_EXISTS);
  436 + }
  437 + if (deliveryExpress.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
  438 + throw exception(EXPRESS_STATUS_NOT_ENABLE);
  439 + }
  440 + }
  441 +
436 442 /**
437 443 * 校验交易订单满足被发货的条件
438 444 *
... ... @@ -449,18 +455,17 @@ public class TradeOrderServiceImpl implements TradeOrderService {
449 455 }
450 456 // 校验订单是否是待发货状态
451 457 if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())
452   - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) {
  458 + || notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) {
453 459 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
454 460 }
455 461 // 校验订单是否退款
456   - if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
  462 + if (notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
457 463 throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE);
458 464 }
459 465 // 订单类型:拼团
460   - if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
  466 + if (equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
461 467 // 校验订单拼团是否成功
462   - // TODO 用户 ID 使用当前登录用户的还是订单保存的?
463   - if (combinationRecordApi.isCombinationRecordSuccess(order.getUserId(), order.getId())) {
  468 + if (combinationRecordApi.isRecordSuccess(order.getUserId(), order.getId())) {
464 469 throw exception(ORDER_DELIVERY_FAIL_COMBINATION_RECORD_STATUS_NOT_SUCCESS);
465 470 }
466 471 }
... ... @@ -510,7 +515,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
510 515 }
511 516 // 校验订单是否是待收货状态
512 517 if (!TradeOrderStatusEnum.isDelivered(order.getStatus())
513   - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus())) {
  518 + || notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus())) {
514 519 throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
515 520 }
516 521 return order;
... ... @@ -520,7 +525,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
520 525 public TradeOrderDO getOrder(Long userId, Long id) {
521 526 TradeOrderDO order = tradeOrderMapper.selectById(id);
522 527 if (order != null
523   - && ObjectUtil.notEqual(order.getUserId(), userId)) {
  528 + && notEqual(order.getUserId(), userId)) {
524 529 return null;
525 530 }
526 531 return order;
... ... @@ -564,7 +569,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
564 569 public TradeOrderItemDO getOrderItem(Long userId, Long itemId) {
565 570 TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(itemId);
566 571 if (orderItem != null
567   - && ObjectUtil.notEqual(orderItem.getUserId(), userId)) {
  572 + && notEqual(orderItem.getUserId(), userId)) {
568 573 return null;
569 574 }
570 575 return orderItem;
... ... @@ -644,10 +649,10 @@ public class TradeOrderServiceImpl implements TradeOrderService {
644 649 if (order == null) {
645 650 throw exception(ORDER_NOT_FOUND);
646 651 }
647   - if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
  652 + if (notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
648 653 throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);
649 654 }
650   - if (ObjectUtil.notEqual(order.getCommentStatus(), Boolean.FALSE)) {
  655 + if (notEqual(order.getCommentStatus(), Boolean.FALSE)) {
651 656 throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
652 657 }
653 658  
... ... @@ -657,7 +662,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
657 662 // 更新订单项评价状态
658 663 tradeOrderItemMapper.updateById(new TradeOrderItemDO().setId(orderItem.getId()).setCommentStatus(Boolean.TRUE));
659 664 List<TradeOrderItemDO> orderItems = getOrderItemListByOrderId(CollUtil.newArrayList(order.getId()));
660   - if (!CollectionUtils.isAny(orderItems, item -> ObjectUtil.equal(item.getCommentStatus(), Boolean.FALSE))) {
  665 + if (!anyMatch(orderItems, item -> equal(item.getCommentStatus(), Boolean.FALSE))) {
661 666 // 对于 order 来说,就是评论完,把 order 更新完合理的 status 等字段。
662 667 tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId()).setCommentStatus(Boolean.TRUE));
663 668 }
... ...