Commit b84f7825c51da85f292d6e3662e69f6dd27ad387

Authored by YunaiV
1 parent e2ed0b7a

review 拼团、秒杀活动的实现

Showing 46 changed files with 197 additions and 147 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
@@ -70,6 +70,7 @@ public class LocalDateTimeUtils { @@ -70,6 +70,7 @@ public class LocalDateTimeUtils {
70 * @param endTime2 校验所需的结束时间 70 * @param endTime2 校验所需的结束时间
71 * @return 是否重叠 71 * @return 是否重叠
72 */ 72 */
  73 + // TODO @puhui999:LocalDateTimeUtil.isOverlap() 是不是可以满足呀?
73 public static boolean checkTimeOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) { 74 public static boolean checkTimeOverlap(LocalTime startTime1, LocalTime endTime1, LocalTime startTime2, LocalTime endTime2) {
74 // 判断时间是否重叠 75 // 判断时间是否重叠
75 // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 [] 76 // 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
@@ -45,10 +45,8 @@ public interface ErrorCodeConstants { @@ -45,10 +45,8 @@ public interface ErrorCodeConstants {
45 ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足"); 45 ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
46 46
47 // ========== 商品 评价 1008007000 ========== 47 // ========== 商品 评价 1008007000 ==========
48 - ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品 评价 不存在");  
49 - ErrorCode ORDER_SKU_COMMENT_EXISTS = new ErrorCode(1008007001, "订单 商品评价 已存在");  
50 - ErrorCode COMMENT_ERROR_OPT = new ErrorCode(1008007002, "商品评价非法操作");  
51 - ErrorCode COMMENT_ADDITIONAL_EXISTS = new ErrorCode(1008007003, "商品追加评价已存在"); 48 + ErrorCode COMMENT_NOT_EXISTS = new ErrorCode(1008007000, "商品评价不存在");
  49 + ErrorCode COMMENT_ORDER_EXISTS = new ErrorCode(1008007001, "订单的商品评价已存在");
52 50
53 // ========== 商品 收藏 1008008000 ========== 51 // ========== 商品 收藏 1008008000 ==========
54 ErrorCode FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏"); 52 ErrorCode FAVORITE_EXISTS = new ErrorCode(1008008000, "该商品已经被收藏");
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuExportReqVO.java
@@ -10,7 +10,7 @@ import java.time.LocalDateTime; @@ -10,7 +10,7 @@ import java.time.LocalDateTime;
10 10
11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
12 12
13 -@Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的") 13 +@Schema(description = "管理后台 - 商品 SPU 导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
14 @Data 14 @Data
15 @NoArgsConstructor 15 @NoArgsConstructor
16 @AllArgsConstructor 16 @AllArgsConstructor
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/comment/AppProductCommentController.java
@@ -51,14 +51,16 @@ public class AppProductCommentController { @@ -51,14 +51,16 @@ public class AppProductCommentController {
51 @Parameter(name = "spuId", description = "商品 SPU 编号", required = true, example = "1024"), 51 @Parameter(name = "spuId", description = "商品 SPU 编号", required = true, example = "1024"),
52 @Parameter(name = "count", description = "数量", required = true, example = "10") 52 @Parameter(name = "count", description = "数量", required = true, example = "10")
53 }) 53 })
54 - public CommonResult<List<AppProductCommentRespVO>> getCommentList(@RequestParam("spuId") Long spuId,  
55 - @RequestParam(value = "count", defaultValue = "10") Integer count) { 54 + public CommonResult<List<AppProductCommentRespVO>> getCommentList(
  55 + @RequestParam("spuId") Long spuId,
  56 + @RequestParam(value = "count", defaultValue = "10") Integer count) {
56 return success(productCommentService.getCommentList(spuId, count)); 57 return success(productCommentService.getCommentList(spuId, count));
57 } 58 }
58 59
59 @GetMapping("/page") 60 @GetMapping("/page")
60 @Operation(summary = "获得商品评价分页") 61 @Operation(summary = "获得商品评价分页")
61 public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) { 62 public CommonResult<PageResult<AppProductCommentRespVO>> getCommentPage(@Valid AppCommentPageReqVO pageVO) {
  63 + // TODO @puhui999:写到 convert 里,可以更简洁哈。
62 PageResult<ProductCommentDO> commentDOPage = productCommentService.getCommentPage(pageVO, Boolean.TRUE); 64 PageResult<ProductCommentDO> commentDOPage = productCommentService.getCommentPage(pageVO, Boolean.TRUE);
63 Set<Long> skuIds = CollectionUtils.convertSet(commentDOPage.getList(), ProductCommentDO::getSkuId); 65 Set<Long> skuIds = CollectionUtils.convertSet(commentDOPage.getList(), ProductCommentDO::getSkuId);
64 List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds); 66 List<ProductSkuDO> skuList = productSkuService.getSkuList(skuIds);
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.convert.comment; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.convert.comment;
2 2
3 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
5 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 6 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
6 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; 7 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
7 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; 8 import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO;
@@ -34,37 +35,33 @@ public interface ProductCommentConvert { @@ -34,37 +35,33 @@ public interface ProductCommentConvert {
34 35
35 ProductCommentRespVO convert(ProductCommentDO bean); 36 ProductCommentRespVO convert(ProductCommentDO bean);
36 37
  38 + @Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")
  39 + AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);
37 @Named("calculateOverallScore") 40 @Named("calculateOverallScore")
38 default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) { 41 default double calculateOverallScore(long goodCount, long mediocreCount, long negativeCount) {
39 return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount); 42 return (goodCount * 5 + mediocreCount * 3 + negativeCount) / (double) (goodCount + mediocreCount + negativeCount);
40 } 43 }
41 -  
42 - @Mapping(target = "scores", expression = "java(calculateOverallScore(goodCount, mediocreCount, negativeCount))")  
43 - AppCommentStatisticsRespVO convert(Long goodCount, Long mediocreCount, Long negativeCount);  
44 - 44 +
45 List<ProductCommentRespVO> convertList(List<ProductCommentDO> list); 45 List<ProductCommentRespVO> convertList(List<ProductCommentDO> list);
46 46
47 - List<AppProductPropertyValueDetailRespVO> convertList01(List<ProductSkuDO.Property> properties);  
48 -  
49 PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page); 47 PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> page);
50 48
51 PageResult<AppProductCommentRespVO> convertPage01(PageResult<ProductCommentDO> pageResult); 49 PageResult<AppProductCommentRespVO> convertPage01(PageResult<ProductCommentDO> pageResult);
52 50
53 - default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult, Map<Long, ProductSkuDO> skuDOMap) { 51 + default PageResult<AppProductCommentRespVO> convertPage02(PageResult<ProductCommentDO> pageResult,
  52 + Map<Long, ProductSkuDO> skuMap) {
54 PageResult<AppProductCommentRespVO> page = convertPage01(pageResult); 53 PageResult<AppProductCommentRespVO> page = convertPage01(pageResult);
55 page.getList().forEach(item -> { 54 page.getList().forEach(item -> {
56 // 判断用户是否选择匿名 55 // 判断用户是否选择匿名
57 if (ObjectUtil.equal(item.getAnonymous(), true)) { 56 if (ObjectUtil.equal(item.getAnonymous(), true)) {
58 item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS); 57 item.setUserNickname(ProductCommentDO.NICKNAME_ANONYMOUS);
59 } 58 }
60 - ProductSkuDO productSkuDO = skuDOMap.get(item.getSkuId());  
61 - if (productSkuDO != null) {  
62 - List<AppProductPropertyValueDetailRespVO> skuProperties = ProductCommentConvert.INSTANCE.convertList01(productSkuDO.getProperties());  
63 - item.setSkuProperties(skuProperties);  
64 - } 59 + MapUtils.findAndThen(skuMap, item.getSkuId(),
  60 + sku -> item.setSkuProperties(convertList01(sku.getProperties())));
65 }); 61 });
66 return page; 62 return page;
67 } 63 }
  64 + List<AppProductPropertyValueDetailRespVO> convertList01(List<ProductSkuDO.Property> properties);
