Commit de828e3d047020482358bad58f0c9e02dbd08ee5

Authored by puhui999
2 parents e2a8f7b3 36da5d69

Merge remote-tracking branch 'yudao/feature/mall_product' into feature/mall_product

# Conflicts:
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityCreateReqVO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityRespVO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityUpdateReqVO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityCreateReqVO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/activity/BargainActivityPageReqVO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/product/BargainProductBaseVO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityPageReqVO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainActivityDO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainProductDO.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationActivityMapper.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationServiceImpl.java
#	yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImplTest.java
#	yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
Showing 51 changed files with 683 additions and 351 deletions
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/AppFileController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.app.file;
  2 +
  3 +import cn.hutool.core.io.IoUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.module.infra.controller.app.file.vo.AppFileUploadReqVO;
  6 +import cn.iocoder.yudao.module.infra.service.file.FileService;
  7 +import io.swagger.v3.oas.annotations.Operation;
  8 +import io.swagger.v3.oas.annotations.tags.Tag;
  9 +import lombok.extern.slf4j.Slf4j;
  10 +import org.springframework.validation.annotation.Validated;
  11 +import org.springframework.web.bind.annotation.PostMapping;
  12 +import org.springframework.web.bind.annotation.RequestMapping;
  13 +import org.springframework.web.bind.annotation.RestController;
  14 +import org.springframework.web.multipart.MultipartFile;
  15 +
  16 +import javax.annotation.Resource;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  19 +
  20 +@Tag(name = "用户 App - 文件存储")
  21 +@RestController
  22 +@RequestMapping("/infra/file")
  23 +@Validated
  24 +@Slf4j
  25 +public class AppFileController {
  26 +
  27 + @Resource
  28 + private FileService fileService;
  29 +
  30 + @PostMapping("/upload")
  31 + @Operation(summary = "上传文件")
  32 + public CommonResult<String> uploadFile(AppFileUploadReqVO uploadReqVO) throws Exception {
  33 + MultipartFile file = uploadReqVO.getFile();
  34 + String path = uploadReqVO.getPath();
  35 + return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
  36 + }
  37 +
  38 +}
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/app/file/vo/AppFileUploadReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.controller.app.file.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.web.multipart.MultipartFile;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@Schema(description = "用户 App - 上传文件 Request VO")
  10 +@Data
  11 +public class AppFileUploadReqVO {
  12 +
  13 + @Schema(description = "文件附件", requiredMode = Schema.RequiredMode.REQUIRED)
  14 + @NotNull(message = "文件附件不能为空")
  15 + private MultipartFile file;
  16 +
  17 + @Schema(description = "文件附件", example = "yudaoyuanma.png")
  18 + private String path;
  19 +
  20 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java
@@ -21,4 +21,11 @@ public interface ProductSpuApi { @@ -21,4 +21,11 @@ public interface ProductSpuApi {
21 */ 21 */
22 List<ProductSpuRespDTO> getSpuList(Collection<Long> ids); 22 List<ProductSpuRespDTO> getSpuList(Collection<Long> ids);
23 23
  24 + /**
  25 + * 获得 SPU
  26 + *
  27 + * @return SPU
  28 + */
  29 + ProductSpuRespDTO getSpu(Long id);
  30 +
24 } 31 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
@@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; @@ -5,6 +5,8 @@ import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
5 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert; 5 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
6 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; 6 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
7 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper; 7 import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
  8 +import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
  9 +import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
8 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
9 import org.springframework.validation.annotation.Validated; 11 import org.springframework.validation.annotation.Validated;
10 12
@@ -24,15 +26,19 @@ import java.util.List; @@ -24,15 +26,19 @@ import java.util.List;
24 public class ProductSpuApiImpl implements ProductSpuApi { 26 public class ProductSpuApiImpl implements ProductSpuApi {
25 27
26 @Resource 28 @Resource
27 - private ProductSpuMapper productSpuMapper; 29 + private ProductSpuService spuService;
28 30
29 @Override 31 @Override
30 - public List<ProductSpuRespDTO> getSpuList(Collection<Long> spuIds) {  
31 - if (CollectionUtil.isEmpty(spuIds)) { 32 + public List<ProductSpuRespDTO> getSpuList(Collection<Long> ids) {
  33 + if (CollectionUtil.isEmpty(ids)) {
32 return Collections.emptyList(); 34 return Collections.emptyList();
33 } 35 }
34 - List<ProductSpuDO> productSpuDOList = productSpuMapper.selectBatchIds(spuIds);  
35 - return ProductSpuConvert.INSTANCE.convertList2(productSpuDOList); 36 + return ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids));
  37 + }
  38 +
  39 + @Override
  40 + public ProductSpuRespDTO getSpu(Long id) {
  41 + return ProductSpuConvert.INSTANCE.convert02(spuService.getSpu(id));
36 } 42 }
37 43
38 } 44 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
@@ -64,6 +64,8 @@ public interface ProductSpuConvert { @@ -64,6 +64,8 @@ public interface ProductSpuConvert {
64 64
65 ProductSpuDetailRespVO convert03(ProductSpuDO spu); 65 ProductSpuDetailRespVO convert03(ProductSpuDO spu);
66 66
  67 + ProductSpuRespDTO convert02(ProductSpuDO bean);
  68 +
67 // ========== 用户 App 相关 ========== 69 // ========== 用户 App 相关 ==========
68 70
69 PageResult<AppProductSpuPageRespVO> convertPageForGetSpuPage(PageResult<ProductSpuDO> page); 71 PageResult<AppProductSpuPageRespVO> convertPageForGetSpuPage(PageResult<ProductSpuDO> page);
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -50,14 +50,11 @@ public interface ErrorCodeConstants { @@ -50,14 +50,11 @@ public interface ErrorCodeConstants {
50 ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013008003, "秒杀活动已关闭,不能修改"); 50 ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013008003, "秒杀活动已关闭,不能修改");
51 ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); 51 ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除");
52 ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); 52 ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭");
53 - ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1013008006, "秒杀活动已结束,不能关闭");  
54 53
55 // ========== 秒杀时段 1013009000 ========== 54 // ========== 秒杀时段 1013009000 ==========
56 - ErrorCode SECKILL_TIME_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在");  
57 - ErrorCode SECKILL_TIME_CONFLICTS = new ErrorCode(1013009001, "秒杀时段冲突");  
58 - ErrorCode SECKILL_TIME_EQUAL = new ErrorCode(1013009002, "秒杀时段开始时间和结束时间不能相等");  
59 - ErrorCode SECKILL_START_TIME_BEFORE_END_TIME = new ErrorCode(1013009003, "秒杀时段开始时间不能在结束时间之后");  
60 - ErrorCode SECKILL_TIME_DISABLE = new ErrorCode(1013009004, "秒杀时段已关闭"); 55 + ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在");
  56 + ErrorCode SECKILL_CONFIG_TIME_CONFLICTS = new ErrorCode(1013009001, "秒杀时段冲突");
  57 + ErrorCode SECKILL_CONFIG_DISABLE = new ErrorCode(1013009004, "秒杀时段已关闭");
61 58
62 // ========== 拼团活动 1013010000 ========== 59 // ========== 拼团活动 1013010000 ==========
63 ErrorCode COMBINATION_ACTIVITY_NOT_EXISTS = new ErrorCode(1013010000, "拼团活动不存在"); 60 ErrorCode COMBINATION_ACTIVITY_NOT_EXISTS = new ErrorCode(1013010000, "拼团活动不存在");
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.bargain; 1 package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 6 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
6 -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO;  
7 -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO;  
8 -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO;  
9 -import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; 7 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityCreateReqVO;
  9 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityPageReqVO;
  10 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityRespVO;
  11 +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.activity.BargainActivityUpdateReqVO;
10 import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert; 12 import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert;
11 import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService; 13 import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
12 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
@@ -18,6 +20,8 @@ import org.springframework.web.bind.annotation.*; @@ -18,6 +20,8 @@ import org.springframework.web.bind.annotation.*;
18 20
19 import javax.annotation.Resource; 21 import javax.annotation.Resource;
20 import javax.validation.Valid; 22 import javax.validation.Valid;
  23 +import java.util.Collections;
  24 +import java.util.List;
