Browse Source

fix:完善拼团活动CRUD

puhui999 2 years ago
parent
commit
7cdb321fe4
13 changed files with 191 additions and 53 deletions
  1. 3 1
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
  2. 3 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationActivityController.java
  3. 1 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityBaseVO.java
  4. 3 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityCreateReqVO.java
  5. 7 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java
  6. 7 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java
  7. 0 6
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/product/CombinationProductUpdateReqVO.java
  8. 73 16
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
  9. 1 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/combinationactivity/CombinationActivityDO.java
  10. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationActivityMapper.java
  11. 4 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/combination/combinationactivity/CombinationProductMapper.java
  12. 8 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.java
  13. 80 21
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java

+ 3 - 1
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 {
 
     // ========== 拼团活动 1013010000 ==========
     ErrorCode COMBINATION_ACTIVITY_NOT_EXISTS = new ErrorCode(1013010000, "拼团活动不存在");
-    ErrorCode COMBINATION_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013010000, "存在商品参加了其它拼团活动");
+    ErrorCode COMBINATION_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1013010001, "存在商品参加了其它拼团活动");
+    ErrorCode COMBINATION_ACTIVITY_STATUS_DISABLE = new ErrorCode(1013010002, "拼团活动已关闭不能修改");
+    ErrorCode COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013010003, "拼团活动未关闭或未结束,不能删除");
 }