68 65
69 /** 66 /**
70 * 计算综合评分 67 * 计算综合评分
@@ -83,14 +80,19 @@ public interface ProductCommentConvert { @@ -83,14 +80,19 @@ public interface ProductCommentConvert {
83 80
84 ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO); 81 ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO);
85 82
86 - @Mapping(target = "scores", expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") 83 + @Mapping(target = "scores",
  84 + expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))")
87 default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, MemberUserRespDTO user) { 85 default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, MemberUserRespDTO user) {
88 ProductCommentDO commentDO = convert(createReqDTO); 86 ProductCommentDO commentDO = convert(createReqDTO);
89 - commentDO.setUserId(user.getId());  
90 - commentDO.setUserNickname(user.getNickname());  
91 - commentDO.setUserAvatar(user.getAvatar());  
92 - commentDO.setSpuId(spuDO.getId());  
93 - commentDO.setSpuName(spuDO.getName()); 87 + if (user != null) {
  88 + commentDO.setUserId(user.getId());
  89 + commentDO.setUserNickname(user.getNickname());
  90 + commentDO.setUserAvatar(user.getAvatar());
  91 + }
  92 + if (spuDO != null) {
  93 + commentDO.setSpuId(spuDO.getId());
  94 + commentDO.setSpuName(spuDO.getName());
  95 + }
94 return commentDO; 96 return commentDO;
95 } 97 }
96 98
@@ -98,7 +100,8 @@ public interface ProductCommentConvert { @@ -98,7 +100,8 @@ public interface ProductCommentConvert {
98 @Mapping(target = "orderId", constant = "0L") 100 @Mapping(target = "orderId", constant = "0L")
99 @Mapping(target = "orderItemId", constant = "0L") 101 @Mapping(target = "orderItemId", constant = "0L")
100 @Mapping(target = "anonymous", expression = "java(Boolean.FALSE)") 102 @Mapping(target = "anonymous", expression = "java(Boolean.FALSE)")
101 - @Mapping(target = "scores", expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))") 103 + @Mapping(target = "scores",
  104 + expression = "java(convertScores(createReq.getDescriptionScores(), createReq.getBenefitScores()))")
102 ProductCommentDO convert(ProductCommentCreateReqVO createReq); 105 ProductCommentDO convert(ProductCommentCreateReqVO createReq);
103 106
104 List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list); 107 List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list);
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
1 package cn.iocoder.yudao.module.product.convert.spu; 1 package cn.iocoder.yudao.module.product.convert.spu;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.dict.core.util.DictFrameworkUtils; 4 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
6 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; 5 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
7 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*; 6 import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
@@ -22,6 +21,7 @@ import java.util.List; @@ -22,6 +21,7 @@ import java.util.List;
22 import java.util.Map; 21 import java.util.Map;
23 22
24 import static cn.hutool.core.util.ObjectUtil.defaultIfNull; 23 import static cn.hutool.core.util.ObjectUtil.defaultIfNull;
  24 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
25 25
26 /** 26 /**
27 * 商品 SPU Convert 27 * 商品 SPU Convert
@@ -110,8 +110,9 @@ public interface ProductSpuConvert { @@ -110,8 +110,9 @@ public interface ProductSpuConvert {
110 } 110 }
111 111
112 default List<ProductSpuDetailRespVO> convertForSpuDetailRespListVO(List<ProductSpuDO> spus, List<ProductSkuDO> skus) { 112 default List<ProductSpuDetailRespVO> convertForSpuDetailRespListVO(List<ProductSpuDO> spus, List<ProductSkuDO> skus) {
113 - ArrayList<ProductSpuDetailRespVO> vos = new ArrayList<>();  
114 - Map<Long, List<ProductSkuDO>> skuMultiMap = CollectionUtils.convertMultiMap(skus, ProductSkuDO::getSpuId); 113 + List<ProductSpuDetailRespVO> vos = new ArrayList<>(spus.size());
  114 + Map<Long, List<ProductSkuDO>> skuMultiMap = convertMultiMap(skus, ProductSkuDO::getSpuId);
  115 + // TODO @puhui999:可以直接使用 CollUtils.convertList
115 spus.forEach(spu -> { 116 spus.forEach(spu -> {
116 ProductSpuDetailRespVO detailRespVO = convert03(spu); 117 ProductSpuDetailRespVO detailRespVO = convert03(spu);
117 detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skuMultiMap.get(spu.getId()))); 118 detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skuMultiMap.get(spu.getId())));
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/comment/ProductCommentMapper.java
@@ -26,6 +26,7 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; { @@ -26,6 +26,7 @@ public interface ProductCommentMapper extends BaseMapperX&lt;ProductCommentDO&gt; {
26 } 26 }
27 27
28 static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) { 28 static void appendTabQuery(LambdaQueryWrapperX<ProductCommentDO> queryWrapper, Integer type) {
  29 + // TODO @puhui999:是不是不用 apply 拉?直接用 mybatis 的方法就好啦
29 // 构建好评查询语句:好评计算 总评 >= 4 30 // 构建好评查询语句:好评计算 总评 >= 4
30 if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) { 31 if (ObjectUtil.equal(type, AppCommentPageReqVO.GOOD_COMMENT)) {
31 queryWrapper.apply("scores >= 4"); 32 queryWrapper.apply("scores >= 4");
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImpl.java
@@ -112,7 +112,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { @@ -112,7 +112,7 @@ public class ProductCommentServiceImpl implements ProductCommentService {
112 // 判断当前订单的当前商品用户是否评价过 112 // 判断当前订单的当前商品用户是否评价过
113 ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, skuId); 113 ProductCommentDO exist = productCommentMapper.selectByUserIdAndOrderItemIdAndSpuId(userId, orderItemId, skuId);
114 if (null != exist) { 114 if (null != exist) {
115 - throw exception(ORDER_SKU_COMMENT_EXISTS); 115 + throw exception(COMMENT_ORDER_EXISTS);
116 } 116 }
117 } 117 }
118 118
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApi.java
@@ -4,6 +4,8 @@ import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRe @@ -4,6 +4,8 @@ import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRe
4 4
5 import javax.validation.Valid; 5 import javax.validation.Valid;
6 6
  7 +// TODO @puhui999:CombinationRecordApi 分成活动、记录哈
  8 +// TODO @芋艿:后面也再撸撸这几个接口
7 /** 9 /**
8 * 拼团活动 API 接口 10 * 拼团活动 API 接口
9 * 11 *
@@ -26,7 +28,6 @@ public interface CombinationApi { @@ -26,7 +28,6 @@ public interface CombinationApi {
26 */ 28 */
27 boolean validateRecordStatusIsSuccess(Long userId, Long orderId); 29 boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
28 30
29 -  
30 /** 31 /**
31 * 更新开团记录状态 32 * 更新开团记录状态
32 * 33 *
@@ -42,7 +43,6 @@ public interface CombinationApi { @@ -42,7 +43,6 @@ public interface CombinationApi {
42 * @param userId 用户编号 43 * @param userId 用户编号
43 * @param orderId 订单编号 44 * @param orderId 订单编号
44 * @param status 状态值 45 * @param status 状态值
45 - * @return  
46 */ 46 */
47 void updateRecordStatusAndStartTime(Long userId, Long orderId, Integer status); 47 void updateRecordStatusAndStartTime(Long userId, Long orderId, Integer status);
48 48
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordReqDTO.java
@@ -5,6 +5,7 @@ import lombok.Data; @@ -5,6 +5,7 @@ import lombok.Data;
5 import javax.validation.constraints.NotEmpty; 5 import javax.validation.constraints.NotEmpty;
6 import javax.validation.constraints.NotNull; 6 import javax.validation.constraints.NotNull;
7 7
  8 +// TODO @puhui999:CombinationRecordCreateReqDTO,这样更容易知道是创建噢