21 25
22 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 26 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
23 27
@@ -31,7 +35,7 @@ public class BargainActivityController { @@ -31,7 +35,7 @@ public class BargainActivityController {
31 private BargainActivityService activityService; 35 private BargainActivityService activityService;
32 36
33 @Resource 37 @Resource
34 - private ProductSpuApi spuApi; 38 + private ProductSpuApi productSpuApi;
35 39
36 @PostMapping("/create") 40 @PostMapping("/create")
37 @Operation(summary = "创建砍价活动") 41 @Operation(summary = "创建砍价活动")
@@ -70,6 +74,19 @@ public class BargainActivityController { @@ -70,6 +74,19 @@ public class BargainActivityController {
70 @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:query')") 74 @PreAuthorize("@ss.hasPermission('promotion:bargain-activity:query')")
71 public CommonResult<PageResult<BargainActivityRespVO>> getBargainActivityPage( 75 public CommonResult<PageResult<BargainActivityRespVO>> getBargainActivityPage(
72 @Valid BargainActivityPageReqVO pageVO) { 76 @Valid BargainActivityPageReqVO pageVO) {
  77 + // 查询砍价活动
  78 + PageResult<BargainActivityDO> pageResult = activityService.getBargainActivityPage(pageVO);
  79 + if (CollUtil.isEmpty(pageResult.getList())) {
  80 + return success(PageResult.empty(pageResult.getTotal()));
  81 + }
  82 +
  83 + // 拼接数据
  84 +// List<BargainProductDO> products = activityService.getBargainProductsByActivityIds(
  85 +// convertSet(pageResult.getList(), BargainActivityDO::getId));
  86 + List<BargainProductDO> products = Collections.emptyList();
  87 + List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(
  88 + convertSet(pageResult.getList(), BargainActivityDO::getSpuId));
  89 + return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, products, spus));
73 return success(BargainActivityConvert.INSTANCE.convertPage(activityService.getBargainActivityPage(pageVO))); 90 return success(BargainActivityConvert.INSTANCE.convertPage(activityService.getBargainActivityPage(pageVO)));
74 } 91 }
75 92
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityBaseVO.java
@@ -22,7 +22,7 @@ public class BargainActivityBaseVO { @@ -22,7 +22,7 @@ public class BargainActivityBaseVO {
22 @NotNull(message = "砍价名称不能为空") 22 @NotNull(message = "砍价名称不能为空")
23 private String name; 23 private String name;
24 24
25 - @Schema(description = "商品 SPU 编号,关联 ProductSpuDO 的 id", example = "[1,2,3]") 25 + @Schema(description = "商品 SPU 编号", example = "1")
26 @NotNull(message = "砍价商品不能为空") 26 @NotNull(message = "砍价商品不能为空")
27 private Long spuId; 27 private Long spuId;
28 28
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/vo/BargainActivityCreateReqVO.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo;  
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 BargainActivityCreateReqVO extends BargainActivityBaseVO {  
13 -  
14 -}  
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.CollUtil;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 6 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  7 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; 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.CombinationActivityPageReqVO; 9 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
8 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO; 10 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO;
@@ -21,7 +23,6 @@ import org.springframework.web.bind.annotation.*; @@ -21,7 +23,6 @@ import org.springframework.web.bind.annotation.*;
21 import javax.annotation.Resource; 23 import javax.annotation.Resource;
22 import javax.validation.Valid; 24 import javax.validation.Valid;
23 import java.util.List; 25 import java.util.List;
24 -import java.util.Set;  
25 26
26 import static cn.hutool.core.collection.CollectionUtil.newArrayList; 27 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.pojo.CommonResult.success;
@@ -37,7 +38,7 @@ public class CombinationActivityController { @@ -37,7 +38,7 @@ public class CombinationActivityController {
37 private CombinationActivityService combinationActivityService; 38 private CombinationActivityService combinationActivityService;
38 39
39 @Resource 40 @Resource
40 - private ProductSpuApi spuApi; 41 + private ProductSpuApi productSpuApi;
41 42
42 @PostMapping("/create") 43 @PostMapping("/create")
43 @Operation(summary = "创建拼团活动") 44 @Operation(summary = "创建拼团活动")
@@ -80,12 +81,16 @@ public class CombinationActivityController { @@ -80,12 +81,16 @@ public class CombinationActivityController {
80 @Valid CombinationActivityPageReqVO pageVO) { 81 @Valid CombinationActivityPageReqVO pageVO) {
81 // 查询拼团活动 82 // 查询拼团活动
82 PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO); 83 PageResult<CombinationActivityDO> pageResult = combinationActivityService.getCombinationActivityPage(pageVO);
  84 + if (CollUtil.isEmpty(pageResult.getList())) {
  85 + return success(PageResult.empty(pageResult.getTotal()));
  86 + }
  87 +
83 // 拼接数据 88 // 拼接数据
84 - Set<Long> activityIds = convertSet(pageResult.getList(), CombinationActivityDO::getId);  
85 - Set<Long> spuIds = convertSet(pageResult.getList(), CombinationActivityDO::getSpuId);  
86 - return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult,  
87 - combinationActivityService.getCombinationProductsByActivityIds(activityIds),  
88 - spuApi.getSpuList(spuIds))); 89 + List<CombinationProductDO> products = combinationActivityService.getCombinationProductsByActivityIds(
  90 + convertSet(pageResult.getList(), CombinationActivityDO::getId));
  91 + List<ProductSpuRespDTO> spus = productSpuApi.getSpuList(
  92 + convertSet(pageResult.getList(), CombinationActivityDO::getSpuId));
  93 + return success(CombinationActivityConvert.INSTANCE.convertPage(pageResult, products, spus));
89 } 94 }
90 95
91 } 96 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
@@ -22,7 +22,7 @@ public class CombinationActivityBaseVO { @@ -22,7 +22,7 @@ public class CombinationActivityBaseVO {
22 @NotNull(message = "拼团名称不能为空") 22 @NotNull(message = "拼团名称不能为空")
23 private String name; 23 private String name;
24 24
25 - @Schema(description = "商品 SPU 编号,关联 ProductSpuDO 的 id", example = "[1,2,3]") 25 + @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
26 @NotNull(message = "拼团商品不能为空") 26 @NotNull(message = "拼团商品不能为空")
27 private Long spuId; 27 private Long spuId;
28 28
@@ -48,7 +48,7 @@ public class CombinationActivityBaseVO { @@ -48,7 +48,7 @@ public class CombinationActivityBaseVO {
48 @NotNull(message = "开团人数不能为空") 48 @NotNull(message = "开团人数不能为空")
49 private Integer userSize; 49 private Integer userSize;
50 50
51 - @Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED) 51 + @Schema(description = "限制时长(小时)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
52 @NotNull(message = "限制时长不能为空") 52 @NotNull(message = "限制时长不能为空")
53 private Integer limitDuration; 53 private Integer limitDuration;
54 54
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity; 1 package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
2 2
3 -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO; 3 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
@@ -17,6 +17,6 @@ public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO { @@ -17,6 +17,6 @@ public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
17 17
18 @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED) 18 @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
19 @Valid 19 @Valid
20 - private List<CombinationProductCreateReqVO> products; 20 + private List<CombinationProductBaseVO> products;
21 21
22 } 22 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java
@@ -17,40 +17,34 @@ import java.util.List; @@ -17,40 +17,34 @@ import java.util.List;
17 @ToString(callSuper = true) 17 @ToString(callSuper = true)
18 public class CombinationActivityRespVO extends CombinationActivityBaseVO { 18 public class CombinationActivityRespVO extends CombinationActivityBaseVO {
19 19
20 - @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618大促") 20 + @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")
  21 + private Long id;
  22 +
  23 + @Schema(description = "商品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "618 大促")
21 private String spuName; 24 private String spuName;
22 25
23 @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png") 26 @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
24 private String picUrl; 27 private String picUrl;
25 28
26 - @Schema(description = "活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22901")  
27 - private Long id;  
28 -  
29 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 29 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
30 private LocalDateTime createTime; 30 private LocalDateTime createTime;
31 31
32 - @Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED)  
33 - @NotNull(message = "开团人数不能为空") 32 + @Schema(description = "开团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
34 private Integer userSize; 33 private Integer userSize;
35 34
36 - @Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED)  
37 - @NotNull(message = "开团组数不能为空")  
38 - private Integer totalNum; 35 + @Schema(description = "开团组数", requiredMode = Schema.RequiredMode.REQUIRED, example = "33")
  36 + private Integer totalCount;
39 37
40 - @Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED)  
41 - @NotNull(message = "成团组数不能为空")  
42 - private Integer successNum; 38 + @Schema(description = "成团组数", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
  39 + private Integer successCount;
43 40
44 - @Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED)  
45 - @NotNull(message = "虚拟成团不能为空") 41 + @Schema(description = "虚拟成团", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
46 private Integer virtualGroup; 42 private Integer virtualGroup;
47 43
48 @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 44 @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
49 - @NotNull(message = "活动状态不能为空")  
50 private Integer status; 45 private Integer status;
51 46
52 @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED) 47 @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
53 - @Valid  
54 private List<CombinationProductRespVO> products; 48 private List<CombinationProductRespVO> products;
55 49
56 } 50 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity; 1 package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
2 2
3 -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO; 3 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
@@ -22,6 +22,6 @@ public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO { @@ -22,6 +22,6 @@ public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO {
22 22
23 @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED) 23 @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
24 @Valid 24 @Valid
25 - private List<CombinationProductUpdateReqVO> products; 25 + private List<CombinationProductBaseVO> products;
26 26
27 } 27 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductBaseVO.java
@@ -21,7 +21,7 @@ public class CombinationProductBaseVO { @@ -21,7 +21,7 @@ public class CombinationProductBaseVO {
21 private Long skuId; 21 private Long skuId;
22 22
23 @Schema(description = "拼团价格,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "27682") 23 @Schema(description = "拼团价格,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "27682")
24 - @NotNull(message = "拼团价格,单位分不能为空")  
25 - private Integer activePrice; 24 + @NotNull(message = "拼团价格不能为空")
  25 + private Integer combinationPrice;
26 26
27 } 27 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductCreateReqVO.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -import lombok.EqualsAndHashCode;  
6 -import lombok.ToString;  
7 -  
8 -@Schema(description = "管理后台 - 拼团商品创建 Request VO")  
9 -@Data  
10 -@EqualsAndHashCode(callSuper = true)  
11 -@ToString(callSuper = true)  
12 -public class CombinationProductCreateReqVO extends CombinationProductBaseVO {  
13 -  
14 -}  
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductUpdateReqVO.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product;  
2 -  
3 -import io.swagger.v3.oas.annotations.media.Schema;  
4 -import lombok.Data;  
5 -import lombok.EqualsAndHashCode;  
6 -import lombok.ToString;  
7 -  
8 -@Schema(description = "管理后台 - 拼团商品更新 Request VO")  
9 -@Data  
10 -@EqualsAndHashCode(callSuper = true)  
11 -@ToString(callSuper = true)  
12 -public class CombinationProductUpdateReqVO extends CombinationProductBaseVO {  
13 -  
14 -}  
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillActivityController.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill; 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 6 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
@@ -8,7 +9,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*; @@ -8,7 +9,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.*;
8 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; 9 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
9 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; 10 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
10 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; 11 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
11 -import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityService; 12 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
12 import io.swagger.v3.oas.annotations.Operation; 13 import io.swagger.v3.oas.annotations.Operation;
13 import io.swagger.v3.oas.annotations.Parameter; 14 import io.swagger.v3.oas.annotations.Parameter;
14 import io.swagger.v3.oas.annotations.tags.Tag; 15 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -19,7 +20,6 @@ import org.springframework.web.bind.annotation.*; @@ -19,7 +20,6 @@ import org.springframework.web.bind.annotation.*;
19 import javax.annotation.Resource; 20 import javax.annotation.Resource;
20 import javax.validation.Valid; 21 import javax.validation.Valid;
21 import java.util.List; 22 import java.util.List;
22 -import java.util.Set;  
23 23
24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
25 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 25 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -33,7 +33,7 @@ public class SeckillActivityController { @@ -33,7 +33,7 @@ public class SeckillActivityController {
33 @Resource 33 @Resource
34 private SeckillActivityService seckillActivityService; 34 private SeckillActivityService seckillActivityService;
35 @Resource 35 @Resource
36 - private ProductSpuApi spuApi; 36 + private ProductSpuApi productSpuApi;
37 37
38 @PostMapping("/create") 38 @PostMapping("/create")
39 @Operation(summary = "创建秒杀活动") 39 @Operation(summary = "创建秒杀活动")
@@ -73,21 +73,27 @@ public class SeckillActivityController { @@ -73,21 +73,27 @@ public class SeckillActivityController {
73 @Parameter(name = "id", description = "编号", required = true, example = "1024") 73 @Parameter(name = "id", description = "编号", required = true, example = "1024")
74 @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") 74 @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
75 public CommonResult<SeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) { 75 public CommonResult<SeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
76 - SeckillActivityDO seckillActivity = seckillActivityService.getSeckillActivity(id);  
77 - List<SeckillProductDO> seckillProducts = seckillActivityService.getSeckillProductListByActivityId(id);  
78 - return success(SeckillActivityConvert.INSTANCE.convert(seckillActivity, seckillProducts)); 76 + SeckillActivityDO activity = seckillActivityService.getSeckillActivity(id);
  77 + List<SeckillProductDO> products = seckillActivityService.getSeckillProductListByActivityId(id);
  78 + return success(SeckillActivityConvert.INSTANCE.convert(activity, products));
79 } 79 }
80 80
81 @GetMapping("/page") 81 @GetMapping("/page")
82 @Operation(summary = "获得秒杀活动分页") 82 @Operation(summary = "获得秒杀活动分页")
83 @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')") 83 @PreAuthorize("@ss.hasPermission('promotion:seckill-activity:query')")
84 public CommonResult<PageResult<SeckillActivityRespVO>> getSeckillActivityPage(@Valid SeckillActivityPageReqVO pageVO) { 84 public CommonResult<PageResult<SeckillActivityRespVO>> getSeckillActivityPage(@Valid SeckillActivityPageReqVO pageVO) {
  85 + // 查询活动列表
85 PageResult<SeckillActivityDO> pageResult = seckillActivityService.getSeckillActivityPage(pageVO); 86 PageResult<SeckillActivityDO> pageResult = seckillActivityService.getSeckillActivityPage(pageVO);
86 - Set<Long> aIds = convertSet(pageResult.getList(), SeckillActivityDO::getId);  
87 - List<SeckillProductDO> seckillProducts = seckillActivityService.getSeckillProductListByActivityId(aIds);  
88 - Set<Long> spuIds = convertSet(pageResult.getList(), SeckillActivityDO::getSpuId);  
89 - List<ProductSpuRespDTO> spuList = spuApi.getSpuList(spuIds);  
90 - return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, seckillProducts, spuList)); 87 + if (CollUtil.isEmpty(pageResult.getList())) {
  88 + return success(PageResult.empty(pageResult.getTotal()));
  89 + }
  90 +
  91 + // 拼接数据
  92 + List<SeckillProductDO> products = seckillActivityService.getSeckillProductListByActivityId(
  93 + convertSet(pageResult.getList(), SeckillActivityDO::getId));
  94 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(
  95 + convertSet(pageResult.getList(), SeckillActivityDO::getSpuId));
  96 + return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, products, spuList));
91 } 97 }
92 98
93 } 99 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/SeckillConfigController.java
@@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -6,7 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.*; 6 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.*;
7 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; 7 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert;
8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
9 -import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigService; 9 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService;
10 import io.swagger.v3.oas.annotations.Operation; 10 import io.swagger.v3.oas.annotations.Operation;
11 import io.swagger.v3.oas.annotations.Parameter; 11 import io.swagger.v3.oas.annotations.Parameter;
12 import io.swagger.v3.oas.annotations.tags.Tag; 12 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -92,4 +92,5 @@ public class SeckillConfigController { @@ -92,4 +92,5 @@ public class SeckillConfigController {
92 PageResult<SeckillConfigDO> pageResult = seckillConfigService.getSeckillConfigPage(pageVO); 92 PageResult<SeckillConfigDO> pageResult = seckillConfigService.getSeckillConfigPage(pageVO);
93 return success(SeckillConfigConvert.INSTANCE.convertPage(pageResult)); 93 return success(SeckillConfigConvert.INSTANCE.convertPage(pageResult));
94 } 94 }
  95 +
95 } 96 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityBaseVO.java
@@ -20,7 +20,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @@ -20,7 +20,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
20 @Data 20 @Data
21 public class SeckillActivityBaseVO { 21 public class SeckillActivityBaseVO {
22 22
23 - @Schema(description = "秒杀活动商品id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]") 23 + @Schema(description = "秒杀活动商品 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "[121,1212]")
24 @NotNull(message = "秒杀活动商品不能为空") 24 @NotNull(message = "秒杀活动商品不能为空")
25 private Long spuId; 25 private Long spuId;
26 26
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityCreateReqVO.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
2 2
3 3
4 -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductCreateReqVO; 4 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
5 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 6 import lombok.Data;
7 import lombok.EqualsAndHashCode; 7 import lombok.EqualsAndHashCode;
@@ -16,6 +16,6 @@ import java.util.List; @@ -16,6 +16,6 @@ import java.util.List;
16 public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO { 16 public class SeckillActivityCreateReqVO extends SeckillActivityBaseVO {
17 17
18 @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED) 18 @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
19 - private List<SeckillProductCreateReqVO> products; 19 + private List<SeckillProductBaseVO> products;
20 20
21 } 21 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityRespVO.java
@@ -21,28 +21,28 @@ public class SeckillActivityRespVO extends SeckillActivityBaseVO { @@ -21,28 +21,28 @@ public class SeckillActivityRespVO extends SeckillActivityBaseVO {
21 @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png") 21 @Schema(description = "商品主图", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xx.png")
22 private String picUrl; 22 private String picUrl;
23 23
24 - @Schema(description = "秒杀活动id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 24 + @Schema(description = "秒杀活动 id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
25 private Long id; 25 private Long id;
26 26
27 @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED) 27 @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
28 private List<SeckillProductRespVO> products; 28 private List<SeckillProductRespVO> products;
29 29
30 - @Schema(description = "活动状态 开启:0 禁用:1", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 30 + @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
31 private Integer status; 31 private Integer status;
32 32
33 @Schema(description = "订单实付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22354") 33 @Schema(description = "订单实付金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "22354")
34 private Integer totalPrice; 34 private Integer totalPrice;
35 35
36 - @Schema(description = "秒杀库存", example = "10") 36 + @Schema(description = "秒杀库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
37 private Integer stock; 37 private Integer stock;
38 38
39 - @Schema(description = "秒杀总库存", example = "20") 39 + @Schema(description = "秒杀总库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
40 private Integer totalStock; 40 private Integer totalStock;
41 41
42 - @Schema(description = "新增订单数", example = "20") 42 + @Schema(description = "新增订单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
43 private Integer orderCount; 43 private Integer orderCount;
44 44
45 - @Schema(description = "付款人数", example = "20") 45 + @Schema(description = "付款人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
46 private Integer userCount; 46 private Integer userCount;
47 47
48 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 48 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/activity/SeckillActivityUpdateReqVO.java
1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity; 1 package cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity;
2 2
3 -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO; 3 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
@@ -18,6 +18,6 @@ public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO { @@ -18,6 +18,6 @@ public class SeckillActivityUpdateReqVO extends SeckillActivityBaseVO {
18 private Long id; 18 private Long id;
19 19
20 @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED) 20 @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
21 - private List<SeckillProductUpdateReqVO> products; 21 + private List<SeckillProductBaseVO> products;
22 22
23 } 23 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductBaseVO.java
@@ -22,7 +22,7 @@ public class SeckillProductBaseVO { @@ -22,7 +22,7 @@ public class SeckillProductBaseVO {
22 @NotNull(message = "秒杀金额,单位:分不能为空") 22 @NotNull(message = "秒杀金额,单位:分不能为空")
23 private Integer seckillPrice; 23 private Integer seckillPrice;
24 24
25 - @Schema(description = "秒杀库存", requiredMode = Schema.RequiredMode.REQUIRED) 25 + @Schema(description = "秒杀库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
26 @NotNull(message = "秒杀库存不能为空") 26 @NotNull(message = "秒杀库存不能为空")
27 private Integer stock; 27 private Integer stock;
28 28
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductCreateReqVO.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.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 -@Schema(description = "管理后台 - 秒杀参与商品创建 Request VO")  
8 -@Data  
9 -@EqualsAndHashCode(callSuper = true)  
10 -@ToString(callSuper = true)  
11 -public class SeckillProductCreateReqVO extends SeckillProductBaseVO {  
12 -  
13 -}  
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/seckill/vo/product/SeckillProductUpdateReqVO.java deleted
1 -package cn.iocoder.yudao.module.promotion.controller.admin.seckill.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 SeckillProductUpdateReqVO extends SeckillProductBaseVO {  
13 -  
14 -}  
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationActivityDO.java
@@ -62,11 +62,11 @@ public class CombinationActivityDO extends BaseDO { @@ -62,11 +62,11 @@ public class CombinationActivityDO extends BaseDO {
62 /** 62 /**
63 * 开团组数 63 * 开团组数
64 */ 64 */
65 - private Integer totalNum; 65 + private Integer totalCount;
66 /** 66 /**
67 * 成团组数 67 * 成团组数
68 */ 68 */
69 - private Integer successNum; 69 + private Integer successCount;
70 /** 70 /**
71 * 参与人数 71 * 参与人数
72 */ 72 */
@@ -76,7 +76,7 @@ public class CombinationActivityDO extends BaseDO { @@ -76,7 +76,7 @@ public class CombinationActivityDO extends BaseDO {
76 */ 76 */
77 private Integer virtualGroup; 77 private Integer virtualGroup;
78 /** 78 /**
79 - * 活动状态:0开启 1关闭 79 + * 活动状态
80 * 80 *
81 * 枚举 {@link CommonStatusEnum} 81 * 枚举 {@link CommonStatusEnum}
82 */ 82 */
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationProductDO.java
@@ -41,6 +41,11 @@ public class CombinationProductDO extends BaseDO { @@ -41,6 +41,11 @@ public class CombinationProductDO extends BaseDO {
41 */ 41 */
42 private Long skuId; 42 private Long skuId;
43 /** 43 /**
  44 + * 拼团价格,单位分
  45 + */
  46 + private Integer combinationPrice;
  47 +
  48 + /**
44 * 拼团商品状态 49 * 拼团商品状态
45 * 50 *
46 * 关联 {@link CombinationActivityDO#getStatus()} 51 * 关联 {@link CombinationActivityDO#getStatus()}
@@ -48,15 +53,15 @@ public class CombinationProductDO extends BaseDO { @@ -48,15 +53,15 @@ public class CombinationProductDO extends BaseDO {
48 private Integer activityStatus; 53 private Integer activityStatus;
49 /** 54 /**
50 * 活动开始时间点 55 * 活动开始时间点
  56 + *
  57 + * 冗余 {@link CombinationActivityDO#getStartTime()}
51 */ 58 */
52 private LocalDateTime activityStartTime; 59 private LocalDateTime activityStartTime;
53 /** 60 /**
54 * 活动结束时间点 61 * 活动结束时间点
  62 + *
  63 + * 冗余 {@link CombinationActivityDO#getEndTime()}
55 */ 64 */
56 private LocalDateTime activityEndTime; 65 private LocalDateTime activityEndTime;
57 - /**  
58 - * 拼团价格,单位分  
59 - */  
60 - private Integer activePrice;  
61 66
62 } 67 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/CombinationProductMapper.java
@@ -26,7 +26,7 @@ public interface CombinationProductMapper extends BaseMapperX&lt;CombinationProduct @@ -26,7 +26,7 @@ public interface CombinationProductMapper extends BaseMapperX&lt;CombinationProduct
26 .eqIfPresent(CombinationProductDO::getActivityStatus, reqVO.getActivityStatus()) 26 .eqIfPresent(CombinationProductDO::getActivityStatus, reqVO.getActivityStatus())
27 .betweenIfPresent(CombinationProductDO::getActivityStartTime, reqVO.getActivityStartTime()) 27 .betweenIfPresent(CombinationProductDO::getActivityStartTime, reqVO.getActivityStartTime())
28 .betweenIfPresent(CombinationProductDO::getActivityEndTime, reqVO.getActivityEndTime()) 28 .betweenIfPresent(CombinationProductDO::getActivityEndTime, reqVO.getActivityEndTime())
29 - .eqIfPresent(CombinationProductDO::getActivePrice, reqVO.getActivePrice()) 29 + .eqIfPresent(CombinationProductDO::getCombinationPrice, reqVO.getActivePrice())
30 .betweenIfPresent(CombinationProductDO::getCreateTime, reqVO.getCreateTime()) 30 .betweenIfPresent(CombinationProductDO::getCreateTime, reqVO.getCreateTime())
31 .orderByDesc(CombinationProductDO::getId)); 31 .orderByDesc(CombinationProductDO::getId));
32 } 32 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
1 package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity; 1 package cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; 4 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
6 -import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;  
7 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
8 6
9 import java.util.Collection; 7 import java.util.Collection;
@@ -25,15 +23,4 @@ public interface SeckillProductMapper extends BaseMapperX&lt;SeckillProductDO&gt; { @@ -25,15 +23,4 @@ public interface SeckillProductMapper extends BaseMapperX&lt;SeckillProductDO&gt; {
25 return selectList(SeckillProductDO::getActivityId, ids); 23 return selectList(SeckillProductDO::getActivityId, ids);
26 } 24 }
27 25
28 - default List<SeckillProductDO> selectListBySkuIds(Collection<Long> skuIds) {  
29 - return selectList(SeckillProductDO::getSkuId, skuIds);  
30 - }  
31 -  
32 - default void updateTimeIdsByActivityId(Long id, List<Long> timeIds) {  
33 - new LambdaUpdateChainWrapper<>(this)  
34 - .set(SeckillProductDO::getConfigIds, CollUtil.join(timeIds, ","))  
35 - .eq(SeckillProductDO::getActivityId, id)  
36 - .update();  
37 - }  
38 -  
39 } 26 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainServiceImpl.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
@@ -41,20 +41,20 @@ public interface CombinationActivityService { @@ -41,20 +41,20 @@ public interface CombinationActivityService {
41 void deleteCombinationActivity(Long id); 41 void deleteCombinationActivity(Long id);
42 42
43 /** 43 /**
44 - * 获得拼团活动 44 + * 校验拼团活动是否存在
45 * 45 *
46 * @param id 编号 46 * @param id 编号
47 * @return 拼团活动 47 * @return 拼团活动
48 */ 48 */
49 - CombinationActivityDO getCombinationActivity(Long id); 49 + CombinationActivityDO validateCombinationActivityExists(Long id);
50 50
51 /** 51 /**
52 - * 获得拼团活动列表 52 + * 获得拼团活动
53 * 53 *
54 - * @param ids 编号  
55 - * @return 拼团活动列表 54 + * @param id 编号
  55 + * @return 拼团活动
56 */ 56 */
57 - List<CombinationActivityDO> getCombinationActivityList(Collection<Long> ids); 57 + CombinationActivityDO getCombinationActivity(Long id);
58 58
59 /** 59 /**
60 * 获得拼团活动分页 60 * 获得拼团活动分页
@@ -67,9 +67,9 @@ public interface CombinationActivityService { @@ -67,9 +67,9 @@ public interface CombinationActivityService {
67 /** 67 /**
68 * 获得拼团活动商品列表 68 * 获得拼团活动商品列表
69 * 69 *
70 - * @param ids 拼团活动 ids 70 + * @param activityIds 拼团活动 ids
71 * @return 拼团活动的商品列表 71 * @return 拼团活动的商品列表
72 */ 72 */
73 - List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> ids); 73 + List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> activityIds);
74 74
75 } 75 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.combination;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  8 +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
  9 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
  10 +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  11 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
  12 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
  13 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
  14 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
  15 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
  16 +import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
  17 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
  18 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationProductDO;
  19 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationActivityMapper;
  20 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationProductMapper;
  21 +import org.springframework.stereotype.Service;
  22 +import org.springframework.transaction.annotation.Transactional;
  23 +import org.springframework.validation.annotation.Validated;
  24 +
  25 +import javax.annotation.Resource;
  26 +import java.util.Collection;
  27 +import java.util.List;
  28 +import java.util.Map;
  29 +
  30 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  32 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
  33 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
  34 +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
  35 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
  36 +import static java.util.Collections.singletonList;
  37 +
  38 +/**
  39 + * 拼团活动 Service 实现类
  40 + *
  41 + * @author HUIHUI
  42 + */
  43 +@Service
  44 +@Validated
  45 +public class CombinationActivityServiceImpl implements CombinationActivityService {
  46 +
  47 + @Resource
  48 + private CombinationActivityMapper combinationActivityMapper;
  49 + @Resource
  50 + private CombinationProductMapper combinationProductMapper;
  51 +
  52 + @Resource
  53 + private ProductSpuApi productSpuApi;
  54 + @Resource
  55 + private ProductSkuApi productSkuApi;
  56 +
  57 + @Override
  58 + @Transactional(rollbackFor = Exception.class)
  59 + public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) {
  60 + // 校验商品 SPU 是否存在是否参加的别的活动
  61 + validateProductConflict(createReqVO.getSpuId(), null);
  62 + // 校验商品是否存在
  63 + validateProductExists(createReqVO.getSpuId(), createReqVO.getProducts());
  64 +
  65 + // 插入拼团活动
  66 + CombinationActivityDO activity = CombinationActivityConvert.INSTANCE.convert(createReqVO)
  67 + .setStatus(CommonStatusEnum.ENABLE.getStatus())
  68 + .setTotalCount(0).setSuccessCount(0).setOrderUserCount(0).setVirtualGroup(0);
  69 + combinationActivityMapper.insert(activity);
  70 + // 插入商品
  71 + List<CombinationProductDO> products = CombinationActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activity);
  72 + combinationProductMapper.insertBatch(products);
  73 + // 返回
  74 + return activity.getId();
  75 + }
  76 +
  77 + /**
  78 + * 校验拼团商品参与的活动是否存在冲突
  79 + *
  80 + * @param spuId 商品 SPU 编号
  81 + * @param activityId 拼团活动编号
  82 + */
  83 + private void validateProductConflict(Long spuId, Long activityId) {
  84 + // 查询所有开启的拼团活动
  85 + List<CombinationActivityDO> activityList = combinationActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
  86 + if (activityId != null) { // 时排除自己
  87 + activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
  88 + }
  89 + // 查找是否有其它活动,选择了该产品
  90 + List<CombinationActivityDO> matchActivityList = filterList(activityList, activity -> ObjectUtil.equal(activity.getId(), spuId));
  91 + if (CollUtil.isNotEmpty(matchActivityList)) {
  92 + throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS);
  93 + }
  94 + }
  95 +
  96 + /**
  97 + * 校验拼团商品是否都存在
  98 + *
  99 + * @param spuId 商品 SPU 编号
  100 + * @param products 秒杀商品
  101 + */
  102 + private void validateProductExists(Long spuId, List<CombinationProductBaseVO> products) {
  103 + // 1. 校验商品 spu 是否存在
  104 + ProductSpuRespDTO spu = productSpuApi.getSpu(spuId);
  105 + if (spu == null) {
  106 + throw exception(SPU_NOT_EXISTS);
  107 + }
  108 +
  109 + // 2. 校验商品 sku 都存在
  110 + Map<Long, ProductSkuRespDTO> skuMap = convertMap(productSkuApi.getSkuListBySpuId(singletonList(spuId)),
  111 + ProductSkuRespDTO::getId);
  112 + products.forEach(product -> {
  113 + if (!skuMap.containsKey(product.getSkuId())) {
  114 + throw exception(SKU_NOT_EXISTS);
  115 + }
  116 + });
  117 + }
  118 +
  119 + @Override
  120 + @Transactional(rollbackFor = Exception.class)
  121 + public void updateCombinationActivity(CombinationActivityUpdateReqVO updateReqVO) {
  122 + // 校验存在
  123 + CombinationActivityDO activityDO = validateCombinationActivityExists(updateReqVO.getId());
  124 + // 校验状态
  125 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  126 + throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
  127 + }
  128 + // 校验商品冲突
  129 + validateProductConflict(updateReqVO.getSpuId(), updateReqVO.getId());
  130 + // 校验商品是否存在
  131 + validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts());
  132 +
  133 + // 更新活动
  134 + CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO);
  135 + combinationActivityMapper.updateById(updateObj);
  136 + // 更新商品
  137 + updateCombinationProduct(updateObj, updateReqVO.getProducts());
  138 + }
  139 +
  140 + /**
  141 + * 更新拼团商品
  142 + *
  143 + * @param activity 拼团活动
  144 + * @param products 该活动的最新商品配置
  145 + */
  146 + private void updateCombinationProduct(CombinationActivityDO activity, List<CombinationProductBaseVO> products) {
  147 + // 第一步,对比新老数据,获得添加、修改、删除的列表
  148 + List<CombinationProductDO> newList = CombinationActivityConvert.INSTANCE.convertList(products, activity);
  149 + List<CombinationProductDO> oldList = combinationProductMapper.selectListByActivityIds(CollUtil.newArrayList(activity.getId()));
  150 + List<List<CombinationProductDO>> diffList = CollectionUtils.diffList(oldList, newList, (oldVal, newVal) -> {
  151 + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId());
  152 + if (same) {
  153 + newVal.setId(oldVal.getId());
  154 + }
  155 + return same;
  156 + });
  157 +
  158 + // 第二步,批量添加、修改、删除
  159 + if (CollUtil.isNotEmpty(diffList.get(0))) {
  160 + combinationProductMapper.insertBatch(diffList.get(0));
  161 + }
  162 + if (CollUtil.isNotEmpty(diffList.get(1))) {
  163 + combinationProductMapper.updateBatch(diffList.get(1));
  164 + }
  165 + if (CollUtil.isNotEmpty(diffList.get(2))) {
  166 + combinationProductMapper.deleteBatchIds(CollectionUtils.convertList(diffList.get(2), CombinationProductDO::getId));
  167 + }
  168 + }
  169 +
  170 + @Override
  171 + @Transactional(rollbackFor = Exception.class)
  172 + public void deleteCombinationActivity(Long id) {
  173 + // 校验存在
  174 + CombinationActivityDO activityDO = validateCombinationActivityExists(id);
  175 + // 校验状态
  176 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  177 + throw exception(COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
  178 + }
  179 +
  180 + // 删除
  181 + combinationActivityMapper.deleteById(id);
  182 + }
  183 +
  184 + @Override
  185 + public CombinationActivityDO validateCombinationActivityExists(Long id) {
  186 + CombinationActivityDO activityDO = combinationActivityMapper.selectById(id);
  187 + if (activityDO == null) {
  188 + throw exception(COMBINATION_ACTIVITY_NOT_EXISTS);
  189 + }
  190 + return activityDO;
  191 + }
  192 +
  193 + @Override
  194 + public CombinationActivityDO getCombinationActivity(Long id) {
  195 + return validateCombinationActivityExists(id);
  196 + }
  197 +
  198 + @Override
  199 + public PageResult<CombinationActivityDO> getCombinationActivityPage(CombinationActivityPageReqVO pageReqVO) {
  200 + return combinationActivityMapper.selectPage(pageReqVO);
  201 + }
  202 +
  203 + @Override
  204 + public List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> activityIds) {
  205 + return combinationProductMapper.selectListByActivityIds(activityIds);
  206 + }
  207 +
  208 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationR @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationR
7 import java.util.List; 7 import java.util.List;
8 8
9 /** 9 /**
10 - * 商品活动记录 service 10 + * 拼团记录 Service 接口
11 * 11 *
12 * @author HUIHUI 12 * @author HUIHUI
13 */ 13 */
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.service.combination;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
  6 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
  7 +import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
  9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
  10 +import cn.iocoder.yudao.module.promotion.dal.mysql.combination.CombinationRecordMapper;
  11 +import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
  12 +import org.springframework.stereotype.Service;
  13 +import org.springframework.transaction.annotation.Transactional;
  14 +import org.springframework.validation.annotation.Validated;
  15 +
  16 +import javax.annotation.Resource;
  17 +import java.util.List;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  20 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
  21 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_RECORD_USER_FULL;
  22 +
  23 +// TODO 芋艿:等拼团记录做完,完整 review 下
  24 +/**
  25 + * 拼团记录 Service 实现类
  26 + *
  27 + * @author HUIHUI
  28 + */
  29 +@Service
  30 +@Validated
  31 +public class CombinationRecordServiceImpl implements CombinationRecordService {
  32 +
  33 + @Resource
  34 + private CombinationActivityService combinationActivityService;
  35 +
  36 + @Resource
  37 + private CombinationRecordMapper recordMapper;
  38 +
  39 + @Override
  40 + public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) {
  41 + // 校验拼团是否存在
  42 + CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
  43 +
  44 + // 更新状态
  45 + recordDO.setStatus(reqDTO.getStatus());
  46 + recordMapper.updateById(recordDO);
  47 + }
  48 +
  49 + @Override
  50 + @Transactional(rollbackFor = Exception.class)
  51 + public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) {
  52 + CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
  53 + // 更新状态
  54 + recordDO.setStatus(reqDTO.getStatus());
  55 + // 更新开始时间
  56 + recordDO.setStartTime(reqDTO.getStartTime());
  57 + recordMapper.updateById(recordDO);
  58 +
  59 + // 更新拼团参入人数
  60 + List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), reqDTO.getStatus());
  61 + if (CollUtil.isNotEmpty(recordDOs)) {
  62 + recordDOs.forEach(item -> {
  63 + item.setUserCount(recordDOs.size());
  64 + // 校验拼团是否满足要求
  65 + if (ObjectUtil.equal(recordDOs.size(), recordDO.getUserSize())) {
  66 + item.setStatus(CombinationRecordStatusEnum.SUCCESS.getStatus());
  67 + }
  68 + });
  69 + }
  70 + recordMapper.updateBatch(recordDOs);
  71 + }
  72 +
  73 + private CombinationRecordDO validateCombinationRecord(Long userId, Long orderId) {
  74 + // 校验拼团是否存在
  75 + CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(userId, orderId);
  76 + if (recordDO == null) {
  77 + throw exception(COMBINATION_RECORD_NOT_EXISTS);
  78 + }
  79 + return recordDO;
  80 + }
  81 +
  82 + @Override
  83 + public void createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
  84 + // 1.1 校验拼团活动
  85 + CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(reqDTO.getActivityId());
  86 + // 1.2 需要校验下,他当前是不是已经参加了该拼团;
  87 + CombinationRecordDO recordDO = recordMapper.selectByUserIdAndOrderId(reqDTO.getUserId(), reqDTO.getOrderId());
  88 + if (recordDO != null) {
  89 + throw exception(COMBINATION_RECORD_EXISTS);
  90 + }
  91 + // 1.3 父拼团是否存在,是否已经满了
  92 + if (reqDTO.getHeadId() != null) {
  93 + CombinationRecordDO recordDO1 = recordMapper.selectRecordByHeadId(reqDTO.getHeadId(), reqDTO.getActivityId(), CombinationRecordStatusEnum.IN_PROGRESS.getStatus());
  94 + if (recordDO1 == null) {
  95 + throw exception(COMBINATION_RECORD_HEAD_NOT_EXISTS);
  96 + }
  97 + // 校验拼团是否满足要求
  98 + if (ObjectUtil.equal(recordDO1.getUserCount(), recordDO1.getUserSize())) {
  99 + throw exception(COMBINATION_RECORD_USER_FULL);
  100 + }
  101 + }
  102 + // TODO @puhui999:应该还有一些校验,后续补噶;例如说,一个团,自己已经参与进去了,不能再参与进去;
  103 +
  104 + // 2. 创建拼团记录
  105 + CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
  106 + record.setVirtualGroup(false);
  107 + // TODO @puhui999:过期时间,应该是 Date 哈;
  108 + record.setExpireTime(activity.getLimitDuration());
  109 + record.setUserSize(activity.getUserSize());
  110 + recordMapper.insert(record);
  111 + }
  112 +
  113 + @Override
  114 + public CombinationRecordDO getCombinationRecord(Long userId, Long orderId) {
  115 + return validateCombinationRecord(userId, orderId);
  116 + }
  117 +
  118 + /**
  119 + * APP 端获取开团记录
  120 + *
  121 + * @return 开团记录
  122 + */
  123 + public List<CombinationRecordDO> getRecordListByStatus(Integer status) {
  124 + return recordMapper.selectListByStatus(status);
  125 + }
  126 +
  127 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityService.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
1 -package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity; 1 +package cn.iocoder.yudao.module.promotion.service.seckill;
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.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; 4 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
@@ -56,14 +56,6 @@ public interface SeckillActivityService { @@ -56,14 +56,6 @@ public interface SeckillActivityService {
56 SeckillActivityDO getSeckillActivity(Long id); 56 SeckillActivityDO getSeckillActivity(Long id);
57 57
58 /** 58 /**
59 - * 获得秒杀活动列表  
60 - *  
61 - * @param ids 编号  
62 - * @return 秒杀活动列表  
63 - */  
64 - List<SeckillActivityDO> getSeckillActivityList(Collection<Long> ids);  
65 -  
66 - /**  
67 * 获得秒杀活动分页 59 * 获得秒杀活动分页
68 * 60 *
69 * @param pageReqVO 分页查询 61 * @param pageReqVO 分页查询
@@ -74,17 +66,17 @@ public interface SeckillActivityService { @@ -74,17 +66,17 @@ public interface SeckillActivityService {
74 /** 66 /**
75 * 通过活动编号获取活动商品 67 * 通过活动编号获取活动商品
76 * 68 *
77 - * @param id 活动编号 69 + * @param activityId 活动编号
78 * @return 活动商品列表 70 * @return 活动商品列表
79 */ 71 */
80 - List<SeckillProductDO> getSeckillProductListByActivityId(Long id); 72 + List<SeckillProductDO> getSeckillProductListByActivityId(Long activityId);
81 73
82 /** 74 /**
83 * 通过活动编号获取活动商品 75 * 通过活动编号获取活动商品
84 * 76 *
85 - * @param ids 活动编号 77 + * @param activityIds 活动编号
86 * @return 活动商品列表 78 * @return 活动商品列表
87 */ 79 */
88 - List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> ids); 80 + List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds);
89 81
90 } 82 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillactivity/SeckillActivityServiceImpl.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
1 -package cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity; 1 +package cn.iocoder.yudao.module.promotion.service.seckill;
2 2
3 -import cn.hutool.core.collection.CollUtil;  
4 import cn.hutool.core.util.ObjectUtil; 3 import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -11,14 +10,12 @@ import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; @@ -11,14 +10,12 @@ import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; 10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; 11 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
13 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; 12 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
14 -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductCreateReqVO;  
15 -import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductUpdateReqVO; 13 +import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO;
16 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; 14 import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert;
17 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; 15 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
18 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; 16 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
19 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; 17 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
20 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper; 18 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillProductMapper;
21 -import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigService;  
22 import cn.iocoder.yudao.module.promotion.util.PromotionUtils; 19 import cn.iocoder.yudao.module.promotion.util.PromotionUtils;
23 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
24 import org.springframework.transaction.annotation.Transactional; 21 import org.springframework.transaction.annotation.Transactional;
@@ -27,7 +24,7 @@ import org.springframework.validation.annotation.Validated; @@ -27,7 +24,7 @@ import org.springframework.validation.annotation.Validated;
27 import javax.annotation.Resource; 24 import javax.annotation.Resource;
28 import java.util.Collection; 25 import java.util.Collection;
29 import java.util.List; 26 import java.util.List;
30 -import java.util.Set; 27 +import java.util.Map;
31 28
32 import static cn.hutool.core.collection.CollUtil.isNotEmpty; 29 import static cn.hutool.core.collection.CollUtil.isNotEmpty;
33 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -35,7 +32,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @@ -35,7 +32,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
35 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; 32 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
36 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; 33 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
37 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; 34 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
38 -import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuAllExists; 35 +import static java.util.Collections.singletonList;
39 36
40 /** 37 /**
41 * 秒杀活动 Service 实现类 38 * 秒杀活动 Service 实现类
@@ -60,19 +57,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -60,19 +57,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
60 @Override 57 @Override
61 @Transactional(rollbackFor = Exception.class) 58 @Transactional(rollbackFor = Exception.class)
62 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) { 59 public Long createSeckillActivity(SeckillActivityCreateReqVO createReqVO) {
63 - // 校验商品秒秒杀时段是否冲突  
64 - validateProductSpuSeckillConflict(createReqVO.getConfigIds(), createReqVO.getSpuId(), null);  
65 - // 获取所选 spu 下的所有 sku  
66 - List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(createReqVO.getSpuId()));  
67 - // 校验商品 sku 是否存在  
68 - if (skus.size() != createReqVO.getProducts().size()) {  
69 - throw exception(SKU_NOT_EXISTS);  
70 - } 60 + // 校验商品秒杀时段是否冲突
  61 + validateProductConflict(createReqVO.getConfigIds(), createReqVO.getSpuId(), null);
  62 + // 校验商品是否存在
  63 + validateProductExists(createReqVO.getSpuId(), createReqVO.getProducts());
71 64
72 // 插入秒杀活动 65 // 插入秒杀活动
73 SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO) 66 SeckillActivityDO activity = SeckillActivityConvert.INSTANCE.convert(createReqVO)
74 .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime())) 67 .setStatus(PromotionUtils.calculateActivityStatus(createReqVO.getEndTime()))
75 - .setTotalStock(getSumValue(createReqVO.getProducts(), SeckillProductCreateReqVO::getStock, Integer::sum)); 68 + .setTotalStock(getSumValue(createReqVO.getProducts(), SeckillProductBaseVO::getStock, Integer::sum));
76 seckillActivityMapper.insert(activity); 69 seckillActivityMapper.insert(activity);
77 // 插入商品 70 // 插入商品
78 List<SeckillProductDO> products = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activity); 71 List<SeckillProductDO> products = SeckillActivityConvert.INSTANCE.convertList(createReqVO.getProducts(), activity);
@@ -80,35 +73,61 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -80,35 +73,61 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
80 return activity.getId(); 73 return activity.getId();
81 } 74 }
82 75
83 - private void validateProductSpuSeckillConflict(List<Long> configIds, Long spuId, Long activityId) {  
84 - // 校验秒杀时段是否存在 76 + /**
  77 + * 校验秒杀商品参与的活动是否存在冲突
  78 + *
  79 + * 1. 校验秒杀时段是否存在
  80 + * 2. 秒杀商品是否参加其它活动
  81 + *
  82 + * @param configIds 秒杀时段数组
  83 + * @param spuId 商品 SPU 编号
  84 + * @param activityId 秒杀活动编号
  85 + */
  86 + private void validateProductConflict(List<Long> configIds, Long spuId, Long activityId) {
  87 + // 1. 校验秒杀时段是否存在
85 seckillConfigService.validateSeckillConfigExists(configIds); 88 seckillConfigService.validateSeckillConfigExists(configIds);
86 - // 校验商品 spu 是否存在  
87 - List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));  
88 - if (CollUtil.isEmpty(spuList)) {  
89 - throw exception(SPU_NOT_EXISTS);  
90 - }  
91 - // 查询所有开启的秒杀活动  
92 - List<SeckillActivityDO> activityDOs = seckillActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());  
93 - if (activityId != null) {  
94 - // 更新时移除本活动  
95 - activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId)); 89 +
  90 + // 2.1 查询所有开启的秒杀活动
  91 + List<SeckillActivityDO> activityList = seckillActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
  92 + if (activityId != null) { // 排除自己
  93 + activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
96 } 94 }
97 - // 过滤出所有 spuId 有交集的活动  
98 - List<SeckillActivityDO> activityDOs1 = convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getSpuId(), spuId)); 95 + // TODO @puhui999:一个 spu,参与两个活动应该没关系,关键是活动时间不充能重叠;
  96 + // 2.2 过滤出所有 spuId 有交集的活动,判断是否存在重叠
  97 + List<SeckillActivityDO> activityDOs1 = filterList(activityList, s -> ObjectUtil.equal(s.getSpuId(), spuId));