+ 3 - 1
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;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.*;
 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
 import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -64,7 +65,8 @@ public class CombinationActivityController {
     @PreAuthorize("@ss.hasPermission('promotion:combination-activity:query')")
     public CommonResult<CombinationActivityRespVO> getCombinationActivity(@RequestParam("id") Long id) {
         CombinationActivityDO combinationActivity = combinationActivityService.getCombinationActivity(id);
-        return success(CombinationActivityConvert.INSTANCE.convert(combinationActivity));
+        List<CombinationProductDO> productDOs = combinationActivityService.getProductsByActivityId(id);
+        return success(CombinationActivityConvert.INSTANCE.convert(combinationActivity, productDOs));
     }
 
     @GetMapping("/list")

+ 1 - 2
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;
 
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
-import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
@@ -23,7 +22,7 @@ public class CombinationActivityBaseVO {
 
     @Schema(description = "商品 SPU 编号关联 ProductSpuDO 的 id", example = "[1,2,3]")
     @NotNull(message = "拼团商品不能为空")
-    private List<Long> spuIds;
+    private Long spuId;
 
     @Schema(description = "总限购数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "16218")
     @NotNull(message = "总限购数量不能为空")

+ 3 - 1
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;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
+import javax.validation.Valid;
 import java.util.List;
 
 @Schema(description = "管理后台 - 拼团活动创建 Request VO")
@@ -14,7 +15,8 @@ import java.util.List;
 @ToString(callSuper = true)
 public class CombinationActivityCreateReqVO extends CombinationActivityBaseVO {
 
-    @Schema(description = "秒杀商品", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Valid
     private List<CombinationProductCreateReqVO> products;
 
 }

+ 7 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityRespVO.java

@@ -1,12 +1,15 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
 
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
+import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "管理后台 - 拼团活动 Response VO")
 @Data
@@ -40,4 +43,8 @@ public class CombinationActivityRespVO extends CombinationActivityBaseVO {
     @NotNull(message = "活动状态:0开启 1关闭不能为空")
     private Integer status;
 
+    @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Valid
+    private List<CombinationProductRespVO> products;
+
 }

+ 7 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/vo/activity/CombinationActivityUpdateReqVO.java

@@ -1,11 +1,14 @@
 package cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity;
 
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
+import javax.validation.Valid;
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 @Schema(description = "管理后台 - 拼团活动更新 Request VO")
 @Data
@@ -17,4 +20,8 @@ public class CombinationActivityUpdateReqVO extends CombinationActivityBaseVO {
     @NotNull(message = "活动编号不能为空")
     private Long id;
 
+    @Schema(description = "拼团商品", requiredMode = Schema.RequiredMode.REQUIRED)
+    @Valid
+    private List<CombinationProductUpdateReqVO> products;
+
 }

+ 0 - 6
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;
 import lombok.EqualsAndHashCode;
 import lombok.ToString;
 
-import javax.validation.constraints.NotNull;
-
 @Schema(description = "管理后台 - 拼团商品更新 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 public class CombinationProductUpdateReqVO extends CombinationProductBaseVO {
 
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28322")
-    @NotNull(message = "编号不能为空")
-    private Long id;
-
 }

+ 73 - 16
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java

@@ -1,19 +1,27 @@
 package cn.iocoder.yudao.module.promotion.convert.combination;
 
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityExcelVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityRespVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
-import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductBaseVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductRespVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.Named;
 import org.mapstruct.factory.Mappers;
 
+import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 拼团活动 Convert
@@ -25,33 +33,82 @@ public interface CombinationActivityConvert {
 
     CombinationActivityConvert INSTANCE = Mappers.getMapper(CombinationActivityConvert.class);
 
-    @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])")
-    @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
+    @Mappings({
+            @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
+            @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
+    })
     CombinationActivityDO convert(CombinationActivityCreateReqVO bean);
 
+    @Mappings({
+            @Mapping(target = "startTime", expression = "java(bean.getActivityTime()[0])"),
+            @Mapping(target = "endTime", expression = "java(bean.getActivityTime()[1])")
+    })
     CombinationActivityDO convert(CombinationActivityUpdateReqVO bean);
 
+    @Named("mergeTime")
+    default LocalDateTime[] mergeTime(LocalDateTime startTime, LocalDateTime endTime) {
+        // TODO 有点怪第一次这样写 hh
+        LocalDateTime[] localDateTime = new LocalDateTime[2];
+        localDateTime[0] = startTime;
+        localDateTime[1] = endTime;
+        return localDateTime;
+    }
+
+    @Mappings({
+            @Mapping(target = "activityTime", expression = "java(mergeTime(bean.getStartTime(),bean.getEndTime()))")
+    })
     CombinationActivityRespVO convert(CombinationActivityDO bean);
 
+    CombinationProductRespVO convert(CombinationProductDO bean);
+
+    default CombinationActivityRespVO convert(CombinationActivityDO bean, List<CombinationProductDO> productDOs) {
+        CombinationActivityRespVO respVO = convert(bean);
+        ArrayList<CombinationProductRespVO> vos = new ArrayList<>();
+        productDOs.forEach(item -> {
+            vos.add(convert(item));
+        });
+        respVO.setProducts(vos);
+        return respVO;
+    }
+
     List<CombinationActivityRespVO> convertList(List<CombinationActivityDO> list);
 
     PageResult<CombinationActivityRespVO> convertPage(PageResult<CombinationActivityDO> page);
 
     List<CombinationActivityExcelVO> convertList02(List<CombinationActivityDO> list);
 
-    default List<CombinationProductDO> convertList(CombinationActivityDO activityDO, List<CombinationProductCreateReqVO> products) {
-        ArrayList<CombinationProductDO> productDOs = new ArrayList<>();
-        products.forEach(item -> {
-            CombinationProductDO productDO = new CombinationProductDO();
-            productDO.setActivityId(activityDO.getId());
-            productDO.setSpuId(item.getSpuId());
-            productDO.setSkuId(item.getSkuId());
-            productDO.setActivityStatus(0); // TODO 拼团状态枚举未定义不确定有些什么状态
-            productDO.setActivityStartTime(activityDO.getStartTime());
-            productDO.setActivityEndTime(activityDO.getEndTime());
-            productDO.setActivePrice(item.getActivePrice());
-            productDOs.add(productDO);
+    @Mappings({
+            @Mapping(target = "id", ignore = true),
+            @Mapping(target = "activityId", source = "activityDO.id"),
+            @Mapping(target = "spuId", source = "activityDO.spuId"),
+            @Mapping(target = "skuId", source = "vo.skuId"),
+            @Mapping(target = "activePrice", source = "vo.activePrice"),
+            @Mapping(target = "activityStartTime", source = "activityDO.startTime"),
+            @Mapping(target = "activityEndTime", source = "activityDO.endTime")
+    })
+    CombinationProductDO convert(CombinationActivityDO activityDO, CombinationProductBaseVO vo);
+
+    default List<CombinationProductDO> convertList(CombinationActivityDO activityDO, List<? extends CombinationProductBaseVO> products) {
+        List<CombinationProductDO> list = new ArrayList<>();
+        products.forEach(sku -> {
+            CombinationProductDO productDO = convert(activityDO, sku);
+            // TODO 状态设置
+            productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
+            list.add(productDO);
         });
-        return productDOs;
+        return list;
     }
+
+    default List<CombinationProductDO> convertList1(CombinationActivityDO activityDO, List<CombinationProductUpdateReqVO> vos, List<CombinationProductDO> productDOs) {
+        Map<Long, Long> longMap = CollectionUtils.convertMap(productDOs, CombinationProductDO::getSkuId, CombinationProductDO::getId);
+        List<CombinationProductDO> list = new ArrayList<>();
+        vos.forEach(sku -> {
+            CombinationProductDO productDO = convert(activityDO, sku);
+            productDO.setId(longMap.get(sku.getSkuId()));
+            productDO.setActivityStatus(CommonStatusEnum.ENABLE.getStatus());
+            list.add(productDO);
+        });
+        return list;
+    }
+
 }

+ 1 - 5
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
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
 import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
 
 import java.time.LocalDateTime;
-import java.util.List;
 
 /**
  * 拼团活动 DO
@@ -39,8 +36,7 @@ public class CombinationActivityDO extends BaseDO {
     /**
      * 商品 SPU 编号关联 ProductSpuDO 的 id
      */
-    @TableField(typeHandler = LongListTypeHandler.class)
-    private List<Long> spuIds;
+    private Long spuId;
     /**
      * 总限购数量
      */

+ 1 - 0
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<CombinationActivi
     default List<CombinationActivityDO> selectListByStatus(Integer status) {
         return selectList(CombinationActivityDO::getStatus, status);
     }
+
 }

+ 4 - 0
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<CombinationProduct
                 .orderByDesc(CombinationProductDO::getId));
     }
 
+    default List<CombinationProductDO> selectListByActivityId(Long id) {
+        return selectList(CombinationProductDO::getActivityId, id);
+    }
+
 }

