Commit 7cdb321fe4b10ac02f3c82c19dc37336fb84472f

Authored by puhui999
1 parent 927f71c7

fix:完善拼团活动CRUD

Showing 13 changed files with 191 additions and 53 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -62,5 +62,7 @@ public interface ErrorCodeConstants { @@ -62,5 +62,7 @@ public interface ErrorCodeConstants {
62 62
63 // ========== 拼团活动 1013010000 ========== 63 // ========== 拼团活动 1013010000 ==========
64 ErrorCode COMBINATION_ACTIVITY_NOT_EXISTS = new ErrorCode(1013010000, "拼团活动不存在"); 64 ErrorCode COMBINATION_ACTIVITY_NOT_EXISTS = new ErrorCode(1013010000, "拼团活动不存在");
65 - ErrorCode COMBINATION_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013010000, "存在商品参加了其它拼团活动"); 65 + ErrorCode COMBINATION_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013010001, "存在商品参加了其它拼团活动");
  66 + ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013010002, "拼团活动已关闭不能修改");
  67 + ErrorCode COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013010003, "拼团活动未关闭或未结束,不能删除");
66 } 68 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; @@ -7,6 +7,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.*; 7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.*;
8 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; 8 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
9 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO; 9 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  10 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
10 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService; 11 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
11 import io.swagger.v3.oas.annotations.Operation; 12 import io.swagger.v3.oas.annotations.Operation;
12 import io.swagger.v3.oas.annotations.Parameter; 13 import io.swagger.v3.oas.annotations.Parameter;
@@ -64,7 +65,8 @@ public class CombinationActivityController { @@ -64,7 +65,8 @@ public class CombinationActivityController {
64 @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')") 65 @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
65 public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) { 66 public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) {
66 CombinationActivityDO combinationActivity = combinationActivityService.getCombinationActivity(id); 67 CombinationActivityDO combinationActivity = combinationActivityService.getCombinationActivity(id);
67 - return success(CombinationActivityConvert.INSTANCE.convert(combinationActivity)); 68 + List<CombinationProductDO> productDOs = combinationActivityService.getProductsByActivityId(id);
  69 + return success(CombinationActivityConvert.INSTANCE.convert(combinationActivity, productDOs));
68 } 70 }
69 71
70 @GetMapping("/list") 72 @GetMapping("/list")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
@@ -6,7 +6,6 @@ import org.springframework.format.annotation.DateTimeFormat; @@ -6,7 +6,6 @@ import org.springframework.format.annotation.DateTimeFormat;
6 6
7 import javax.validation.constraints.NotNull; 7 import javax.validation.constraints.NotNull;
8 import java.time.LocalDateTime; 8 import java.time.LocalDateTime;
9 -import java.util.List;  
10 9
11 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 10 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
12 11
@@ -23,7 +22,7 @@ public class CombinationActivityBaseVO { @@ -23,7 +22,7 @@ public class CombinationActivityBaseVO {
23 22
24 @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "[1,2,3]") 23 @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "[1,2,3]")
25 @NotNull(message = "拼团商品不能为空") 24 @NotNull(message = "拼团商品不能为空")
26 - private List<Long> spuIds; 25 + private Long spuId;
27 26
28 @Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218") 27 @Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
29 @NotNull(message = "总限购数量不能为空") 28 @NotNull(message = "总限购数量不能为空")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java
@@ -6,6 +6,7 @@ import lombok.Data; @@ -6,6 +6,7 @@ import lombok.Data;
6 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
7 import lombok.ToString; 7 import lombok.ToString;
8 8
  9 +import javax.validation.Valid;
9 import java.util.List; 10 import java.util.List;
10 11
11 @Schema(description = "管理后台 - 拼团活动创建 Request VO") 12 @Schema(description = "管理后台 - 拼团活动创建 Request VO")
@@ -14,7 +15,8 @@ import java.util.List; @@ -14,7 +15,8 @@ import java.util.List;
14 @ToString(callSuper = true) 15 @ToString(callSuper = true)
15 public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO { 16 public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
16 17
17 - @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED) 18 + @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
  19 + @Valid
18 private List<CombinationProductCreateReqVO> products; 20 private List<CombinationProductCreateReqVO> products;
19 21
20 } 22 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.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.CombinationProductRespVO;
3 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 5 import lombok.Data;
5 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 7 import lombok.ToString;
7 8
  9 +import javax.validation.Valid;