8 /** 9 /**
9 * 拼团记录 Request DTO 10 * 拼团记录 Request DTO
10 * 11 *
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -42,8 +42,7 @@ public interface ErrorCodeConstants { @@ -42,8 +42,7 @@ public interface ErrorCodeConstants {
42 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013006004, "满减送活动已关闭,不能重复关闭"); 42 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013006004, "满减送活动已关闭,不能重复关闭");
43 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013006005, "满减送活动已结束,不能关闭"); 43 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013006005, "满减送活动已结束,不能关闭");
44 44
45 - // ========== Price 相关 1013007000 ============  
46 - ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1013007000, "支付价格计算异常,原因:价格小于等于 0"); 45 + // ========== TODO 空着 1013007000 ============
47 46
48 // ========== 秒杀活动 1013008000 ========== 47 // ========== 秒杀活动 1013008000 ==========
49 ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1013008000, "秒杀活动不存在"); 48 ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1013008000, "秒杀活动不存在");
@@ -66,4 +65,5 @@ public interface ErrorCodeConstants { @@ -66,4 +65,5 @@ public interface ErrorCodeConstants {
66 ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013010002, "拼团活动已关闭不能修改"); 65 ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013010002, "拼团活动已关闭不能修改");
67 ErrorCode COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013010003, "拼团活动未关闭或未结束,不能删除"); 66 ErrorCode COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013010003, "拼团活动未关闭或未结束,不能删除");
68 ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1013010004, "拼团不存在"); 67 ErrorCode COMBINATION_RECORD_NOT_EXISTS = new ErrorCode(1013010004, "拼团不存在");
  68 +
69 } 69 }
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/combination/CombinationRecordStatusEnum.java
@@ -14,8 +14,9 @@ import java.util.Arrays; @@ -14,8 +14,9 @@ import java.util.Arrays;
14 @AllArgsConstructor 14 @AllArgsConstructor
15 @Getter 15 @Getter
16 public enum CombinationRecordStatusEnum implements IntArrayValuable { 16 public enum CombinationRecordStatusEnum implements IntArrayValuable {
17 - NOT_PAY(0, "未付款"),  
18 - ONGOING(1, "进行中"), 17 +
  18 + WAITING(0, "未付款"),
  19 + IN_PROGRESS(1, "进行中"),
19 SUCCESS(2, "拼团成功"), 20 SUCCESS(2, "拼团成功"),
20 FAILED(3, "拼团失败"); 21 FAILED(3, "拼团失败");
21 22
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java
@@ -14,6 +14,7 @@ import java.time.LocalDateTime; @@ -14,6 +14,7 @@ import java.time.LocalDateTime;
14 */ 14 */
15 @Service 15 @Service
16 public class CombinationApiImpl implements CombinationApi { 16 public class CombinationApiImpl implements CombinationApi {
  17 +
17 @Resource 18 @Resource
18 private CombinationActivityService activityService; 19 private CombinationActivityService activityService;
19 20
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.combination; 1 package cn.iocoder.yudao.module.promotion.controller.admin.combination;
2 2
3 -import cn.hutool.core.collection.CollectionUtil;  
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 5 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -28,6 +27,7 @@ import java.util.Collection; @@ -28,6 +27,7 @@ import java.util.Collection;
28 import java.util.List; 27 import java.util.List;
29 import java.util.Set; 28 import java.util.Set;
30 29
  30 +import static cn.hutool.core.collection.CollectionUtil.newArrayList;
31 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 31 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
32 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 32 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
33 33
@@ -71,9 +71,9 @@ public class CombinationActivityController { @@ -71,9 +71,9 @@ public class CombinationActivityController {
71 @Parameter(name = "id", description = "编号", required = true, example = "1024") 71 @Parameter(name = "id", description = "编号", required = true, example = "1024")
72 @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')") 72 @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
73 public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) { 73 public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) {
74 - CombinationActivityDO combinationActivity = combinationActivityService.getCombinationActivity(id);  
75 - List<CombinationProductDO> productDOs = combinationActivityService.getProductsByActivityIds(CollectionUtil.newArrayList(id));  
76 - return success(CombinationActivityConvert.INSTANCE.convert(combinationActivity, productDOs)); 74 + CombinationActivityDO activity = combinationActivityService.getCombinationActivity(id);
  75 + List<CombinationProductDO> products = combinationActivityService.getProductsByActivityIds(newArrayList(id));
  76 + return success(CombinationActivityConvert.INSTANCE.convert(activity, products));
77 } 77 }
78 78
79 @GetMapping("/list") 79 @GetMapping("/list")
@@ -88,13 +88,15 @@ public class CombinationActivityController { @@ -88,13 +88,15 @@ public class CombinationActivityController {
88 @GetMapping("/page") 88 @GetMapping("/page")
89 @Operation(summary = "获得拼团活动分页") 89 @Operation(summary = "获得拼团活动分页")
90 @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')") 90 @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
91 - public CommonResult<PageResult<CombinationActivityRespVO>> getCombinationActivityPage(@Valid CombinationActivityPageReqVO pageVO) { 91 + public CommonResult<PageResult<CombinationActivityRespVO>> getCombinationActivityPage(
  92 + @Valid CombinationActivityPageReqVO pageVO) {
92 PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO); 93 PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO);
  94 + // TODO @puhui999:可以不一定 aIds,直接批量查询结果出来;下面也是类似;
93 Set<Long> aIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getId); 95 Set<Long> aIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getId);
94 - List<CombinationProductDO> productDOs = combinationActivityService.getProductsByActivityIds(aIds); 96 + List<CombinationProductDO> products = combinationActivityService.getProductsByActivityIds(aIds);
95 Set<Long> spuIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getSpuId); 97 Set<Long> spuIds = CollectionUtils.convertSet(pageResult.getList(), CombinationActivityDO::getSpuId);
96 - List<ProductSpuRespDTO> spuList = spuApi.getSpuList(spuIds);  
97 - return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult, productDOs, spuList)); 98 + List<ProductSpuRespDTO> spus = spuApi.getSpuList(spuIds);
  99 + return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult, products, spus));