99 if (isNotEmpty(activityDOs1)) { 98 if (isNotEmpty(activityDOs1)) {
100 throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); 99 throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
101 } 100 }
102 - List<SeckillActivityDO> activityDOs2 = convertList(activityDOs, c -> c, s -> {  
103 - // 判断秒杀时段是否有交集  
104 - return containsAny(s.getConfigIds(), configIds);  
105 - });  
106 - 101 + // 2.3 过滤出所有 configIds 有交集的活动,判断是否存在重叠
  102 + List<SeckillActivityDO> activityDOs2 = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds));
107 if (isNotEmpty(activityDOs2)) { 103 if (isNotEmpty(activityDOs2)) {
108 - throw exception(SECKILL_TIME_CONFLICTS); 104 + throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
109 } 105 }
110 } 106 }
111 107
  108 + /**
  109 + * 校验秒杀商品是否都存在
  110 + *
  111 + * @param spuId 商品 SPU 编号
  112 + * @param products 秒杀商品
  113 + */
  114 + private void validateProductExists(Long spuId, List<SeckillProductBaseVO> products) {
  115 + // 1. 校验商品 spu 是否存在
  116 + ProductSpuRespDTO spu = productSpuApi.getSpu(spuId);
  117 + if (spu == null) {
  118 + throw exception(SPU_NOT_EXISTS);
  119 + }
  120 +
  121 + // 2. 校验商品 sku 都存在
  122 + Map<Long, ProductSkuRespDTO> skuMap = convertMap(productSkuApi.getSkuListBySpuId(singletonList(spuId)),
  123 + ProductSkuRespDTO::getId);
  124 + products.forEach(product -> {
  125 + if (!skuMap.containsKey(product.getSkuId())) {
  126 + throw exception(SKU_NOT_EXISTS);
  127 + }
  128 + });
  129 + }
  130 +