8 import javax.validation.constraints.NotNull; 10 import javax.validation.constraints.NotNull;
9 import java.time.LocalDateTime; 11 import java.time.LocalDateTime;
  12 +import java.util.List;
10 13
11 @Schema(description = "管理后台 - 拼团活动 Response VO") 14 @Schema(description = "管理后台 - 拼团活动 Response VO")
12 @Data 15 @Data
@@ -40,4 +43,8 @@ public class CombinationActivityRespVO extends CombinationActivityBaseVO { @@ -40,4 +43,8 @@ public class CombinationActivityRespVO extends CombinationActivityBaseVO {
40 @NotNull(message = "活动状态:0开启 1关闭不能为空") 43 @NotNull(message = "活动状态:0开启 1关闭不能为空")
41 private Integer status; 44 private Integer status;
42 45
  46 + @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
  47 + @Valid
  48 + private List<CombinationProductRespVO> products;
  49 +
43 } 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 io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 5 import lombok.Data;
5 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 7 import lombok.ToString;
7 8
  9 +import javax.validation.Valid;
8 import javax.validation.constraints.NotNull; 10 import javax.validation.constraints.NotNull;
  11 +import java.util.List;
9 12
10 @Schema(description = "管理后台 - 拼团活动更新 Request VO") 13 @Schema(description = "管理后台 - 拼团活动更新 Request VO")
11 @Data 14 @Data
@@ -17,4 +20,8 @@ public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO { @@ -17,4 +20,8 @@ public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO {
17 @NotNull(message = "活动编号不能为空") 20 @NotNull(message = "活动编号不能为空")
18 private Long id; 21 private Long id;
19 22
  23 + @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
  24 + @Valid
  25 + private List<CombinationProductUpdateReqVO> products;
  26 +
20 } 27 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductUpdateReqVO.java
@@ -5,16 +5,10 @@ import lombok.Data; @@ -5,16 +5,10 @@ import lombok.Data;
5 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 6 import lombok.ToString;
7 7
8 -import javax.validation.constraints.NotNull;  
9 -  
10 @Schema(description = "管理后台 - 拼团商品更新 Request VO") 8 @Schema(description = "管理后台 - 拼团商品更新 Request VO")
11 @Data 9 @Data
12 @EqualsAndHashCode(callSuper = true) 10 @EqualsAndHashCode(callSuper = true)
13 @ToString(callSuper = true) 11 @ToString(callSuper = true)
14 public class CombinationProductUpdateReqVO extends CombinationProductBaseVO { 12 public class CombinationProductUpdateReqVO extends CombinationProductBaseVO {
15 13
16 - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")  
17 - @NotNull(message = "编号不能为空")  
18 - private Long id;  
19 -  
20 } 14 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
1 package cn.iocoder.yudao.module.promotion.convert.combination; 1 package cn.iocoder.yudao.module.promotion.convert.combination;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
4 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
5 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExcelVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExcelVO;
6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO; 8 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO;
7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; 9 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
8 -import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO; 10 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
  11 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO;
  12 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
9 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO; 13 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
10 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO; 14 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
11 import org.mapstruct.Mapper; 15 import org.mapstruct.Mapper;
12 import org.mapstruct.Mapping; 16 import org.mapstruct.Mapping;
  17 +import org.mapstruct.Mappings;
  18 +import org.mapstruct.Named;
13 import org.mapstruct.factory.Mappers; 19 import org.mapstruct.factory.Mappers;
14 20
  21 +import java.time.LocalDateTime;
15 import java.util.ArrayList; 22 import java.util.ArrayList;
16 import java.util.List; 23 import java.util.List;
  24 +import java.util.Map;
17 25
18 /** 26 /**
19 * 拼团活动 Convert 27 * 拼团活动 Convert
@@ -25,33 +33,82 @@ public interface CombinationActivityConvert { @@ -25,33 +33,82 @@ public interface CombinationActivityConvert {
25 33
26 CombinationActivityConvert INSTANCE = Mappers.getMapper(CombinationActivityConvert.class); 34 CombinationActivityConvert INSTANCE = Mappers.getMapper(CombinationActivityConvert.class);
27 35
28 - @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])")  
29 - @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])") 36 + @Mappings({
  37 + @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
  38 + @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
  39 + })
30 CombinationActivityDO convert(CombinationActivityCreateReqVO bean); 40 CombinationActivityDO convert(CombinationActivityCreateReqVO bean);
31 41
  42 + @Mappings({
  43 + @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
  44 + @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
  45 + })
32 CombinationActivityDO convert(CombinationActivityUpdateReqVO bean); 46 CombinationActivityDO convert(CombinationActivityUpdateReqVO bean);
33 47
  48 + @Named("mergeTime")
  49 + default LocalDateTime[] mergeTime(LocalDateTime startTime, LocalDateTime endTime) {
  50 + // TODO 有点怪第一次这样写 hh
  51 + LocalDateTime[] localDateTime = new LocalDateTime[2];
  52 + localDateTime[0] = startTime;
  53 + localDateTime[1] = endTime;
  54 + return localDateTime;
  55 + }
  56 +
  57 + @Mappings({
  58 + @Mapping(target = "activityTime", expression = "java(mergeTime(bean.getStartTime(),bean.getEndTime()))")
  59 + })
34 CombinationActivityRespVO convert(CombinationActivityDO bean); 60 CombinationActivityRespVO convert(CombinationActivityDO bean);
35 61
  62 + CombinationProductRespVO convert(CombinationProductDO bean);
  63 +
  64 + default CombinationActivityRespVO convert(CombinationActivityDO bean, List<CombinationProductDO> productDOs) {
  65 + CombinationActivityRespVO respVO = convert(bean);
  66 + ArrayList<CombinationProductRespVO> vos = new ArrayList<>();
  67 + productDOs.forEach(item -> {
  68 + vos.add(convert(item));
  69 + });
  70 + respVO.setProducts(vos);
  71 + return respVO;
  72 + }
  73 +
36 List<CombinationActivityRespVO> convertList(List<CombinationActivityDO> list); 74 List<CombinationActivityRespVO> convertList(List<CombinationActivityDO> list);
37 75
38 PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page); 76 PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page);
39 77
40 List<CombinationActivityExcelVO> convertList02(List<CombinationActivityDO> list); 78 List<CombinationActivityExcelVO> convertList02(List<CombinationActivityDO> list);
41 79
42 - default List<CombinationProductDO> convertList(CombinationActivityDO activityDO, List<CombinationProductCreateReqVO> products) {  
43 - ArrayList<CombinationProductDO> productDOs = new ArrayList<>();  
44 - products.forEach(item -> {  
45 - CombinationProductDO productDO = new CombinationProductDO();  
46 - productDO.setActivityId(activityDO.getId());  
47 - productDO.setSpuId(item.getSpuId());  
48 - productDO.setSkuId(item.getSkuId());  
49 - productDO.setActivityStatus(0); // TODO 拼团状态枚举未定义不确定有些什么状态  
50 - productDO.setActivityStartTime(activityDO.getStartTime());  
51 - productDO.setActivityEndTime(activityDO.getEndTime());  
52 - productDO.setActivePrice(item.getActivePrice());  
53 - productDOs.add(productDO); 80 + @Mappings({
  81 + @Mapping(target = "id", ignore = true),
  82 + @Mapping(target = "activityId", source = "activityDO.id"),
  83 + @Mapping(target = "spuId", source = "activityDO.spuId"),
  84 + @Mapping(target = "skuId", source = "vo.skuId"),
  85 + @Mapping(target = "activePrice", source = "vo.activePrice"),
  86 + @Mapping(target = "activityStartTime", source = "activityDO.startTime"),
  87 + @Mapping(target = "activityEndTime", source = "activityDO.endTime")
  88 + })
  89 + CombinationProductDO convert(CombinationActivityDO activityDO, CombinationProductBaseVO vo);
  90 +
  91 + default List<CombinationProductDO> convertList(CombinationActivityDO activityDO, List<? extends CombinationProductBaseVO> products) {
  92 + List<CombinationProductDO> list = new ArrayList<>();
  93 + products.forEach(sku -> {
  94 + CombinationProductDO productDO = convert(activityDO, sku);
  95 + // TODO 状态设置
  96 + productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
  97 + list.add(productDO);
54 }); 98 });
55 - return productDOs; 99 + return list;
56 } 100 }
  101 +
  102 + default List<CombinationProductDO> convertList1(CombinationActivityDO activityDO, List<CombinationProductUpdateReqVO> vos, List<CombinationProductDO> productDOs) {
  103 + Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, CombinationProductDO::getSkuId, CombinationProductDO::getId);
  104 + List<CombinationProductDO> list = new ArrayList<>();
  105 + vos.forEach(sku -> {
  106 + CombinationProductDO productDO = convert(activityDO, sku);
  107 + productDO.setId(longMap.get(sku.getSkuId()));
  108 + productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
  109 + list.add(productDO);
  110 + });
  111 + return list;
  112 + }
  113 +
57 } 114 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationActivityDO.java
@@ -2,15 +2,12 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combination @@ -2,15 +2,12 @@ package cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combination
2 2
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 -import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;  
6 import com.baomidou.mybatisplus.annotation.KeySequence; 5 import com.baomidou.mybatisplus.annotation.KeySequence;
7 -import com.baomidou.mybatisplus.annotation.TableField;  
8 import com.baomidou.mybatisplus.annotation.TableId; 6 import com.baomidou.mybatisplus.annotation.TableId;
9 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
10 import lombok.*; 8 import lombok.*;
11 9
12 import java.time.LocalDateTime; 10 import java.time.LocalDateTime;
13 -import java.util.List;  
14 11
15 /** 12 /**
16 * 拼团活动 DO 13 * 拼团活动 DO
@@ -39,8 +36,7 @@ public class CombinationActivityDO extends BaseDO { @@ -39,8 +36,7 @@ public class CombinationActivityDO extends BaseDO {
39 /** 36 /**
40 * 商品 SPU 编号关联 ProductSpuDO 的 id 37 * 商品 SPU 编号关联 ProductSpuDO 的 id
41 */ 38 */
42 - @TableField(typeHandler = LongListTypeHandler.class)  
43 - private List<Long> spuIds; 39 + private Long spuId;
44 /** 40 /**
45 * 总限购数量 41 * 总限购数量
46 */ 42 */
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationActivityMapper.java
@@ -34,4 +34,5 @@ public interface CombinationActivityMapper extends BaseMapperX&lt;CombinationActivi @@ -34,4 +34,5 @@ public interface CombinationActivityMapper extends BaseMapperX&lt;CombinationActivi
34 default List<CombinationActivityDO> selectListByStatus(Integer status) { 34 default List<CombinationActivityDO> selectListByStatus(Integer status) {
35 return selectList(CombinationActivityDO::getStatus, status); 35 return selectList(CombinationActivityDO::getStatus, status);
36 } 36 }
  37 +
37 } 38 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationProductMapper.java
@@ -44,4 +44,8 @@ public interface CombinationProductMapper extends BaseMapperX&lt;CombinationProduct @@ -44,4 +44,8 @@ public interface CombinationProductMapper extends BaseMapperX&lt;CombinationProduct
44 .orderByDesc(CombinationProductDO::getId)); 44 .orderByDesc(CombinationProductDO::getId));
45 } 45 }
46 46
  47 + default List<CombinationProductDO> selectListByActivityId(Long id) {
  48 + return selectList(CombinationProductDO::getActivityId, id);
  49 + }
  50 +