98 } 100 }
99 101
100 @GetMapping("/export-excel") 102 @GetMapping("/export-excel")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
@@ -20,7 +20,7 @@ public class CombinationActivityBaseVO { @@ -20,7 +20,7 @@ public class CombinationActivityBaseVO {
20 @NotNull(message = "拼团名称不能为空") 20 @NotNull(message = "拼团名称不能为空")
21 private String name; 21 private String name;
22 22
23 - @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "[1,2,3]") 23 + @Schema(description = "商品 SPU 编号,关联 ProductSpuDO 的 id", example = "[1,2,3]")
24 @NotNull(message = "拼团商品不能为空") 24 @NotNull(message = "拼团商品不能为空")
25 private Long spuId; 25 private Long spuId;
26 26
@@ -32,6 +32,7 @@ public class CombinationActivityBaseVO { @@ -32,6 +32,7 @@ public class CombinationActivityBaseVO {
32 @NotNull(message = "单次限购数量不能为空") 32 @NotNull(message = "单次限购数量不能为空")
33 private Integer singleLimitCount; 33 private Integer singleLimitCount;
34 34
  35 + // TODO @puhui999:是不是弄成 2 个字段会好点哈。开始、结束
35 @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]") 36 @Schema(description = "活动时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")
36 @NotNull(message = "活动时间不能为空") 37 @NotNull(message = "活动时间不能为空")
37 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 38 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@@ -42,7 +43,7 @@ public class CombinationActivityBaseVO { @@ -42,7 +43,7 @@ public class CombinationActivityBaseVO {
42 private Integer userSize; 43 private Integer userSize;
43 44
44 @Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED) 45 @Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED)
45 - @NotNull(message = "限制时长(小时)不能为空") 46 + @NotNull(message = "限制时长不能为空")
46 private Integer limitDuration; 47 private Integer limitDuration;
47 48
48 } 49 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExcelVO.java
@@ -7,7 +7,7 @@ import lombok.Data; @@ -7,7 +7,7 @@ import lombok.Data;
7 7
8 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
9 9
10 - 10 +// TODO @puhui999:如无必要,导出都可以删除哈
11 /** 11 /**
12 * 拼团活动 Excel VO 12 * 拼团活动 Excel VO
13 * 13 *
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityExportReqVO.java
@@ -8,6 +8,7 @@ import java.time.LocalDateTime; @@ -8,6 +8,7 @@ import java.time.LocalDateTime;
8 8
9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10
  11 +// TODO @puhui999:如无必要,导出都可以删除哈
11 @Schema(description = "管理后台 - 拼团活动 Excel 导出 Request VO,参数和 CombinationActivityPageReqVO 是一致的") 12 @Schema(description = "管理后台 - 拼团活动 Excel 导出 Request VO,参数和 CombinationActivityPageReqVO 是一致的")
12 @Data 13 @Data
13 public class CombinationActivityExportReqVO { 14 public class CombinationActivityExportReqVO {
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java
@@ -45,7 +45,7 @@ public class CombinationActivityRespVO extends CombinationActivityBaseVO { @@ -45,7 +45,7 @@ public class CombinationActivityRespVO extends CombinationActivityBaseVO {
45 @NotNull(message = "虚拟成团不能为空") 45 @NotNull(message = "虚拟成团不能为空")
46 private Integer virtualGroup; 46 private Integer virtualGroup;
47 47
48 - @Schema(description = "活动状态:0开启 1关闭", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 48 + @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
49 @NotNull(message = "活动状态不能为空") 49 @NotNull(message = "活动状态不能为空")
50 private Integer status; 50 private Integer status;
51 51
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExcelVO.java
@@ -5,6 +5,7 @@ import lombok.Data; @@ -5,6 +5,7 @@ import lombok.Data;
5 5
6 import java.time.LocalDateTime; 6 import java.time.LocalDateTime;
7 7
  8 +// TODO @puhui999:可以考虑删除 excel 导出哈
8 /** 9 /**
9 * 拼团商品 Excel VO 10 * 拼团商品 Excel VO
10 * 11 *
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductExportReqVO.java
@@ -8,6 +8,7 @@ import java.time.LocalDateTime; @@ -8,6 +8,7 @@ import java.time.LocalDateTime;
8 8
9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 9 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
10 10
  11 +// TODO @puhui999:可以考虑删除 excel 导出哈
11 @Schema(description = "管理后台 - 拼团商品 Excel 导出 Request VO,参数和 CombinationProductPageReqVO 是一致的") 12 @Schema(description = "管理后台 - 拼团商品 Excel 导出 Request VO,参数和 CombinationProductPageReqVO 是一致的")
12 @Data 13 @Data
13 public class CombinationProductExportReqVO { 14 public class CombinationProductExportReqVO {
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.convert.combination; @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.convert.combination;
2 2
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
6 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; 5 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
7 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO; 6 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordReqDTO;
8 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
@@ -26,6 +25,8 @@ import java.util.ArrayList; @@ -26,6 +25,8 @@ import java.util.ArrayList;
26 import java.util.List; 25 import java.util.List;
27 import java.util.Map; 26 import java.util.Map;
28 27
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  29 +
29 /** 30 /**
30 * 拼团活动 Convert 31 * 拼团活动 Convert
31 * 32 *
@@ -74,13 +75,17 @@ public interface CombinationActivityConvert { @@ -74,13 +75,17 @@ public interface CombinationActivityConvert {
74 75
75 PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page); 76 PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page);
76 77
77 - default PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page, List<CombinationProductDO> productDOList, List<ProductSpuRespDTO> spuList) {  
78 - Map<Long, ProductSpuRespDTO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuRespDTO::getId, c -> c); 78 + default PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page,
  79 + List<CombinationProductDO> productList,
  80 + List<ProductSpuRespDTO> spuList) {
  81 + // TODO @puhui999:c -> c 可以去掉哈
  82 + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId, c -> c);
79 PageResult<CombinationActivityRespVO> pageResult = convertPage(page); 83 PageResult<CombinationActivityRespVO> pageResult = convertPage(page);
80 pageResult.getList().forEach(item -> { 84 pageResult.getList().forEach(item -> {
  85 + // TODO @puhui999:最好 MapUtils.findAndThen,万一没找到呢,啊哈哈。
81 item.setSpuName(spuMap.get(item.getSpuId()).getName()); 86 item.setSpuName(spuMap.get(item.getSpuId()).getName());
82 item.setPicUrl(spuMap.get(item.getSpuId()).getPicUrl()); 87 item.setPicUrl(spuMap.get(item.getSpuId()).getPicUrl());
83 - item.setProducts(convertList2(productDOList)); 88 + item.setProducts(convertList2(productList));
84 }); 89 });
85 return pageResult; 90 return pageResult;
86 } 91 }
@@ -111,12 +116,17 @@ public interface CombinationActivityConvert { @@ -111,12 +116,17 @@ public interface CombinationActivityConvert {
111 return list; 116 return list;
112 } 117 }
113 118
114 - default List<CombinationProductDO> convertList1(CombinationActivityDO activityDO, List<CombinationProductUpdateReqVO> vos, List<CombinationProductDO> productDOs) {  
115 - Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, CombinationProductDO::getSkuId, CombinationProductDO::getId); 119 + // TODO @puhui999:这个方法的参数,调整成 productDOs、vos、activityDO;因为 productDOs 是主角;
  120 + // 然后,这个方法,感觉不是为了 convert,而是为了补全;
  121 + default List<CombinationProductDO> convertList1(CombinationActivityDO activityDO,
  122 + List<CombinationProductUpdateReqVO> vos,
  123 + List<CombinationProductDO> productDOs) {
  124 + Map<Long, Long> longMap = convertMap(productDOs, CombinationProductDO::getSkuId, CombinationProductDO::getId);
116 List<CombinationProductDO> list = new ArrayList<>(); 125 List<CombinationProductDO> list = new ArrayList<>();
117 vos.forEach(sku -> { 126 vos.forEach(sku -> {
118 CombinationProductDO productDO = convert(activityDO, sku); 127 CombinationProductDO productDO = convert(activityDO, sku);
119 productDO.setId(longMap.get(sku.getSkuId())); 128 productDO.setId(longMap.get(sku.getSkuId()));
  129 + // TODO @puhui999:是是不是用 activityDO 的状态;
120 productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus()); 130 productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
121 list.add(productDO); 131 list.add(productDO);
122 }); 132 });
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
@@ -84,6 +84,7 @@ public interface SeckillActivityConvert { @@ -84,6 +84,7 @@ public interface SeckillActivityConvert {
84 return list; 84 return list;
85 } 85 }
86 86
  87 + // TODO @puhui999:同拼团那个 convert 想通的情况哈。
87 default List<SeckillProductDO> convertList1(SeckillActivityDO activityDO, List<SeckillProductUpdateReqVO> vos, List<SeckillProductDO> productDOs) { 88 default List<SeckillProductDO> convertList1(SeckillActivityDO activityDO, List<SeckillProductUpdateReqVO> vos, List<SeckillProductDO> productDOs) {
88 Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, SeckillProductDO::getSkuId, SeckillProductDO::getId); 89 Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, SeckillProductDO::getSkuId, SeckillProductDO::getId);
89 List<SeckillProductDO> list = new ArrayList<>(); 90 List<SeckillProductDO> list = new ArrayList<>();
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationActivityDO.java
@@ -9,6 +9,7 @@ import lombok.*; @@ -9,6 +9,7 @@ import lombok.*;
9 9
10 import java.time.LocalDateTime; 10 import java.time.LocalDateTime;
11 11
  12 +// TODO @puhui999:是不是应该在 combination 哈?
12 /** 13 /**
13 * 拼团活动 DO 14 * 拼团活动 DO
14 * 15 *
@@ -34,7 +35,9 @@ public class CombinationActivityDO extends BaseDO { @@ -34,7 +35,9 @@ public class CombinationActivityDO extends BaseDO {
34 */ 35 */
35 private String name; 36 private String name;
36 /** 37 /**
37 - * 商品 SPU 编号关联 ProductSpuDO 的 id 38 + * 商品 SPU 编号
  39 + *
  40 + * 关联 ProductSpuDO 的 id
38 */ 41 */
39 private Long spuId; 42 private Long spuId;
40 /** 43 /**
@@ -75,7 +78,7 @@ public class CombinationActivityDO extends BaseDO { @@ -75,7 +78,7 @@ public class CombinationActivityDO extends BaseDO {
75 private Integer virtualGroup; 78 private Integer virtualGroup;
76 /** 79 /**
77 * 活动状态:0开启 1关闭 80 * 活动状态:0开启 1关闭
78 - * <p> 81 + *
79 * 枚举 {@link CommonStatusEnum} 82 * 枚举 {@link CommonStatusEnum}
80 */ 83 */
81 private Integer status; 84 private Integer status;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationRecordDO.java
@@ -31,11 +31,11 @@ public class CombinationRecordDO extends BaseDO { @@ -31,11 +31,11 @@ public class CombinationRecordDO extends BaseDO {
31 */ 31 */
32 private Long activityId; 32 private Long activityId;
33 /** 33 /**
34 - * spu 编号 34 + * SPU 编号
35 */ 35 */
36 private Long spuId; 36 private Long spuId;
37 /** 37 /**
38 - * sku 编号 38 + * SKU 编号
39 */ 39 */
40 private Long skuId; 40 private Long skuId;
41 /** 41 /**
@@ -48,7 +48,7 @@ public class CombinationRecordDO extends BaseDO { @@ -48,7 +48,7 @@ public class CombinationRecordDO extends BaseDO {
48 private Long orderId; 48 private Long orderId;
49 /** 49 /**
50 * 团长编号 50 * 团长编号
51 - * <p> 51 + *
52 * 关联 {@link CombinationRecordDO#getUserId()} 52 * 关联 {@link CombinationRecordDO#getUserId()}
53 */ 53 */
54 private Long headId; 54 private Long headId;
@@ -84,7 +84,8 @@ public class CombinationRecordDO extends BaseDO { @@ -84,7 +84,8 @@ public class CombinationRecordDO extends BaseDO {
84 private Boolean virtualGroup; 84 private Boolean virtualGroup;
85 /** 85 /**
86 * 过期时间,单位:小时 86 * 过期时间,单位:小时
87 - * 关联关联 {@link CombinationActivityDO#getLimitDuration()} 87 + *
  88 + * 关联 {@link CombinationActivityDO#getLimitDuration()}
88 */ 89 */
89 private Integer expireTime; 90 private Integer expireTime;
90 /** 91 /**
@@ -97,6 +98,7 @@ public class CombinationRecordDO extends BaseDO { @@ -97,6 +98,7 @@ public class CombinationRecordDO extends BaseDO {
97 private LocalDateTime endTime; 98 private LocalDateTime endTime;
98 /** 99 /**
99 * 开团需要人数 100 * 开团需要人数
  101 + *
100 * 关联 {@link CombinationActivityDO#getUserSize()} 102 * 关联 {@link CombinationActivityDO#getUserSize()}
101 */ 103 */
102 private Integer userSize; 104 private Integer userSize;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/package-info.java deleted
1 -package cn.iocoder.yudao.module.promotion.dal.dataobject.combination;  
2 \ No newline at end of file 0 \ No newline at end of file
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillProductDO.java
@@ -47,11 +47,11 @@ public class SeckillProductDO extends BaseDO { @@ -47,11 +47,11 @@ public class SeckillProductDO extends BaseDO {
47 @TableField(typeHandler = LongListTypeHandler.class) 47 @TableField(typeHandler = LongListTypeHandler.class)
48 private List<Long> configIds; 48 private List<Long> configIds;
49 /** 49 /**
50 - * 商品 spu_id 50 + * 商品 SPU 编号
51 */ 51 */
52 private Long spuId; 52 private Long spuId;
53 /** 53 /**
54 - * 商品 sku_id 54 + * 商品 SKU 编号
55 */ 55 */
56 private Long skuId; 56 private Long skuId;
57 /** 57 /**
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillconfig/SeckillConfigDO.java
@@ -50,7 +50,7 @@ public class SeckillConfigDO extends BaseDO { @@ -50,7 +50,7 @@ public class SeckillConfigDO extends BaseDO {
50 private List<String> sliderPicUrls; 50 private List<String> sliderPicUrls;
51 /** 51 /**
52 * 状态 52 * 状态
53 - * <p> 53 + *
54 * 枚举 {@link CommonStatusEnum 对应的类} 54 * 枚举 {@link CommonStatusEnum 对应的类}
55 */ 55 */
56 private Integer status; 56 private Integer status;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationActivityMapper.java
@@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Mapper; @@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
10 10
11 import java.util.List; 11 import java.util.List;
12 12
  13 +// TODO @puhui999:是不是应该在 combination 哈?
13 /** 14 /**
14 * 拼团活动 Mapper 15 * 拼团活动 Mapper
15 * 16 *
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationRecordMapper.java
@@ -16,16 +16,18 @@ import java.util.List; @@ -16,16 +16,18 @@ import java.util.List;
16 public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO> { 16 public interface CombinationRecordMapper extends BaseMapperX<CombinationRecordDO> {
17 17
18 default CombinationRecordDO selectRecord(Long userId, Long orderId) { 18 default CombinationRecordDO selectRecord(Long userId, Long orderId) {
19 - return selectOne(CombinationRecordDO::getUserId, userId, CombinationRecordDO::getOrderId, orderId); 19 + return selectOne(CombinationRecordDO::getUserId, userId,
  20 + CombinationRecordDO::getOrderId, orderId);
20 } 21 }
21 22
22 default List<CombinationRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) { 23 default List<CombinationRecordDO> selectListByHeadIdAndStatus(Long headId, Integer status) {
23 - return selectList(new LambdaQueryWrapperX<CombinationRecordDO>().eq(CombinationRecordDO::getHeadId, headId) 24 + return selectList(new LambdaQueryWrapperX<CombinationRecordDO>()
  25 + .eq(CombinationRecordDO::getHeadId, headId)
24 .eq(CombinationRecordDO::getStatus, status)); 26 .eq(CombinationRecordDO::getStatus, status));
25 } 27 }
26 28
27 default List<CombinationRecordDO> selectListByStatus(Integer status) { 29 default List<CombinationRecordDO> selectListByStatus(Integer status) {
28 - return selectList(new LambdaQueryWrapperX<CombinationRecordDO>().eq(CombinationRecordDO::getStatus, status)); 30 + return selectList(CombinationRecordDO::getStatus, status);
29 } 31 }
30 32
31 } 33 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/package-info.java deleted
1 -package cn.iocoder.yudao.module.promotion.dal.mysql.combination;  
2 \ No newline at end of file 0 \ No newline at end of file
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillconfig/SeckillConfigMapper.java
@@ -23,5 +23,4 @@ public interface SeckillConfigMapper extends BaseMapperX&lt;SeckillConfigDO&gt; { @@ -23,5 +23,4 @@ public interface SeckillConfigMapper extends BaseMapperX&lt;SeckillConfigDO&gt; {
23 return selectList(SeckillConfigDO::getStatus, status); 23 return selectList(SeckillConfigDO::getStatus, status);
24 } 24 }
25 25
26 -  
27 } 26 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
@@ -83,6 +83,7 @@ public interface CombinationActivityService { @@ -83,6 +83,7 @@ public interface CombinationActivityService {
83 */ 83 */
84 List<CombinationProductDO> getProductsByActivityIds(Collection<Long> ids); 84 List<CombinationProductDO> getProductsByActivityIds(Collection<Long> ids);
85 85
  86 + // TODO @puhui999:拆一个 CombinationRecordService 里,方法名可以简洁成 updateRecordStatusByOrderId;service 方法可以稍微简单一点,如果是 update 方法
86 /** 87 /**
87 * 更新拼团状态 88 * 更新拼团状态
88 * 89 *
@@ -99,10 +100,10 @@ public interface CombinationActivityService { @@ -99,10 +100,10 @@ public interface CombinationActivityService {
99 * @param orderId 订单编号 100 * @param orderId 订单编号
100 * @param status 状态 101 * @param status 状态
101 * @param startTime 开始时间 102 * @param startTime 开始时间
102 - * @return  
103 */ 103 */
104 void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime); 104 void updateRecordStatusAndStartTimeByUserIdAndOrderId(Long userId, Long orderId, Integer status, LocalDateTime startTime);
105 105
  106 + // TODO @puhui999:拆一个 CombinationRecordService 里
106 /** 107 /**
107 * 创建拼团记录 108 * 创建拼团记录
108 * 109 *
@@ -118,4 +119,5 @@ public interface CombinationActivityService { @@ -118,4 +119,5 @@ public interface CombinationActivityService {
118 * @return 拼团状态 119 * @return 拼团状态
119 */ 120 */
120 boolean validateRecordStatusIsSuccess(Long userId, Long orderId); 121 boolean validateRecordStatusIsSuccess(Long userId, Long orderId);
  122 +
121 } 123 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
@@ -254,28 +254,33 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -254,28 +254,33 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
254 @Override 254 @Override
255 public void createRecord(CombinationRecordReqDTO reqDTO) { 255 public void createRecord(CombinationRecordReqDTO reqDTO) {
256 // 校验拼团活动 256 // 校验拼团活动
257 - CombinationActivityDO activityDO = validateCombinationActivityExists(reqDTO.getActivityId()); 257 + CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId());
  258 + // TODO @puhui999:需要校验下,它当前是不是已经参加了该拼团;
  259 + // TODO @puhui999: 父拼团是否存在,是否已经满了
258 260
259 - CombinationRecordDO recordDO = CombinationActivityConvert.INSTANCE.convert(reqDTO);  
260 - recordDO.setVirtualGroup(false);  
261 - recordDO.setExpireTime(activityDO.getLimitDuration());  
262 - recordDO.setUserSize(activityDO.getUserSize());  
263 - recordMapper.insert(recordDO); 261 + CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
  262 + record.setVirtualGroup(false);
  263 + // TODO @puhui999:过期时间,应该是 Date 哈;
  264 + record.setExpireTime(activity.getLimitDuration());
  265 + record.setUserSize(activity.getUserSize());
  266 + recordMapper.insert(record);
264 } 267 }
265 268
266 @Override 269 @Override
267 public boolean validateRecordStatusIsSuccess(Long userId, Long orderId) { 270 public boolean validateRecordStatusIsSuccess(Long userId, Long orderId) {
268 - CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);  
269 - return ObjectUtil.equal(recordDO.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus()); 271 + CombinationRecordDO record = validateCombinationRecord(userId, orderId);
  272 + // TODO @puhui999:可以搞个 getRecrod 方法,然后业务通过 CombinationRecordStatusEnum.isSuccess 方法校验
  273 + return ObjectUtil.equal(record.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus());
270 } 274 }
271 275
  276 + // TODO @puhui999:status 传入进来搞哈;
272 /** 277 /**
273 * APP 端获取开团记录 278 * APP 端获取开团记录
274 * 279 *
275 * @return 开团记录 280 * @return 开团记录
276 */ 281 */
277 public List<CombinationRecordDO> getRecordList() { 282 public List<CombinationRecordDO> getRecordList() {
278 - return recordMapper.selectListByStatus(CombinationRecordStatusEnum.ONGOING.getStatus()); 283 + return recordMapper.selectListByStatus(CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
279 } 284 }
280 285
281 } 286 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java
@@ -60,9 +60,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -60,9 +60,10 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
60 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) { 60 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
61 // 校验商品秒秒杀时段是否冲突 61 // 校验商品秒秒杀时段是否冲突
62 validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuId(), null); 62 validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuId(), null);
63 - // 获取所选 spu下的所有 sku 63 + // 获取所选 spu 下的所有 sku
64 List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(createReqVO.getSpuId())); 64 List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(createReqVO.getSpuId()));
65 // 校验商品 sku 是否存在 65 // 校验商品 sku 是否存在
  66 + // TODO @puhui999:直接校验 sku 数量,是不是就完事啦,不需要校验的特别严谨哈;