+ 8 - 0
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
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
+import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
 
 import javax.validation.Valid;
 import java.util.Collection;
@@ -72,4 +73,11 @@ public interface CombinationActivityService {
      */
     List<CombinationActivityDO> getCombinationActivityList(CombinationActivityExportReqVO exportReqVO);
 
+    /**
+     * 获得拼团活动商品列表
+     *
+     * @param id 拼团活动 ID
+     * @return 拼团活动的商品列表
+     */
+    List<CombinationProductDO> getProductsByActivityId(Long id);
 }

+ 80 - 21
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java

@@ -1,9 +1,11 @@
 package cn.iocoder.yudao.module.promotion.service.combination;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
@@ -13,6 +15,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activit
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductCreateReqVO;
+import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.product.CombinationProductUpdateReqVO;
 import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationActivityDO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.combinationactivity.CombinationProductDO;
@@ -22,15 +25,13 @@ import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
-import java.util.stream.Collectors;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
-import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_NOT_EXISTS;
-import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINATION_ACTIVITY_SPU_CONFLICTS;
+import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
 import static cn.iocoder.yudao.module.promotion.util.PromotionUtils.validateProductSkuExistence;
 
 /**
@@ -54,9 +55,9 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
     @Override
     public Long createCombinationActivity(CombinationActivityCreateReqVO createReqVO) {
         // 校验商品 SPU 是否存在是否参加的别的活动
-        validateProductCombinationConflict(createReqVO.getSpuIds());
+        validateProductCombinationConflict(createReqVO.getSpuId(), null);
         // 获取所选 spu下的所有 sku
-        List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(createReqVO.getSpuIds());
+        List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(createReqVO.getSpuId()));
         // 校验商品 sku 是否存在
         validateProductSkuExistence(skus, createReqVO.getProducts(), CombinationProductCreateReqVO::getSkuId);
 
@@ -79,21 +80,20 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
         return activityDO.getId();
     }
 
-    private void validateProductCombinationConflict(List<Long> spuIds) {
+    private void validateProductCombinationConflict(Long spuId, Long activityId) {
         // 校验商品 spu 是否存在
-        List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);
-        if (ObjectUtil.notEqual(spuIds.size(), spuList.size())) {
+        List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(CollUtil.newArrayList(spuId));
+        if (CollUtil.isEmpty(spuList)) {
             throw exception(SPU_NOT_EXISTS);
         }
-        // 查询所有开启的秒杀活动
+        // 查询所有开启的拼团活动
         List<CombinationActivityDO> activityDOs = combinationActivityMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
+        // 更新时排除自己
+        if (activityId != null) {
+            activityDOs.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
+        }
         // 过滤出所有 spuIds 有交集的活动
-        List<CombinationActivityDO> doList = activityDOs.stream().filter(s -> {
-            // 判断 spu 是否有交集
-            ArrayList<Long> spuIdsClone = CollUtil.newArrayList(s.getSpuIds());
-            spuIdsClone.retainAll(spuIds);
-            return CollUtil.isNotEmpty(spuIdsClone);
-        }).collect(Collectors.toList());
+        List<CombinationActivityDO> doList = CollectionUtils.convertList(activityDOs, c -> c, s -> ObjectUtil.equal(s.getId(), spuId));
         if (CollUtil.isNotEmpty(doList)) {
             throw exception(COMBINATION_ACTIVITY_SPU_CONFLICTS);
         }
@@ -102,29 +102,83 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
     @Override
     public void updateCombinationActivity(CombinationActivityUpdateReqVO updateReqVO) {
         // 校验存在
-        validateCombinationActivityExists(updateReqVO.getId());
+        CombinationActivityDO activityDO = validateCombinationActivityExists(updateReqVO.getId());
+        // 校验状态
+        if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
+            throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
+        }
+        // 校验商品冲突
+        validateProductCombinationConflict(updateReqVO.getSpuId(), updateReqVO.getId());
+        // 获取所选 spu下的所有 sku
+        List<ProductSkuRespDTO> skus = productSkuApi.getSkuListBySpuId(CollectionUtil.newArrayList(updateReqVO.getSpuId()));
+        // 校验商品 sku 是否存在
+        validateProductSkuExistence(skus, updateReqVO.getProducts(), CombinationProductUpdateReqVO::getSkuId);
+
         // 更新
         CombinationActivityDO updateObj = CombinationActivityConvert.INSTANCE.convert(updateReqVO);
         combinationActivityMapper.updateById(updateObj);
+        // 更新商品
+        updateCombinationProduct(updateObj, updateReqVO.getProducts());
+    }
+
+    /**
+     * 更新秒杀商品
+     *  TODO 更新商品要不要封装成通用方法
+     *
+     * @param updateObj DO
+     * @param products  商品配置
+     */
+    private void updateCombinationProduct(CombinationActivityDO updateObj, List<CombinationProductUpdateReqVO> products) {
+        List<CombinationProductDO> combinationProductDOs = combinationProductMapper.selectListByActivityId(updateObj.getId());
+        // 数据库中的活动商品
+        Set<Long> convertSet = CollectionUtils.convertSet(combinationProductDOs, CombinationProductDO::getSkuId);
+        // 前端传过来的活动商品
+        Set<Long> convertSet1 = CollectionUtils.convertSet(products, CombinationProductUpdateReqVO::getSkuId);
+        // 删除后台存在的前端不存在的商品
+        List<Long> d = CollectionUtils.filterList(convertSet, item -> !convertSet1.contains(item));
+        if (CollUtil.isNotEmpty(d)) {
+            combinationProductMapper.deleteBatchIds(d);
+        }
+        // 前端存在的后端不存在的商品
+        List<Long> c = CollectionUtils.filterList(convertSet1, item -> !convertSet.contains(item));
+        if (CollUtil.isNotEmpty(c)) {
+            List<CombinationProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> c.contains(item.getSkuId()));
+            List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList(updateObj, vos);
+            combinationProductMapper.insertBatch(productDOs);
+        }
+        // 更新已存在的商品
+        List<Long> u = CollectionUtils.filterList(convertSet1, convertSet::contains);
+        if (CollUtil.isNotEmpty(u)) {
+            List<CombinationProductUpdateReqVO> vos = CollectionUtils.filterList(products, item -> u.contains(item.getSkuId()));
+            List<CombinationProductDO> productDOs = CombinationActivityConvert.INSTANCE.convertList1(updateObj, vos, combinationProductDOs);
+            combinationProductMapper.updateBatch(productDOs);
+        }
     }
 
     @Override
     public void deleteCombinationActivity(Long id) {
         // 校验存在
-        validateCombinationActivityExists(id);
+        CombinationActivityDO activityDO = validateCombinationActivityExists(id);
+        // 校验状态
+        if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
+            throw exception(COMBINATION_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
+        }
+
         // 删除
         combinationActivityMapper.deleteById(id);
     }
 
-    private void validateCombinationActivityExists(Long id) {
-        if (combinationActivityMapper.selectById(id) == null) {
+    private CombinationActivityDO validateCombinationActivityExists(Long id) {
+        CombinationActivityDO activityDO = combinationActivityMapper.selectById(id);
+        if (activityDO == null) {
             throw exception(COMBINATION_ACTIVITY_NOT_EXISTS);
         }
+        return activityDO;
     }
 
     @Override
     public CombinationActivityDO getCombinationActivity(Long id) {
-        return combinationActivityMapper.selectById(id);
+        return validateCombinationActivityExists(id);
     }
 
     @Override
@@ -142,4 +196,9 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
         return combinationActivityMapper.selectList(exportReqVO);
     }
 
+    @Override
+    public List<CombinationProductDO> getProductsByActivityId(Long id) {
+        return combinationProductMapper.selectListByActivityId(id);
+    }
+
 }