47 } 51 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activit @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activit
6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; 7 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
8 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO; 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
  9 +import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
9 10
10 import javax.validation.Valid; 11 import javax.validation.Valid;
11 import java.util.Collection; 12 import java.util.Collection;
@@ -72,4 +73,11 @@ public interface CombinationActivityService { @@ -72,4 +73,11 @@ public interface CombinationActivityService {
72 */ 73 */
73 List<CombinationActivityDO> getCombinationActivityList(CombinationActivityExportReqVO exportReqVO); 74 List<CombinationActivityDO> getCombinationActivityList(CombinationActivityExportReqVO exportReqVO);
74 75
  76 + /**
  77 + * 获得拼团活动商品列表
  78 + *
  79 + * @param id 拼团活动 ID
  80 + * @return 拼团活动的商品列表
  81 + */
  82 + List<CombinationProductDO> getProductsByActivityId(Long id);
75 } 83 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
1 package cn.iocoder.yudao.module.promotion.service.combination; 1 package cn.iocoder.yudao.module.promotion.service.combination;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.collection.CollectionUtil;
4 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 6 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; 9 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
8 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; 10 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
9 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; 11 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
@@ -13,6 +15,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activit @@ -13,6 +15,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activit
13 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; 15 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; 16 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
15 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO; 17 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
  18 +import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
16 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; 19 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
17 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO; 20 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
18 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO; 21 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
@@ -22,15 +25,13 @@ import org.springframework.stereotype.Service; @@ -22,15 +25,13 @@ import org.springframework.stereotype.Service;
22 import org.springframework.validation.annotation.Validated; 25 import org.springframework.validation.annotation.Validated;
23 26
24 import javax.annotation.Resource; 27 import javax.annotation.Resource;
25 -import java.util.ArrayList;  
26 import java.util.Collection; 28 import java.util.Collection;
27 import java.util.List; 29 import java.util.List;
28 -import java.util.stream.Collectors; 30 +import java.util.Set;
29 31
30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 32 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
31 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;
32 -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_NOT_EXISTS;  
33 -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_SPU_CONFLICTS; 34 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
34 import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuExistence; 35 import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuExistence;
35 36
36 /** 37 /**
@@ -54,9 +55,9 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -54,9 +55,9 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
54 @Override 55 @Override
55 public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) { 56 public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) {
56 // 校验商品 SPU 是否存在是否参加的别的活动 57 // 校验商品 SPU 是否存在是否参加的别的活动
57 - validateProductCombinationConflict(createReqVO.getSpuIds()); 58 + validateProductCombinationConflict(createReqVO.getSpuId(), null);
58 // 获取所选 spu下的所有 sku 59 // 获取所选 spu下的所有 sku
59 - List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(createReqVO.getSpuIds()); 60 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId()));
60 // 校验商品 sku 是否存在 61 // 校验商品 sku 是否存在
61 validateProductSkuExistence(skus, createReqVO.getProducts(), CombinationProductCreateReqVO::getSkuId); 62 validateProductSkuExistence(skus, createReqVO.getProducts(), CombinationProductCreateReqVO::getSkuId);
62 63
@@ -79,21 +80,20 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -79,21 +80,20 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
79 return activityDO.getId(); 80 return activityDO.getId();
80 } 81 }
81 82
82 - private void validateProductCombinationConflict(List<Long> spuIds) { 83 + private void validateProductCombinationConflict(Long spuId, Long activityId) {
83 // 校验商品 spu 是否存在 84 // 校验商品 spu 是否存在
84 - List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);  
85 - if (ObjectUtil.notEqual(spuIds.size(), spuList.size())) { 85 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));
  86 + if (CollUtil.isEmpty(spuList)) {
86 throw exception(SPU_NOT_EXISTS); 87 throw exception(SPU_NOT_EXISTS);
87 } 88 }
88 - // 查询所有开启的秒杀活动 89 + // 查询所有开启的拼团活动
89 List<CombinationActivityDO> activityDOs = combinationActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()); 90 List<CombinationActivityDO> activityDOs = combinationActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
  91 + // 更新时排除自己
  92 + if (activityId != null) {
  93 + activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
  94 + }
90 // 过滤出所有 spuIds 有交集的活动 95 // 过滤出所有 spuIds 有交集的活动
91 - List<CombinationActivityDO> doList = activityDOs.stream().filter(s -> {  
92 - // 判断 spu 是否有交集  
93 - ArrayList<Long> spuIdsClone = CollUtil.newArrayList(s.getSpuIds());  
94 - spuIdsClone.retainAll(spuIds);  
95 - return CollUtil.isNotEmpty(spuIdsClone);  
96 - }).collect(Collectors.toList()); 96 + List<CombinationActivityDO> doList = CollectionUtils.convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getId(), spuId));
97 if (CollUtil.isNotEmpty(doList)) { 97 if (CollUtil.isNotEmpty(doList)) {
98 throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS); 98 throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS);
99 } 99 }
@@ -102,29 +102,83 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -102,29 +102,83 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
102 @Override 102 @Override
103 public void updateCombinationActivity(CombinationActivityUpdateReqVO updateReqVO) { 103 public void updateCombinationActivity(CombinationActivityUpdateReqVO updateReqVO) {
104 // 校验存在 104 // 校验存在
105 - validateCombinationActivityExists(updateReqVO.getId()); 105 + CombinationActivityDO activityDO = validateCombinationActivityExists(updateReqVO.getId());
  106 + // 校验状态
  107 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
  108 + throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
  109 + }
  110 + // 校验商品冲突
  111 + validateProductCombinationConflict(updateReqVO.getSpuId(), updateReqVO.getId());
  112 + // 获取所选 spu下的所有 sku
  113 + List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId()));
  114 + // 校验商品 sku 是否存在
  115 + validateProductSkuExistence(skus, updateReqVO.getProducts(), CombinationProductUpdateReqVO::getSkuId);
  116 +
106 // 更新 117 // 更新
107 CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO); 118 CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO);
108 combinationActivityMapper.updateById(updateObj); 119 combinationActivityMapper.updateById(updateObj);
  120 + // 更新商品
  121 + updateCombinationProduct(updateObj, updateReqVO.getProducts());
  122 + }
  123 +
  124 + /**
  125 + * 更新秒杀商品
  126 + * TODO 更新商品要不要封装成通用方法
  127 + *
  128 + * @param updateObj DO
  129 + * @param products 商品配置
  130 + */
  131 + private void updateCombinationProduct(CombinationActivityDO updateObj, List<CombinationProductUpdateReqVO> products) {
  132 + List<CombinationProductDO> combinationProductDOs = combinationProductMapper.selectListByActivityId(updateObj.getId());
  133 + // 数据库中的活动商品
  134 + Set<Long> convertSet = CollectionUtils.convertSet(combinationProductDOs, CombinationProductDO::getSkuId);
  135 + // 前端传过来的活动商品
  136 + Set<Long> convertSet1 = CollectionUtils.convertSet(products, CombinationProductUpdateReqVO::getSkuId);
  137 + // 删除后台存在的前端不存在的商品
  138 + List<Long> d = CollectionUtils.filterList(convertSet, item -> !convertSet1.contains(item));
  139 + if (CollUtil.isNotEmpty(d)) {
  140 + combinationProductMapper.deleteBatchIds(d);
  141 + }
  142 + // 前端存在的后端不存在的商品
  143 + List<Long> c = CollectionUtils.filterList(convertSet1, item -> !convertSet.contains(item));
  144 + if (CollUtil.isNotEmpty(c)) {
  145 + List<CombinationProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> c.contains(item.getSkuId()));
  146 + List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList(updateObj, vos);
  147 + combinationProductMapper.insertBatch(productDOs);
  148 + }
  149 + // 更新已存在的商品
  150 + List<Long> u = CollectionUtils.filterList(convertSet1, convertSet::contains);
  151 + if (CollUtil.isNotEmpty(u)) {
  152 + List<CombinationProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> u.contains(item.getSkuId()));
  153 + List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList1(updateObj, vos, combinationProductDOs);
  154 + combinationProductMapper.updateBatch(productDOs);
  155 + }