66 validateProductSkuExistence(skus, createReqVO.getProducts(), SeckillProductCreateReqVO::getSkuId); 67 validateProductSkuExistence(skus, createReqVO.getProducts(), SeckillProductCreateReqVO::getSkuId);
67 68
68 // 插入秒杀活动 69 // 插入秒杀活动
@@ -71,6 +72,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -71,6 +72,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
71 .setTotalStock(CollectionUtils.getSumValue(createReqVO.getProducts(), SeckillProductCreateReqVO::getStock, Integer::sum)); 72 .setTotalStock(CollectionUtils.getSumValue(createReqVO.getProducts(), SeckillProductCreateReqVO::getStock, Integer::sum));
72 seckillActivityMapper.insert(activity); 73 seckillActivityMapper.insert(activity);
73 // 插入商品 74 // 插入商品
  75 + // TODO @puhui999:products 要注意复数哈
74 List<SeckillProductDO> product = SeckillActivityConvert.INSTANCE.convertList(activity, createReqVO.getProducts()); 76 List<SeckillProductDO> product = SeckillActivityConvert.INSTANCE.convertList(activity, createReqVO.getProducts());
75 seckillProductMapper.insertBatch(product); 77 seckillProductMapper.insertBatch(product);
76 return activity.getId(); 78 return activity.getId();
@@ -97,6 +99,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -97,6 +99,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
97 } 99 }
98 List<SeckillActivityDO> activityDOs2 = CollectionUtils.convertList(activityDOs, c -> c, s -> { 100 List<SeckillActivityDO> activityDOs2 = CollectionUtils.convertList(activityDOs, c -> c, s -> {
99 // 判断秒杀时段是否有交集 101 // 判断秒杀时段是否有交集
  102 + // TODO @puhui999:是不是 containsAny 就是有交集呀
100 List<Long> configIdsClone = CollUtil.newArrayList(s.getConfigIds()); 103 List<Long> configIdsClone = CollUtil.newArrayList(s.getConfigIds());
101 configIdsClone.retainAll(configIds); 104 configIdsClone.retainAll(configIds);
102 return CollUtil.isNotEmpty(configIdsClone); 105 return CollUtil.isNotEmpty(configIdsClone);
@@ -134,29 +137,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -134,29 +137,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
134 /** 137 /**
135 * 更新秒杀商品 138 * 更新秒杀商品
136 * 139 *
137 - * @param updateObj DO 140 + * @param updateObj 更新的活动
138 * @param products 商品配置 141 * @param products 商品配置
139 */ 142 */
  143 + // TODO @puhui999:我在想,我们是不是可以封装一个 CollUtil 的方法,传入两个数组,判断出哪些是新增、哪些是修改、哪些是删除;
  144 + // 例如说,products 先转化成 SeckillProductDO;然后,基于一个 func(key1, key2) 做比对;
  145 + // 如果可以跑通,所有涉及到这种逻辑的,都可以服用哈。
140 private void updateSeckillProduct(SeckillActivityDO updateObj, List<SeckillProductUpdateReqVO> products) { 146 private void updateSeckillProduct(SeckillActivityDO updateObj, List<SeckillProductUpdateReqVO> products) {
141 - List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateObj.getId());  
142 // 数据库中的活动商品 147 // 数据库中的活动商品
143 - Set<Long> convertSet = CollectionUtils.convertSet(seckillProductDOs, SeckillProductDO::getSkuId);  
144 - // 前端传过来的活动商品  
145 - Set<Long> convertSet1 = CollectionUtils.convertSet(products, SeckillProductUpdateReqVO::getSkuId);  
146 - // 删除后台存在的前端不存在的商品  
147 - List<Long> d = CollectionUtils.filterList(convertSet, item -> !convertSet1.contains(item)); 148 + List<SeckillProductDO> seckillProductDOs = seckillProductMapper.selectListByActivityId(updateObj.getId());
  149 + Set<Long> dbSkuIds = CollectionUtils.convertSet(seckillProductDOs, SeckillProductDO::getSkuId);
  150 + // 1. 删除后台存在的前端不存在的商品
  151 + // TODO @puhui999:delete 应该是 id,不是 skuId 哈
  152 + Set<Long> voSkuIds = CollectionUtils.convertSet(products, SeckillProductUpdateReqVO::getSkuId);
  153 + List<Long> d = CollectionUtils.filterList(dbSkuIds, item -> !voSkuIds.contains(item));
148 if (CollUtil.isNotEmpty(d)) { 154 if (CollUtil.isNotEmpty(d)) {
149 seckillProductMapper.deleteBatchIds(d); 155 seckillProductMapper.deleteBatchIds(d);
150 } 156 }
151 - // 前端存在的后端不存在的商品  
152 - List<Long> c = CollectionUtils.filterList(convertSet1, item -> !convertSet.contains(item)); 157 + // 2. 前端存在的后端不存在的商品
  158 + List<Long> c = CollectionUtils.filterList(voSkuIds, item -> !dbSkuIds.contains(item));
153 if (CollUtil.isNotEmpty(c)) { 159 if (CollUtil.isNotEmpty(c)) {
154 List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> c.contains(item.getSkuId())); 160 List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> c.contains(item.getSkuId()));
155 List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList(updateObj, vos); 161 List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList(updateObj, vos);
156 seckillProductMapper.insertBatch(productDOs); 162 seckillProductMapper.insertBatch(productDOs);
157 } 163 }
158 - // 更新已存在的商品  
159 - List<Long> u = CollectionUtils.filterList(convertSet1, convertSet::contains); 164 + // 3. 更新已存在的商品
  165 + List<Long> u = CollectionUtils.filterList(voSkuIds, dbSkuIds::contains);
160 if (CollUtil.isNotEmpty(u)) { 166 if (CollUtil.isNotEmpty(u)) {
161 List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> u.contains(item.getSkuId())); 167 List<SeckillProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> u.contains(item.getSkuId()));
162 List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList1(updateObj, vos, seckillProductDOs); 168 List<SeckillProductDO> productDOs = SeckillActivityConvert.INSTANCE.convertList1(updateObj, vos, seckillProductDOs);
@@ -165,12 +171,12 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -165,12 +171,12 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
165 } 171 }
166 172
167 @Override 173 @Override
168 - @Transactional(rollbackFor = Exception.class) 174 + @Transactional(rollbackFor = Exception.class) // TODO @puhui999:这个不用加事务哈
169 public void closeSeckillActivity(Long id) { 175 public void closeSeckillActivity(Long id) {
170 // TODO 待验证没使用过 176 // TODO 待验证没使用过
171 // 校验存在 177 // 校验存在
172 - SeckillActivityDO seckillActivity = validateSeckillActivityExists(id);  
173 - if (CommonStatusEnum.DISABLE.getStatus().equals(seckillActivity.getStatus())) { 178 + SeckillActivityDO activity = validateSeckillActivityExists(id);
  179 + if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) {
174 throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED); 180 throw exception(SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
175 } 181 }
176 182
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java
@@ -151,6 +151,7 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { @@ -151,6 +151,7 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
151 return seckillConfigMapper.selectPage(pageVO); 151 return seckillConfigMapper.selectPage(pageVO);
152 } 152 }
153 153
  154 + // TODO @puhui999:改成传入 enable 状态哈。一个通用的 getSeckillConfigList 方法
154 @Override 155 @Override
155 public List<SeckillConfigDO> getListAllSimple() { 156 public List<SeckillConfigDO> getListAllSimple() {
156 return seckillConfigMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); 157 return seckillConfigMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java
@@ -31,6 +31,7 @@ public class PromotionUtils { @@ -31,6 +31,7 @@ public class PromotionUtils {
31 return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus(); 31 return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus();
32 } 32 }
33 33
  34 + // TODO @puhui999:写个注释哈。
34 public static <T> void validateProductSkuExistence(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) { 35 public static <T> void validateProductSkuExistence(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) {
35 // 校验 sku 个数是否一致 36 // 校验 sku 个数是否一致
36 Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func); 37 Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func);
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java
@@ -24,6 +24,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; @@ -24,6 +24,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
24 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_NOT_EXISTS; 24 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_NOT_EXISTS;
25 import static org.junit.jupiter.api.Assertions.*; 25 import static org.junit.jupiter.api.Assertions.*;
26 26
  27 +// TODO 芋艿:等完成后,在补全单测
27 /** 28 /**
28 * {@link CombinationActivityServiceImpl} 的单元测试类 29 * {@link CombinationActivityServiceImpl} 的单元测试类
29 * 30 *
yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql
1 -DELETE  
2 -FROM "market_activity";  
3 -DELETE  
4 -FROM "promotion_coupon_template";  
5 -DELETE  
6 -FROM "promotion_coupon";  
7 -DELETE  
8 -FROM "promotion_reward_activity";  
9 -DELETE  
10 -FROM "promotion_discount_activity";  
11 -DELETE  
12 -FROM "promotion_discount_product";  
13 -DELETE  
14 -FROM "promotion_seckill_config";  
15 -DELETE  
16 -FROM "promotion_combination_activity"; 1 +DELETE FROM "market_activity";
  2 +DELETE FROM "promotion_coupon_template";
  3 +DELETE FROM "promotion_coupon";
  4 +DELETE FROM "promotion_reward_activity";
  5 +DELETE FROM "promotion_discount_activity";
  6 +DELETE FROM "promotion_discount_product";
  7 +DELETE FROM "promotion_seckill_config";
  8 +DELETE FROM "promotion_combination_activity";
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -70,7 +70,9 @@ public interface ErrorCodeConstants { @@ -70,7 +70,9 @@ public interface ErrorCodeConstants {
70 ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在"); 70 ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在");
71 71
72 // ========== 物流 PICK_UP 模块 1011007000 ========== 72 // ========== 物流 PICK_UP 模块 1011007000 ==========
  73 + // TODO @puhui999:这几个错误码,应该属于订单哈
73 ErrorCode ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY = new ErrorCode(1011007000, "订单发货失败,请选择发货商品"); 74 ErrorCode ORDER_DELIVERY_FAILED_ITEMS_NOT_EMPTY = new ErrorCode(1011007000, "订单发货失败,请选择发货商品");
74 ErrorCode ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS = new ErrorCode(1011007001, "订单发货失败,所选发货商品不存在"); 75 ErrorCode ORDER_DELIVERY_FAILED_ITEM_NOT_EXISTS = new ErrorCode(1011007001, "订单发货失败,所选发货商品不存在");
75 - ErrorCode ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY = new ErrorCode(1011007001, "订单发货失败,所选商品已发货"); 76 + ErrorCode ORDER_DELIVERY_FAILED_ITEM_ALREADY_DELIVERY = new ErrorCode(1011007002, "订单发货失败,所选商品已发货");
  77 +
76 } 78 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java
@@ -21,13 +21,15 @@ public class TradeOrderDeliveryReqVO { @@ -21,13 +21,15 @@ public class TradeOrderDeliveryReqVO {
21 @NotNull(message = "发货类型不能为空") 21 @NotNull(message = "发货类型不能为空")
22 private Integer type; 22 private Integer type;
23 23
  24 + // TODO @puhui999:还是要校验下
  25 +
24 @Schema(description = "发货物流公司编号", example = "1") 26 @Schema(description = "发货物流公司编号", example = "1")
25 private Long logisticsId; 27 private Long logisticsId;
26 28
27 @Schema(description = "发货物流单号", example = "SF123456789") 29 @Schema(description = "发货物流单号", example = "SF123456789")
28 private String logisticsNo; 30 private String logisticsNo;
29 31
30 - // TODO 订单项商品单独发货 32 + // TODO 订单项商品单独发货;不做单独发
31 33
32 @Schema(description = "发货订单项", example = "[1,2,3]") 34 @Schema(description = "发货订单项", example = "[1,2,3]")
33 @NotNull(message = "发货订单项不能为空") 35 @NotNull(message = "发货订单项不能为空")
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
@@ -108,13 +108,17 @@ public class AppTradeOrderController { @@ -108,13 +108,17 @@ public class AppTradeOrderController {
108 // 全部 108 // 全部
109 orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null)); 109 orderCount.put("allCount", tradeOrderService.getOrderCount(getLoginUserId(), null, null));
110 // 待付款(未支付) 110 // 待付款(未支付)
111 - orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNPAID.getStatus(), null)); 111 + orderCount.put("unpaidCount", tradeOrderService.getOrderCount(getLoginUserId(),
  112 + TradeOrderStatusEnum.UNPAID.getStatus(), null));
112 // 待发货 113 // 待发货
113 - orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.UNDELIVERED.getStatus(), null)); 114 + orderCount.put("undeliveredCount", tradeOrderService.getOrderCount(getLoginUserId(),
  115 + TradeOrderStatusEnum.UNDELIVERED.getStatus(), null));
114 // 待收货 116 // 待收货
115 - orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.DELIVERED.getStatus(), null)); 117 + orderCount.put("deliveredCount", tradeOrderService.getOrderCount(getLoginUserId(),
  118 + TradeOrderStatusEnum.DELIVERED.getStatus(), null));
116 // 待评价 119 // 待评价
117 - orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(), TradeOrderStatusEnum.COMPLETED.getStatus(), false)); 120 + orderCount.put("uncommentedCount", tradeOrderService.getOrderCount(getLoginUserId(),
  121 + TradeOrderStatusEnum.COMPLETED.getStatus(), false));
118 return success(orderCount); 122 return success(orderCount);
119 } 123 }
120 124
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDeliveryDO.java
@@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence; @@ -6,7 +6,7 @@ import com.baomidou.mybatisplus.annotation.KeySequence;
6 import com.baomidou.mybatisplus.annotation.TableName; 6 import com.baomidou.mybatisplus.annotation.TableName;
7 import lombok.*; 7 import lombok.*;
8 8
9 - 9 +// TODO @puhui999:
10 /** 10 /**
11 * 交易订单发货记录 DO 11 * 交易订单发货记录 DO
12 * 12 *
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderDeliveryMapper.java
@@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Mapper; @@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Mapper;
7 7
8 import java.util.List; 8 import java.util.List;
9 9
  10 +// TODO @puhui999:应该去掉啦
10 /** 11 /**
11 * 交易订单发货记录 Mapper 12 * 交易订单发货记录 Mapper
12 * 13 *
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java
@@ -180,8 +180,7 @@ public interface TradeOrderService { @@ -180,8 +180,7 @@ public interface TradeOrderService {
180 TradeOrderDO getOrderByIdAndUserId(Long orderId, Long loginUserId); 180 TradeOrderDO getOrderByIdAndUserId(Long orderId, Long loginUserId);
181 181
182 /** 182 /**
183 - * 创建订单项评论  
184 - * 创建交易订单项的评价 183 + * 创建订单项的评论
185 * 184 *
186 * @param createReqVO 创建请求 185 * @param createReqVO 创建请求
187 * @return 得到评价 id 186 * @return 得到评价 id
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
@@ -178,7 +178,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -178,7 +178,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
178 MemberUserRespDTO user = memberUserApi.getUser(userId); 178 MemberUserRespDTO user = memberUserApi.getUser(userId);
179 // TODO 拼团一次应该只能选择一种规格的商品 179 // TODO 拼团一次应该只能选择一种规格的商品
180 combinationApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user) 180 combinationApi.createRecord(TradeOrderConvert.INSTANCE.convert(order, orderItems.get(0), createReqVO, user)
181 - .setStatus(CombinationRecordStatusEnum.NOT_PAY.getStatus())); 181 + .setStatus(CombinationRecordStatusEnum.WAITING.getStatus()));
182 } 182 }
183 // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除 183 // TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
184 if (ObjectUtil.equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) { 184 if (ObjectUtil.equal(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
@@ -204,23 +204,6 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -204,23 +204,6 @@ public class TradeOrderServiceImpl implements TradeOrderService {
204 return address; 204 return address;
205 } 205 }
206 206
207 - /**  
208 - * 校验活动返回订单类型  
209 - *  
210 - * @param createReqVO 请求参数  
211 - * @return 订单类型  
212 - */  
213 - private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) {  
214 - if (createReqVO.getSeckillActivityId() != null) {  
215 - return TradeOrderTypeEnum.SECKILL.getType();  
216 - }  
217 - if (createReqVO.getCombinationActivityId() != null) {  
218 - return TradeOrderTypeEnum.COMBINATION.getType();  
219 - }  
220 - // TODO 砍价敬请期待  
221 - return TradeOrderTypeEnum.NORMAL.getType();  
222 - }  
223 -  
224 private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO, 207 private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO,
225 TradePriceCalculateRespBO calculateRespBO) { 208 TradePriceCalculateRespBO calculateRespBO) {
226 // 用户选择物流配送的时候才需要填写收货地址 209 // 用户选择物流配送的时候才需要填写收货地址
@@ -246,6 +229,23 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -246,6 +229,23 @@ public class TradeOrderServiceImpl implements TradeOrderService {
246 return order; 229 return order;
247 } 230 }
248 231
  232 + /**
  233 + * 校验活动,并返回订单类型
  234 + *
  235 + * @param createReqVO 请求参数
  236 + * @return 订单类型
  237 + */
  238 + private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) {
  239 + if (createReqVO.getSeckillActivityId() != null) {
  240 + return TradeOrderTypeEnum.SECKILL.getType();
  241 + }
  242 + if (createReqVO.getCombinationActivityId() != null) {
  243 + return TradeOrderTypeEnum.COMBINATION.getType();
  244 + }
  245 + // TODO 砍价敬请期待
  246 + return TradeOrderTypeEnum.NORMAL.getType();
  247 + }
  248 +