112 @Override 131 @Override
113 @Transactional(rollbackFor = Exception.class) 132 @Transactional(rollbackFor = Exception.class)
114 public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) { 133 public void updateSeckillActivity(SeckillActivityUpdateReqVO updateReqVO) {
@@ -118,29 +137,26 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -118,29 +137,26 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
118 throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED); 137 throw exception(SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
119 } 138 }
120 // 校验商品是否冲突 139 // 校验商品是否冲突
121 - validateProductSpuSeckillConflict(updateReqVO.getConfigIds(), updateReqVO.getSpuId(), updateReqVO.getId());  
122 - // 获取所选 spu下的所有 sku  
123 - List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollUtil.newArrayList(updateReqVO.getSpuId()));  
124 - // 校验商品 sku 是否存在  
125 - validateProductSkuAllExists(skus, updateReqVO.getProducts(), SeckillProductUpdateReqVO::getSkuId); 140 + validateProductConflict(updateReqVO.getConfigIds(), updateReqVO.getSpuId(), updateReqVO.getId());
  141 + // 校验商品是否存在
  142 + validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts());
126 143
127 // 更新活动 144 // 更新活动
128 SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO) 145 SeckillActivityDO updateObj = SeckillActivityConvert.INSTANCE.convert(updateReqVO)
129 .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime())) 146 .setStatus(PromotionUtils.calculateActivityStatus(updateReqVO.getEndTime()))
130 - .setTotalStock(getSumValue(updateReqVO.getProducts(), SeckillProductUpdateReqVO::getStock, Integer::sum)); 147 + .setTotalStock(getSumValue(updateReqVO.getProducts(), SeckillProductBaseVO::getStock, Integer::sum));
131 seckillActivityMapper.updateById(updateObj); 148 seckillActivityMapper.updateById(updateObj);
132 // 更新商品 149 // 更新商品
133 updateSeckillProduct(updateObj, updateReqVO.getProducts()); 150 updateSeckillProduct(updateObj, updateReqVO.getProducts());
134 } 151 }
135 152
136 -  
137 /** 153 /**
138 * 更新秒杀商品 154 * 更新秒杀商品
139 * 155 *
140 * @param activity 秒杀活动 156 * @param activity 秒杀活动
141 * @param products 该活动的最新商品配置 157 * @param products 该活动的最新商品配置
142 */ 158 */
143 - private void updateSeckillProduct(SeckillActivityDO activity, List<SeckillProductUpdateReqVO> products) { 159 + private void updateSeckillProduct(SeckillActivityDO activity, List<SeckillProductBaseVO> products) {
144 // 第一步,对比新老数据,获得添加、修改、删除的列表 160 // 第一步,对比新老数据,获得添加、修改、删除的列表
145 List<SeckillProductDO> newList = SeckillActivityConvert.INSTANCE.convertList(products, activity); 161 List<SeckillProductDO> newList = SeckillActivityConvert.INSTANCE.convertList(products, activity);
146 List<SeckillProductDO> oldList = seckillProductMapper.selectListByActivityId(activity.getId()); 162 List<SeckillProductDO> oldList = seckillProductMapper.selectListByActivityId(activity.getId());
@@ -159,7 +175,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -159,7 +175,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
159 if (isNotEmpty(diffList.get(1))) { 175 if (isNotEmpty(diffList.get(1))) {
160 seckillProductMapper.updateBatch(diffList.get(1)); 176 seckillProductMapper.updateBatch(diffList.get(1));
161 } 177 }
162 - // delete  
163 if (isNotEmpty(diffList.get(2))) { 178 if (isNotEmpty(diffList.get(2))) {
164 seckillProductMapper.deleteBatchIds(convertList(diffList.get(2), SeckillProductDO::getId)); 179 seckillProductMapper.deleteBatchIds(convertList(diffList.get(2), SeckillProductDO::getId));
165 } 180 }
@@ -167,7 +182,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -167,7 +182,6 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
167 182
168 @Override 183 @Override
169 public void closeSeckillActivity(Long id) { 184 public void closeSeckillActivity(Long id) {
170 - // TODO 待验证没使用过  
171 // 校验存在 185 // 校验存在
172 SeckillActivityDO activity = validateSeckillActivityExists(id); 186 SeckillActivityDO activity = validateSeckillActivityExists(id);
173 if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) { 187 if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) {
@@ -191,9 +205,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -191,9 +205,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
191 // 删除活动 205 // 删除活动
192 seckillActivityMapper.deleteById(id); 206 seckillActivityMapper.deleteById(id);
193 // 删除活动商品 207 // 删除活动商品
194 - List<SeckillProductDO> productDOs = seckillProductMapper.selectListByActivityId(id);  
195 - Set<Long> convertSet = convertSet(productDOs, SeckillProductDO::getSkuId);  
196 - seckillProductMapper.deleteBatchIds(convertSet); 208 + List<SeckillProductDO> products = seckillProductMapper.selectListByActivityId(id);
  209 + seckillProductMapper.deleteBatchIds(convertSet(products, SeckillProductDO::getId));
197 } 210 }
198 211
199 private SeckillActivityDO validateSeckillActivityExists(Long id) { 212 private SeckillActivityDO validateSeckillActivityExists(Long id) {
@@ -210,23 +223,18 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { @@ -210,23 +223,18 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
210 } 223 }
211 224
212 @Override 225 @Override
213 - public List<SeckillActivityDO> getSeckillActivityList(Collection<Long> ids) {  
214 - return seckillActivityMapper.selectBatchIds(ids);  
215 - }  
216 -  
217 - @Override  
218 public PageResult<SeckillActivityDO> getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO) { 226 public PageResult<SeckillActivityDO> getSeckillActivityPage(SeckillActivityPageReqVO pageReqVO) {
219 return seckillActivityMapper.selectPage(pageReqVO); 227 return seckillActivityMapper.selectPage(pageReqVO);
220 } 228 }
221 229
222 @Override 230 @Override
223 - public List<SeckillProductDO> getSeckillProductListByActivityId(Long id) {  
224 - return seckillProductMapper.selectListByActivityId(id); 231 + public List<SeckillProductDO> getSeckillProductListByActivityId(Long activityId) {
  232 + return seckillProductMapper.selectListByActivityId(activityId);
225 } 233 }
226 234
227 @Override 235 @Override
228 - public List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> ids) {  
229 - return seckillProductMapper.selectListByActivityId(ids); 236 + public List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds) {
  237 + return seckillProductMapper.selectListByActivityId(activityIds);
230 } 238 }
231 239
232 } 240 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigService.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigService.java
1 -package cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig; 1 +package cn.iocoder.yudao.module.promotion.service.seckill;
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.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO; 4 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
@@ -57,10 +57,9 @@ public interface SeckillConfigService { @@ -57,10 +57,9 @@ public interface SeckillConfigService {
57 /** 57 /**
58 * 校验秒杀时段是否存在 58 * 校验秒杀时段是否存在
59 * 59 *
60 - * @param timeIds 秒杀时段id集合 60 + * @param ids 秒杀时段 id 集合
61 */ 61 */
62 - void validateSeckillConfigExists(Collection<Long> timeIds);  
63 - 62 + void validateSeckillConfigExists(Collection<Long> ids);
64 63
65 /** 64 /**
66 * 获得秒杀时间段配置分页数据 65 * 获得秒杀时间段配置分页数据
@@ -85,4 +84,5 @@ public interface SeckillConfigService { @@ -85,4 +84,5 @@ public interface SeckillConfigService {
85 * @param status 状态 84 * @param status 状态
86 */ 85 */
87 void updateSeckillConfigStatus(Long id, Integer status); 86 void updateSeckillConfigStatus(Long id, Integer status);
  87 +
88 } 88 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/seckillconfig/SeckillConfigServiceImpl.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillConfigServiceImpl.java
1 -package cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig; 1 +package cn.iocoder.yudao.module.promotion.service.seckill;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
8 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; 7 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO; 8 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
10 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO; 9 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
@@ -13,7 +12,6 @@ import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillCo @@ -13,7 +12,6 @@ import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillCo
13 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; 12 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
14 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper; 13 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
15 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
16 -import org.springframework.transaction.annotation.Transactional;  
17 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
18 16
19 import javax.annotation.Resource; 17 import javax.annotation.Resource;
@@ -37,7 +35,6 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { @@ -37,7 +35,6 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
37 private SeckillConfigMapper seckillConfigMapper; 35 private SeckillConfigMapper seckillConfigMapper;
38 36
39 @Override 37 @Override
40 - @Transactional(rollbackFor = Exception.class)  
41 public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) { 38 public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) {
42 // 校验时间段是否冲突 39 // 校验时间段是否冲突
43 validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime(), null); 40 validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime(), null);
@@ -50,7 +47,6 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { @@ -50,7 +47,6 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
50 } 47 }
51 48
52 @Override 49 @Override
53 - @Transactional(rollbackFor = Exception.class)  
54 public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) { 50 public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) {
55 // 校验存在 51 // 校验存在
56 validateSeckillConfigExists(updateReqVO.getId()); 52 validateSeckillConfigExists(updateReqVO.getId());
@@ -72,7 +68,6 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { @@ -72,7 +68,6 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
72 } 68 }
73 69
74 @Override 70 @Override
75 - @Transactional(rollbackFor = Exception.class)  
76 public void deleteSeckillConfig(Long id) { 71 public void deleteSeckillConfig(Long id) {
77 // 校验存在 72 // 校验存在
78 validateSeckillConfigExists(id); 73 validateSeckillConfigExists(id);
@@ -83,35 +78,31 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { @@ -83,35 +78,31 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
83 78
84 private void validateSeckillConfigExists(Long id) { 79 private void validateSeckillConfigExists(Long id) {
85 if (seckillConfigMapper.selectById(id) == null) { 80 if (seckillConfigMapper.selectById(id) == null) {
86 - throw exception(SECKILL_TIME_NOT_EXISTS); 81 + throw exception(SECKILL_CONFIG_NOT_EXISTS);
87 } 82 }
88 } 83 }
89 84
90 /** 85 /**
91 * 校验时间是否存在冲突 86 * 校验时间是否存在冲突
92 * 87 *
93 - * @param startTime 开始时间  
94 - * @param endTime 结束时间 88 + * @param startTimeStr 开始时间
  89 + * @param endTimeStr 结束时间
95 */ 90 */
96 - private void validateSeckillConfigConflict(String startTime, String endTime, Long seckillConfigId) {  
97 - LocalTime startTime1 = LocalTime.parse(startTime);  
98 - LocalTime endTime1 = LocalTime.parse(endTime);  
99 - // 查询出所有的时段配置  
100 - List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList(); 91 + private void validateSeckillConfigConflict(String startTimeStr, String endTimeStr, Long id) {
  92 + // 1. 查询出所有的时段配置
  93 + LocalTime startTime = LocalTime.parse(startTimeStr);
  94 + LocalTime endTime = LocalTime.parse(endTimeStr);
  95 + List<SeckillConfigDO> configs = seckillConfigMapper.selectList();
101 // 更新时排除自己 96 // 更新时排除自己
102 - if (seckillConfigId != null) {  
103 - configDOs.removeIf(item -> ObjectUtil.equal(item.getId(), seckillConfigId)); 97 + if (id != null) {
  98 + configs.removeIf(item -> ObjectUtil.equal(item.getId(), id));
104 } 99 }
105 - // 过滤出重叠的时段 ids  
106 - boolean hasConflict = configDOs.stream().anyMatch(config -> {  
107 - LocalTime startTime2 = LocalTime.parse(config.getStartTime());  
108 - LocalTime endTime2 = LocalTime.parse(config.getEndTime());  
109 - // 判断时间是否重叠  
110 - return LocalDateTimeUtils.isOverlap(startTime1, endTime1, startTime2, endTime2);  
111 - });  
112 100
  101 + // 2. 判断是否有重叠的时间
  102 + boolean hasConflict = configs.stream().anyMatch(config -> LocalDateTimeUtils.isOverlap(startTime, endTime,
  103 + LocalTime.parse(config.getStartTime()), LocalTime.parse(config.getEndTime())));
113 if (hasConflict) { 104 if (hasConflict) {
114 - throw exception(SECKILL_TIME_CONFLICTS); 105 + throw exception(SECKILL_CONFIG_TIME_CONFLICTS);
115 } 106 }
116 } 107 }
117 108
@@ -127,22 +118,22 @@ public class SeckillConfigServiceImpl implements SeckillConfigService { @@ -127,22 +118,22 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
127 } 118 }
128 119
129 @Override 120 @Override
130 - public void validateSeckillConfigExists(Collection<Long> configIds) {  
131 - if (CollUtil.isEmpty(configIds)) {  
132 - throw exception(SECKILL_TIME_NOT_EXISTS);  
133 - }  
134 - List<SeckillConfigDO> configDOs = seckillConfigMapper.selectBatchIds(configIds);  
135 - if (CollUtil.isEmpty(configDOs)) {  
136 - throw exception(SECKILL_TIME_NOT_EXISTS);  
137 - }  
138 - // 过滤出关闭的时段  
139 - List<SeckillConfigDO> filterList = CollectionUtils.filterList(configDOs, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.DISABLE.getStatus()));  
140 - if (CollUtil.isNotEmpty(filterList)) {  
141 - throw exception(SECKILL_TIME_DISABLE); 121 + public void validateSeckillConfigExists(Collection<Long> ids) {
  122 + if (CollUtil.isEmpty(ids)) {
  123 + return;
142 } 124 }
143 - if (configDOs.size() != configIds.size()) {  
144 - throw exception(SECKILL_TIME_NOT_EXISTS); 125 + // 1. 如果有数量不匹配,说明有不存在的,则抛出 SECKILL_CONFIG_NOT_EXISTS 业务异常
  126 + List<SeckillConfigDO> configs = seckillConfigMapper.selectBatchIds(ids);
  127 + if (configs.size() != ids.size()) {
  128 + throw exception(SECKILL_CONFIG_NOT_EXISTS);
145 } 129 }
  130 +
  131 + // 2. 如果存在关闭,则抛出 SECKILL_CONFIG_DISABLE 业务异常
  132 + configs.forEach(config -> {
  133 + if (ObjectUtil.equal(config.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  134 + throw exception(SECKILL_CONFIG_DISABLE);
  135 + }
  136 + });
146 } 137 }
147 138
148 @Override 139 @Override
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillactivity/SeckillActivityServiceImplTest.java
@@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.Se
7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
9 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper; 9 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillactivity.SeckillActivityMapper;
10 -import cn.iocoder.yudao.module.promotion.service.seckill.seckillactivity.SeckillActivityServiceImpl; 10 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityServiceImpl;
11 import org.junit.jupiter.api.Disabled; 11 import org.junit.jupiter.api.Disabled;
12 import org.junit.jupiter.api.Test; 12 import org.junit.jupiter.api.Test;
13 import org.springframework.context.annotation.Import; 13 import org.springframework.context.annotation.Import;
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/seckillconfig/SeckillConfigServiceImplTest.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck
5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; 5 import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
6 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; 6 import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
7 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper; 7 import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
8 -import cn.iocoder.yudao.module.promotion.service.seckill.seckillconfig.SeckillConfigServiceImpl; 8 +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigServiceImpl;
9 import com.fasterxml.jackson.core.JsonProcessingException; 9 import com.fasterxml.jackson.core.JsonProcessingException;
10 import com.fasterxml.jackson.databind.ObjectMapper; 10 import com.fasterxml.jackson.databind.ObjectMapper;
11 import org.junit.jupiter.api.Disabled; 11 import org.junit.jupiter.api.Disabled;
@@ -19,7 +19,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq @@ -19,7 +19,7 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq
19 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; 19 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
20 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; 20 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
21 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; 21 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
22 -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_TIME_NOT_EXISTS; 22 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_CONFIG_NOT_EXISTS;
23 import static org.junit.jupiter.api.Assertions.assertNotNull; 23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull; 24 import static org.junit.jupiter.api.Assertions.assertNull;
25 25
@@ -94,7 +94,7 @@ public class SeckillConfigServiceImplTest extends BaseDbUnitTest { @@ -94,7 +94,7 @@ public class SeckillConfigServiceImplTest extends BaseDbUnitTest {
94 SeckillConfigUpdateReqVO reqVO = randomPojo(SeckillConfigUpdateReqVO.class); 94 SeckillConfigUpdateReqVO reqVO = randomPojo(SeckillConfigUpdateReqVO.class);
95 95
96 // 调用, 并断言异常 96 // 调用, 并断言异常
97 - assertServiceException(() -> SeckillConfigService.updateSeckillConfig(reqVO), SECKILL_TIME_NOT_EXISTS); 97 + assertServiceException(() -> SeckillConfigService.updateSeckillConfig(reqVO), SECKILL_CONFIG_NOT_EXISTS);
98 } 98 }
99 99
100 @Test 100 @Test
@@ -117,7 +117,7 @@ public class SeckillConfigServiceImplTest extends BaseDbUnitTest { @@ -117,7 +117,7 @@ public class SeckillConfigServiceImplTest extends BaseDbUnitTest {
117 Long id = randomLongId(); 117 Long id = randomLongId();
118 118
119 // 调用, 并断言异常 119 // 调用, 并断言异常
120 - assertServiceException(() -> SeckillConfigService.deleteSeckillConfig(id), SECKILL_TIME_NOT_EXISTS); 120 + assertServiceException(() -> SeckillConfigService.deleteSeckillConfig(id), SECKILL_CONFIG_NOT_EXISTS);
121 } 121 }
122 122
123 @Test 123 @Test
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java deleted
1 -package cn.iocoder.yudao.module.trade.enums.order;  
2 -  
3 -import lombok.Getter;  
4 -import lombok.RequiredArgsConstructor;  
5 -  
6 -/**  
7 - * 交易订单 - 发货状态  
8 - *  
9 - * @author 芋道源码  
10 - */  
11 -@RequiredArgsConstructor  
12 -@Getter  
13 -public enum TradeOrderDeliveryStatusEnum {  
14 -  
15 - UNDELIVERED(0, "未发货"),  
16 - DELIVERED(1, "已发货"),  
17 - RECEIVED(2, "已收货");  
18 -  
19 - /**  
20 - * 状态值  
21 - */  
22 - private final Integer status;  
23 - /**  
24 - * 状态名  
25 - */  
26 - private final String name;  
27 -  
28 -}  
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
@@ -10,10 +10,12 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; @@ -10,10 +10,12 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
10 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; 10 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
11 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; 11 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
12 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; 12 import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert;
  13 +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
13 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 14 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
14 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 15 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
15 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; 16 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
16 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; 17 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
  18 +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
17 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; 19 import cn.iocoder.yudao.module.trade.service.order.TradeOrderService;
18 import com.google.common.collect.Maps; 20 import com.google.common.collect.Maps;
19 import io.swagger.v3.oas.annotations.Operation; 21 import io.swagger.v3.oas.annotations.Operation;
@@ -43,7 +45,11 @@ public class AppTradeOrderController { @@ -43,7 +45,11 @@ public class AppTradeOrderController {
43 @Resource 45 @Resource
44 private TradeOrderService tradeOrderService; 46 private TradeOrderService tradeOrderService;
45 @Resource 47 @Resource
  48 + private DeliveryExpressService deliveryExpressService;
  49 +
  50 + @Resource
46 private ProductPropertyValueApi productPropertyValueApi; 51 private ProductPropertyValueApi productPropertyValueApi;
  52 +
47 @Resource 53 @Resource
48 private TradeOrderProperties tradeOrderProperties; 54 private TradeOrderProperties tradeOrderProperties;
49 55
@@ -76,14 +82,21 @@ public class AppTradeOrderController { @@ -76,14 +82,21 @@ public class AppTradeOrderController {
76 public CommonResult<AppTradeOrderDetailRespVO> getOrder(@RequestParam("id") Long id) { 82 public CommonResult<AppTradeOrderDetailRespVO> getOrder(@RequestParam("id") Long id) {
77 // 查询订单 83 // 查询订单
78 TradeOrderDO order = tradeOrderService.getOrder(getLoginUserId(), id); 84 TradeOrderDO order = tradeOrderService.getOrder(getLoginUserId(), id);
  85 + if (order == null) {
  86 + return success(null);
  87 + }
  88 +
79 // 查询订单项 89 // 查询订单项
80 List<TradeOrderItemDO> orderItems = tradeOrderService.getOrderItemListByOrderId(order.getId()); 90 List<TradeOrderItemDO> orderItems = tradeOrderService.getOrderItemListByOrderId(order.getId());
81 // 查询商品属性 91 // 查询商品属性
82 List<ProductPropertyValueDetailRespDTO> propertyValueDetails = productPropertyValueApi 92 List<ProductPropertyValueDetailRespDTO> propertyValueDetails = productPropertyValueApi
83 .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); 93 .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems));
  94 + // 查询物流公司
  95 + DeliveryExpressDO express = order.getLogisticsId() != null && order.getLogisticsId() > 0 ?
  96 + deliveryExpressService.getDeliveryExpress(order.getLogisticsId()) : null;
84 // 最终组合 97 // 最终组合
85 return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, 98 return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems,
86 - propertyValueDetails, tradeOrderProperties)); 99 + propertyValueDetails, tradeOrderProperties, express));
87 } 100 }
88 101
89 @GetMapping("/page") 102 @GetMapping("/page")
@@ -122,7 +135,7 @@ public class AppTradeOrderController { @@ -122,7 +135,7 @@ public class AppTradeOrderController {
122 return success(orderCount); 135 return success(orderCount);
123 } 136 }
124 137
125 - @PutMapping("/take") 138 + @PutMapping("/receive")
126 @Operation(summary = "确认交易订单收货") 139 @Operation(summary = "确认交易订单收货")
127 @Parameter(name = "id", description = "交易订单编号") 140 @Parameter(name = "id", description = "交易订单编号")
128 public CommonResult<Boolean> takeOrder(@RequestParam("id") Long id) { 141 public CommonResult<Boolean> takeOrder(@RequestParam("id") Long id) {
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java
@@ -80,6 +80,12 @@ public class AppTradeOrderDetailRespVO { @@ -80,6 +80,12 @@ public class AppTradeOrderDetailRespVO {
80 @Schema(description = "配送方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 80 @Schema(description = "配送方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
81 private Integer deliveryType; 81 private Integer deliveryType;
82 82
  83 + @Schema(description = "发货物流公司编号", example = "10")
  84 + private Long logisticsId;
  85 +
  86 + @Schema(description = "发货物流名称", example = "顺丰快递")
  87 + private String logisticsName;
  88 +
83 @Schema(description = "发货物流单号", example = "1024") 89 @Schema(description = "发货物流单号", example = "1024")
84 private String logisticsNo; 90 private String logisticsNo;
85 91
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemCommentCreateReqVO.java
@@ -35,5 +35,4 @@ public class AppTradeOrderItemCommentCreateReqVO { @@ -35,5 +35,4 @@ public class AppTradeOrderItemCommentCreateReqVO {
35 @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张") 35 @Size(max = 9, message = "评论图片地址数组长度不能超过 9 张")
36 private List<String> picUrls; 36 private List<String> picUrls;
37 37
38 -  
39 } 38 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/item/AppTradeOrderItemRespVO.java
@@ -13,6 +13,9 @@ public class AppTradeOrderItemRespVO { @@ -13,6 +13,9 @@ public class AppTradeOrderItemRespVO {
13 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 13 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
14 private Long id; 14 private Long id;
15 15
  16 + @Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  17 + private Long orderId;
  18 +
16 @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 19 @Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
17 private Long spuId; 20 private Long spuId;
18 @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码") 21 @Schema(description = "商品 SPU 名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
@@ -48,5 +51,5 @@ public class AppTradeOrderItemRespVO { @@ -48,5 +51,5 @@ public class AppTradeOrderItemRespVO {
48 51
49 @Schema(description = "售后状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 52 @Schema(description = "售后状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
50 private Integer afterSaleStatus; 53 private Integer afterSaleStatus;
51 - 54 +
52 } 55 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; @@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
25 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; 25 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
26 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; 26 import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
27 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO; 27 import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartDO;
  28 +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
28 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
29 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 30 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
30 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; 31 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
@@ -234,7 +235,8 @@ public interface TradeOrderConvert { @@ -234,7 +235,8 @@ public interface TradeOrderConvert {
234 235
235 // TODO 芋艿:可简化 236 // TODO 芋艿:可简化
236 default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems, 237 default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List<TradeOrderItemDO> orderItems,
237 - List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties) { 238 + List<ProductPropertyValueDetailRespDTO> propertyValueDetails, TradeOrderProperties tradeOrderProperties,
  239 + DeliveryExpressDO express) {
238 AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems); 240 AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems);
239 orderVO.setPayExpireTime(addTime(tradeOrderProperties.getExpireTime())); 241 orderVO.setPayExpireTime(addTime(tradeOrderProperties.getExpireTime()));
240 if (StrUtil.isNotEmpty(order.getPayChannelCode())) { 242 if (StrUtil.isNotEmpty(order.getPayChannelCode())) {
@@ -260,6 +262,9 @@ public interface TradeOrderConvert { @@ -260,6 +262,9 @@ public interface TradeOrderConvert {
260 } 262 }
261 // 处理收货地址 263 // 处理收货地址
262 orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); 264 orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId()));
  265 + if (express != null) {
  266 + orderVO.setLogisticsId(express.getId()).setLogisticsName(express.getName());
  267 + }
263 return orderVO; 268 return orderVO;
264 } 269 }
265 270
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order;
2 2
3 import cn.iocoder.yudao.framework.common.enums.TerminalEnum; 3 import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
5 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; 6 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO;
6 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; 7 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
7 import cn.iocoder.yudao.module.trade.enums.order.*; 8 import cn.iocoder.yudao.module.trade.enums.order.*;
@@ -174,18 +175,18 @@ public class TradeOrderDO extends BaseDO { @@ -174,18 +175,18 @@ public class TradeOrderDO extends BaseDO {
174 private Integer deliveryType; 175 private Integer deliveryType;
175 /** 176 /**
176 * 发货物流公司编号 177 * 发货物流公司编号
  178 + *
  179 + * 如果无需发货,则 logisticsId 设置为 0。原因是,不想再添加额外字段
  180 + *
  181 + * 关联 {@link DeliveryExpressDO#getId()}
177 */ 182 */
178 private Long logisticsId; 183 private Long logisticsId;
179 /** 184 /**
180 * 发货物流单号 185 * 发货物流单号
181 - */  
182 - private String logisticsNo;  
183 - /**  
184 - * 发货状态  
185 * 186 *
186 - * 枚举 {@link TradeOrderDeliveryStatusEnum} 187 + * 如果无需发货,则 logisticsNo 设置 ""。原因是,不想再添加额外字段
187 */ 188 */
188 - private Integer deliveryStatus; 189 + private String logisticsNo;
189 /** 190 /**
190 * 发货时间 191 * 发货时间
191 */ 192 */
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java
@@ -233,8 +233,8 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -233,8 +233,8 @@ public class TradeOrderServiceImpl implements TradeOrderService {
233 order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? 233 order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源?
234 // 支付信息 234 // 支付信息
235 order.setAdjustPrice(0).setPayStatus(false); 235 order.setAdjustPrice(0).setPayStatus(false);
236 - // 物流信息 TODO 芋艿:暂时写死物流方式;应该是前端选择的  
237 - order.setDeliveryType(createReqVO.getDeliveryType()).setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); 236 + // 物流信息
  237 + order.setDeliveryType(createReqVO.getDeliveryType());
238 // 退款信息 238 // 退款信息
239 order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); 239 order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0);
240 tradeOrderMapper.insert(order); 240 tradeOrderMapper.insert(order);
@@ -418,8 +418,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -418,8 +418,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
418 } 418 }
419 419
420 // 更新 TradeOrderDO 状态为已发货,等待收货 420 // 更新 TradeOrderDO 状态为已发货,等待收货
421 - updateOrderObj.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus())  
422 - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now()); 421 + updateOrderObj.setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now());
423 int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), updateOrderObj); 422 int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), updateOrderObj);
424 if (updateCount == 0) { 423 if (updateCount == 0) {
425 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); 424 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
@@ -428,7 +427,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -428,7 +427,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
428 427
429 // 发送站内信 428 // 发送站内信
430 tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO().setOrderId(order.getId()) 429 tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO().setOrderId(order.getId())
431 - .setUserId(userId).setMessage(TradeOrderDeliveryStatusEnum.DELIVERED.getName())); 430 + .setUserId(userId).setMessage(null));
432 431
433 // TODO 芋艿:OrderLog 432 // TODO 芋艿:OrderLog
434 // TODO 设计:lili:是不是发货后,才支持售后? 433 // TODO 设计:lili:是不是发货后,才支持售后?
@@ -449,8 +448,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -449,8 +448,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
449 throw exception(ORDER_NOT_FOUND); 448 throw exception(ORDER_NOT_FOUND);
450 } 449 }
451 // 校验订单是否是待发货状态 450 // 校验订单是否是待发货状态
452 - if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())  
453 - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) { 451 + if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())) {
454 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); 452 throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
455 } 453 }
456 // 校验订单是否退款 454 // 校验订单是否退款
@@ -482,8 +480,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -482,8 +480,7 @@ public class TradeOrderServiceImpl implements TradeOrderService {
482 480
483 // 更新 TradeOrderDO 状态为已完成 481 // 更新 TradeOrderDO 状态为已完成
484 int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), 482 int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(),
485 - new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus())  
486 - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.RECEIVED.getStatus()).setReceiveTime(LocalDateTime.now())); 483 + new TradeOrderDO().setStatus(TradeOrderStatusEnum.COMPLETED.getStatus()).setReceiveTime(LocalDateTime.now()));
487 if (updateCount == 0) { 484 if (updateCount == 0) {
488 throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); 485 throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
489 } 486 }
@@ -495,11 +492,6 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -495,11 +492,6 @@ public class TradeOrderServiceImpl implements TradeOrderService {
495 return Boolean.TRUE; 492 return Boolean.TRUE;
496 } 493 }
497 494
498 - @Override  
499 - public TradeOrderDO getOrder(Long id) {  
500 - return tradeOrderMapper.selectById(id);  
501 - }  
502 -  
503 /** 495 /**
504 * 校验交易订单满足可售货的条件 496 * 校验交易订单满足可售货的条件
505 * 497 *
@@ -516,14 +508,18 @@ public class TradeOrderServiceImpl implements TradeOrderService { @@ -516,14 +508,18 @@ public class TradeOrderServiceImpl implements TradeOrderService {
516 throw exception(ORDER_NOT_FOUND); 508 throw exception(ORDER_NOT_FOUND);
517 } 509 }
518 // 校验订单是否是待收货状态 510 // 校验订单是否是待收货状态
519 - if (!TradeOrderStatusEnum.isDelivered(order.getStatus())  
520 - || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus())) { 511 + if (!TradeOrderStatusEnum.isDelivered(order.getStatus())) {
521 throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED); 512 throw exception(ORDER_RECEIVE_FAIL_STATUS_NOT_DELIVERED);
522 } 513 }
523 return order; 514 return order;
524 } 515 }
525 516
526 @Override 517 @Override
  518 + public TradeOrderDO getOrder(Long id) {
  519 + return tradeOrderMapper.selectById(id);
  520 + }
  521 +
  522 + @Override
527 public TradeOrderDO getOrder(Long userId, Long id) { 523 public TradeOrderDO getOrder(Long userId, Long id) {
528 TradeOrderDO order = tradeOrderMapper.selectById(id); 524 TradeOrderDO order = tradeOrderMapper.selectById(id);
529 if (order != null 525 if (order != null
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java
@@ -177,7 +177,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { @@ -177,7 +177,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest {
177 assertEquals(tradeOrderDO.getPayOrderId(), 1000L); 177 assertEquals(tradeOrderDO.getPayOrderId(), 1000L);
178 assertNull(tradeOrderDO.getPayChannelCode()); 178 assertNull(tradeOrderDO.getPayChannelCode());
179 assertNull(tradeOrderDO.getLogisticsId()); 179 assertNull(tradeOrderDO.getLogisticsId());
180 - assertEquals(tradeOrderDO.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus());  
181 assertNull(tradeOrderDO.getDeliveryTime()); 180 assertNull(tradeOrderDO.getDeliveryTime());
182 assertNull(tradeOrderDO.getReceiveTime()); 181 assertNull(tradeOrderDO.getReceiveTime());
183 assertEquals(tradeOrderDO.getReceiverName(), "芋艿"); 182 assertEquals(tradeOrderDO.getReceiverName(), "芋艿");
@@ -274,8 +273,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { @@ -274,8 +273,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest {
274 // mock 数据(TradeOrder) 273 // mock 数据(TradeOrder)
275 TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { 274 TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> {
276 o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()); 275 o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus());
277 - o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null)  
278 - .setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); 276 + o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null);
279 }); 277 });
280 tradeOrderMapper.insert(order); 278 tradeOrderMapper.insert(order);
281 // 准备参数 279 // 准备参数
@@ -288,7 +286,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { @@ -288,7 +286,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest {
288 // 断言 286 // 断言
289 TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L); 287 TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L);
290 assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus()); 288 assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus());
291 - assertEquals(dbOrder.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus());  
292 assertPojoEquals(dbOrder, deliveryReqVO); 289 assertPojoEquals(dbOrder, deliveryReqVO);
293 assertNotNull(dbOrder.getDeliveryTime()); 290 assertNotNull(dbOrder.getDeliveryTime());
294 } 291 }
@@ -298,7 +295,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { @@ -298,7 +295,7 @@ public class TradeOrderServiceTest extends BaseDbUnitTest {
298 // mock 数据(TradeOrder) 295 // mock 数据(TradeOrder)
299 TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { 296 TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> {
300 o.setId(1L).setUserId(10L).setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()); 297 o.setId(1L).setUserId(10L).setStatus(TradeOrderStatusEnum.DELIVERED.getStatus());
301 - o.setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setReceiveTime(null); 298 + o.setReceiveTime(null);
302 }); 299 });
303 tradeOrderMapper.insert(order); 300 tradeOrderMapper.insert(order);
304 // 准备参数 301 // 准备参数
@@ -311,7 +308,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { @@ -311,7 +308,6 @@ public class TradeOrderServiceTest extends BaseDbUnitTest {
311 // 断言 308 // 断言
312 TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L); 309 TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L);
313 assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus()); 310 assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.COMPLETED.getStatus());
314 - assertEquals(dbOrder.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.RECEIVED.getStatus());  
315 assertNotNull(dbOrder.getReceiveTime()); 311 assertNotNull(dbOrder.getReceiveTime());
316 } 312 }
317 313
yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
@@ -25,7 +25,6 @@ CREATE TABLE IF NOT EXISTS &quot;trade_order&quot; ( @@ -25,7 +25,6 @@ CREATE TABLE IF NOT EXISTS &quot;trade_order&quot; (
25 "delivery_template_id" bigint, 25 "delivery_template_id" bigint,
26 "logistics_id" bigint, 26 "logistics_id" bigint,
27 "logistics_no" varchar, 27 "logistics_no" varchar,
28 - "delivery_status" smallint NOT NULL,  
29 "delivery_time" datetime, 28 "delivery_time" datetime,
30 "receive_time" datetime, 29 "receive_time" datetime,
31 "receiver_name" varchar NOT NULL, 30 "receiver_name" varchar NOT NULL,