109 } 156 }
110 157
111 @Override 158 @Override
112 public void deleteCombinationActivity(Long id) { 159 public void deleteCombinationActivity(Long id) {
113 // 校验存在 160 // 校验存在
114 - validateCombinationActivityExists(id); 161 + CombinationActivityDO activityDO = validateCombinationActivityExists(id);
  162 + // 校验状态
  163 + if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  164 + throw exception(COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
  165 + }
  166 +
115 // 删除 167 // 删除
116 combinationActivityMapper.deleteById(id); 168 combinationActivityMapper.deleteById(id);
117 } 169 }
118 170
119 - private void validateCombinationActivityExists(Long id) {  
120 - if (combinationActivityMapper.selectById(id) == null) { 171 + private CombinationActivityDO validateCombinationActivityExists(Long id) {
  172 + CombinationActivityDO activityDO = combinationActivityMapper.selectById(id);
  173 + if (activityDO == null) {
121 throw exception(COMBINATION_ACTIVITY_NOT_EXISTS); 174 throw exception(COMBINATION_ACTIVITY_NOT_EXISTS);
122 } 175 }
  176 + return activityDO;
123 } 177 }
124 178
125 @Override 179 @Override
126 public CombinationActivityDO getCombinationActivity(Long id) { 180 public CombinationActivityDO getCombinationActivity(Long id) {
127 - return combinationActivityMapper.selectById(id); 181 + return validateCombinationActivityExists(id);
128 } 182 }
129 183
130 @Override 184 @Override
@@ -142,4 +196,9 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic @@ -142,4 +196,9 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
142 return combinationActivityMapper.selectList(exportReqVO); 196 return combinationActivityMapper.selectList(exportReqVO);
143 } 197 }
144 198
  199 + @Override
  200 + public List<CombinationProductDO> getProductsByActivityId(Long id) {
  201 + return combinationProductMapper.selectListByActivityId(id);
  202 + }
  203 +
145 } 204 }