249 private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) { 249 private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) {
250 List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO); 250 List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO);
251 tradeOrderItemMapper.insertBatch(orderItems); 251 tradeOrderItemMapper.insertBatch(orderItems);
@@ -314,7 +314,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -314,7 +314,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
314 // 1、拼团活动 314 // 1、拼团活动
315 if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { 315 if (ObjectUtil.equal(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
316 // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录 316 // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录
317 - combinationApi.updateRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.ONGOING.getStatus()); 317 + combinationApi.updateRecordStatusAndStartTime(order.getUserId(), order.getId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
318 } 318 }
319 // TODO 芋艿:发送订单变化的消息 319 // TODO 芋艿:发送订单变化的消息
320 320
@@ -422,6 +422,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -422,6 +422,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
422 orderDeliveryMapper.insertBatch(deliveryDOs); 422 orderDeliveryMapper.insertBatch(deliveryDOs);
423 // TODO 芋艿:发送订单变化的消息 423 // TODO 芋艿:发送订单变化的消息
424 424
  425 + // TODO @puhui999:可以抽个 message 包,里面是 Order 所有的 message;类似工作流的
425 // 发送站内信 426 // 发送站内信
426 // 1、构造消息 427 // 1、构造消息
427 Map<String, Object> msgMap = new HashMap<>(); 428 Map<String, Object> msgMap = new HashMap<>();
@@ -684,24 +685,26 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -684,24 +685,26 @@ public class TradeOrderServiceImpl implements TradeOrderService {
684 @Override 685 @Override
685 public Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO) { 686 public Long createOrderItemComment(AppTradeOrderItemCommentCreateReqVO createReqVO) {
686 Long loginUserId = getLoginUserId(); 687 Long loginUserId = getLoginUserId();
687 - // 先通过订单项 ID 查询订单项是否存在  
688 - TradeOrderItemDO orderItemDO = getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);  
689 - if (orderItemDO == null) { 688 + // 先通过订单项 ID,查询订单项是否存在
  689 + TradeOrderItemDO orderItem = getOrderItemByIdAndUserId(createReqVO.getOrderItemId(), loginUserId);
  690 + if (orderItem == null) {
690 throw exception(ORDER_ITEM_NOT_FOUND); 691 throw exception(ORDER_ITEM_NOT_FOUND);
691 } 692 }
692 // 校验订单 693 // 校验订单
693 - TradeOrderDO orderDO = getOrderByIdAndUserId(orderItemDO.getOrderId(), loginUserId);  
694 - if (orderDO == null) { 694 + TradeOrderDO order = getOrderByIdAndUserId(orderItem.getOrderId(), loginUserId);
  695 + if (order == null) {
695 throw exception(ORDER_NOT_FOUND); 696 throw exception(ORDER_NOT_FOUND);
696 } 697 }
697 - if (ObjectUtil.notEqual(orderDO.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) { 698 + if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus())) {
698 throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED); 699 throw exception(ORDER_COMMENT_FAIL_STATUS_NOT_COMPLETED);
699 } 700 }
700 - if (ObjectUtil.notEqual(orderDO.getCommentStatus(), Boolean.FALSE)) { 701 + if (ObjectUtil.notEqual(order.getCommentStatus(), Boolean.FALSE)) {
701 throw exception(ORDER_COMMENT_STATUS_NOT_FALSE); 702 throw exception(ORDER_COMMENT_STATUS_NOT_FALSE);
702 } 703 }
  704 + // TODO @puhui999:是不是评论完,要更新 status、commentStatus;另外,是不是上面 order 可以不校验,直接只判断 orderItem 就够;
  705 + // 对于 order 来说,就是评论完,把 order 更新完合理的 status 等字段。
703 706
704 - ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItemDO); 707 + ProductCommentCreateReqDTO productCommentCreateReqDTO = TradeOrderConvert.INSTANCE.convert04(createReqVO, orderItem);
705 return productCommentApi.createComment(productCommentCreateReqDTO); 708 return productCommentApi.createComment(productCommentCreateReqDTO);
706 } 709 }
707 710
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImpl.java
@@ -21,7 +21,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU @@ -21,7 +21,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
21 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 21 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
22 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 22 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
23 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*; 23 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
24 -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL; 24 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_PAY_PRICE_ILLEGAL;
25 25
26 /** 26 /**
27 * 价格计算 Service 实现类 27 * 价格计算 Service 实现类