Commit 342c25c0dd96c0796eeab8a32837fde1edf26ab3

Authored by puhui999
1 parent 51fdbb81

【代码优化】商城: 完善积分商城

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
@@ -46,7 +46,10 @@ public interface ErrorCodeConstants { @@ -46,7 +46,10 @@ public interface ErrorCodeConstants {
46 46
47 // ========== 积分商城活动 1-013-007-000 ========== 47 // ========== 积分商城活动 1-013-007-000 ==========
48 ErrorCode POINT_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_007_000, "积分商城活动不存在"); 48 ErrorCode POINT_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_007_000, "积分商城活动不存在");
49 - ErrorCode POINT_PRODUCT_NOT_EXISTS = new ErrorCode(1_013_007_100, "积分商城商品不存在"); 49 + ErrorCode POINT_ACTIVITY_SPU_CONFLICTS = new ErrorCode(1_013_007_001, "存在商品参加了其它积分商城活动");
  50 + ErrorCode POINT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_002, "积分商城活动已关闭,不能修改");
  51 + ErrorCode POINT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_007_003, "积分商城活动未关闭或未结束,不能删除");
  52 + ErrorCode POINT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_007_004, "积分商城活动已关闭,不能重复关闭");
50 53
51 // ========== 秒杀活动 1-013-008-000 ========== 54 // ========== 秒杀活动 1-013-008-000 ==========
52 ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_008_000, "秒杀活动不存在"); 55 ErrorCode SECKILL_ACTIVITY_NOT_EXISTS = new ErrorCode(1_013_008_000, "秒杀活动不存在");
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/point/PointActivityController.java
@@ -51,6 +51,15 @@ public class PointActivityController { @@ -51,6 +51,15 @@ public class PointActivityController {
51 return success(true); 51 return success(true);
52 } 52 }
53 53
  54 + @PutMapping("/close")
  55 + @Operation(summary = "关闭积分商城活动")
  56 + @Parameter(name = "id", description = "编号", required = true)
  57 + @PreAuthorize("@ss.hasPermission('promotion:point-activity:close')")
  58 + public CommonResult<Boolean> closeSeckillActivity(@RequestParam("id") Long id) {
  59 + pointActivityService.closePointActivity(id);
  60 + return success(true);
  61 + }
  62 +
54 @DeleteMapping("/delete") 63 @DeleteMapping("/delete")
55 @Operation(summary = "删除积分商城活动") 64 @Operation(summary = "删除积分商城活动")
56 @Parameter(name = "id", description = "编号", required = true) 65 @Parameter(name = "id", description = "编号", required = true)
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/point/vo/product/PointProductSaveReqVO.java
@@ -25,7 +25,7 @@ public class PointProductSaveReqVO { @@ -25,7 +25,7 @@ public class PointProductSaveReqVO {
25 25
26 @Schema(description = "可兑换数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3926") 26 @Schema(description = "可兑换数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "3926")
27 @NotNull(message = "可兑换数量不能为空") 27 @NotNull(message = "可兑换数量不能为空")
28 - private Integer maxCount; 28 + private Integer count;
29 29
30 @Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED) 30 @Schema(description = "兑换积分", requiredMode = Schema.RequiredMode.REQUIRED)
31 @NotNull(message = "兑换积分不能为空") 31 @NotNull(message = "兑换积分不能为空")
@@ -35,9 +35,9 @@ public class PointProductSaveReqVO { @@ -35,9 +35,9 @@ public class PointProductSaveReqVO {
35 @NotNull(message = "兑换金额,单位:分不能为空") 35 @NotNull(message = "兑换金额,单位:分不能为空")
36 private Integer price; 36 private Integer price;
37 37
38 - @Schema(description = "兑换类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")  
39 - @NotNull(message = "兑换类型不能为空")  
40 - private Integer type; 38 + @Schema(description = "积分商城商品库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
  39 + @NotNull(message = "积分商城商品不能为空")
  40 + private Integer stock;
41 41
42 @Schema(description = "积分商城商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 42 @Schema(description = "积分商城商品状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
43 @NotNull(message = "积分商城商品状态不能为空") 43 @NotNull(message = "积分商城商品状态不能为空")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/point/PointActivityDO.java
@@ -45,4 +45,13 @@ public class PointActivityDO extends BaseDO { @@ -45,4 +45,13 @@ public class PointActivityDO extends BaseDO {
45 */ 45 */
46 private Integer sort; 46 private Integer sort;
47 47
  48 + /**
  49 + * 积分商城活动库存(剩余库存积分兑换时扣减)
  50 + */
  51 + private Integer stock;
  52 + /**
  53 + * 积分商城活动总库存
  54 + */
  55 + private Integer totalStock;
  56 +
48 } 57 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/point/PointProductDO.java
@@ -42,24 +42,21 @@ public class PointProductDO extends BaseDO { @@ -42,24 +42,21 @@ public class PointProductDO extends BaseDO {
42 */ 42 */
43 private Long skuId; 43 private Long skuId;
44 /** 44 /**
45 - * 可兑换数量 45 + * 可兑换次数
46 */ 46 */
47 - private Integer maxCount; 47 + private Integer count;
48 /** 48 /**
49 - * 兑换积分 49 + * 所需兑换积分
50 */ 50 */
51 private Integer point; 51 private Integer point;
52 /** 52 /**
53 - * 兑换金额,单位:分 53 + * 所需兑换金额,单位:分
54 */ 54 */
55 private Integer price; 55 private Integer price;
56 /** 56 /**
57 - * 兑换类型  
58 - * 1. 积分  
59 - * 2. 积分 + 钱  
60 - * 3. 直接购买 57 + * 积分商城商品库存
61 */ 58 */
62 - private Integer type; 59 + private Integer stock;
63 /** 60 /**
64 * 积分商城商品状态 61 * 积分商城商品状态
65 * 62 *
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/pointproduct/PointProductDO.java deleted
1 -package cn.iocoder.yudao.module.promotion.dal.dataobject.pointproduct;  
2 -  
3 -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;  
4 -import com.baomidou.mybatisplus.annotation.KeySequence;  
5 -import com.baomidou.mybatisplus.annotation.TableId;  
6 -import com.baomidou.mybatisplus.annotation.TableName;  
7 -import lombok.*;  
8 -  
9 -/**  
10 - * 积分商城商品 DO  
11 - *  
12 - * @author HUIHUI  
13 - */  
14 -@TableName("promotion_point_product")  
15 -@KeySequence("promotion_point_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
16 -@Data  
17 -@EqualsAndHashCode(callSuper = true)  
18 -@ToString(callSuper = true)  
19 -@Builder  
20 -@NoArgsConstructor  
21 -@AllArgsConstructor  
22 -public class PointProductDO extends BaseDO {  
23 -  
24 - /**  
25 - * 积分商城商品编号  
26 - */  
27 - @TableId  
28 - private Long id;  
29 - /**  
30 - * 积分商城活动 id  
31 - */  
32 - private Long activityId;  
33 - /**  
34 - * 商品 SPU 编号  
35 - */  
36 - private Long spuId;  
37 - /**  
38 - * 商品 SKU 编号  
39 - */  
40 - private Long skuId;  
41 - /**  
42 - * 可兑换数量  
43 - */  
44 - private Integer maxCount;  
45 - /**  
46 - * 兑换积分  
47 - */  
48 - private Integer point;  
49 - /**  
50 - * 兑换金额,单位:分  
51 - */  
52 - private Integer price;  
53 - /**  
54 - * 兑换类型  
55 - */  
56 - private Integer type;  
57 - /**  
58 - * 积分商城商品状态  
59 - */  
60 - private Integer activityStatus;  
61 -  
62 -}  
63 \ No newline at end of file 0 \ No newline at end of file
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/point/PointProductMapper.java
@@ -4,9 +4,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,9 +4,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6 import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductPageReqVO; 6 import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductPageReqVO;
7 -import cn.iocoder.yudao.module.promotion.dal.dataobject.pointproduct.PointProductDO; 7 +import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointProductDO;
  8 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
8 import org.apache.ibatis.annotations.Mapper; 9 import org.apache.ibatis.annotations.Mapper;
9 10
  11 +import java.util.Collection;
  12 +import java.util.List;
  13 +
10 /** 14 /**
11 * 积分商城商品 Mapper 15 * 积分商城商品 Mapper
12 * 16 *
@@ -20,13 +24,24 @@ public interface PointProductMapper extends BaseMapperX&lt;PointProductDO&gt; { @@ -20,13 +24,24 @@ public interface PointProductMapper extends BaseMapperX&lt;PointProductDO&gt; {
20 .eqIfPresent(PointProductDO::getActivityId, reqVO.getActivityId()) 24 .eqIfPresent(PointProductDO::getActivityId, reqVO.getActivityId())
21 .eqIfPresent(PointProductDO::getSpuId, reqVO.getSpuId()) 25 .eqIfPresent(PointProductDO::getSpuId, reqVO.getSpuId())
22 .eqIfPresent(PointProductDO::getSkuId, reqVO.getSkuId()) 26 .eqIfPresent(PointProductDO::getSkuId, reqVO.getSkuId())
23 - .eqIfPresent(PointProductDO::getMaxCount, reqVO.getMaxCount())  
24 .eqIfPresent(PointProductDO::getPoint, reqVO.getPoint()) 27 .eqIfPresent(PointProductDO::getPoint, reqVO.getPoint())
25 .eqIfPresent(PointProductDO::getPrice, reqVO.getPrice()) 28 .eqIfPresent(PointProductDO::getPrice, reqVO.getPrice())
26 - .eqIfPresent(PointProductDO::getType, reqVO.getType())  
27 .eqIfPresent(PointProductDO::getActivityStatus, reqVO.getActivityStatus()) 29 .eqIfPresent(PointProductDO::getActivityStatus, reqVO.getActivityStatus())
28 .betweenIfPresent(PointProductDO::getCreateTime, reqVO.getCreateTime()) 30 .betweenIfPresent(PointProductDO::getCreateTime, reqVO.getCreateTime())
29 .orderByDesc(PointProductDO::getId)); 31 .orderByDesc(PointProductDO::getId));
30 } 32 }
31 33
  34 + default List<PointProductDO> selectListByActivityId(Collection<Long> activityIds) {
  35 + return selectList(PointProductDO::getActivityId, activityIds);
  36 + }
  37 +
  38 + default List<PointProductDO> selectListByActivityId(Long activityId) {
  39 + return selectList(PointProductDO::getActivityId, activityId);
  40 + }
  41 +
  42 + default void updateByActivityId(PointProductDO pointProductDO) {
  43 + update(pointProductDO, new LambdaUpdateWrapper<PointProductDO>()
  44 + .eq(PointProductDO::getActivityId, pointProductDO.getActivityId()));
  45 + }
  46 +
32 } 47 }
33 \ No newline at end of file 48 \ No newline at end of file
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityService.java
@@ -29,6 +29,13 @@ public interface PointActivityService { @@ -29,6 +29,13 @@ public interface PointActivityService {
29 void updatePointActivity(@Valid PointActivitySaveReqVO updateReqVO); 29 void updatePointActivity(@Valid PointActivitySaveReqVO updateReqVO);
30 30
31 /** 31 /**
  32 + * 关闭积分商城活动
  33 + *
  34 + * @param id 编号
  35 + */
  36 + void closePointActivity(Long id);
  37 +
  38 + /**
32 * 删除积分商城活动 39 * 删除积分商城活动
33 * 40 *
34 * @param id 编号 41 * @param id 编号
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/point/PointActivityServiceImpl.java
1 package cn.iocoder.yudao.module.promotion.service.point; 1 package cn.iocoder.yudao.module.promotion.service.point;
2 2
  3 +import cn.hutool.core.util.ObjectUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; 7 import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
@@ -10,6 +12,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.Poin @@ -10,6 +12,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.Poin
10 import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO; 12 import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.activity.PointActivitySaveReqVO;
11 import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductSaveReqVO; 13 import cn.iocoder.yudao.module.promotion.controller.admin.point.vo.product.PointProductSaveReqVO;
12 import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO; 14 import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointActivityDO;
  15 +import cn.iocoder.yudao.module.promotion.dal.dataobject.point.PointProductDO;
13 import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointActivityMapper; 16 import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointActivityMapper;
14 import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointProductMapper; 17 import cn.iocoder.yudao.module.promotion.dal.mysql.point.PointProductMapper;
15 import jakarta.annotation.Resource; 18 import jakarta.annotation.Resource;
@@ -19,15 +22,16 @@ import org.springframework.validation.annotation.Validated; @@ -19,15 +22,16 @@ import org.springframework.validation.annotation.Validated;
19 import java.util.List; 22 import java.util.List;
20 import java.util.Map; 23 import java.util.Map;
21 24
  25 +import static cn.hutool.core.collection.CollUtil.intersectionDistinct;
  26 +import static cn.hutool.core.collection.CollUtil.isNotEmpty;
22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
23 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; 28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
24 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; 30 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
25 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; 31 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
26 -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.POINT_ACTIVITY_NOT_EXISTS; 32 +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
27 import static java.util.Collections.singletonList; 33 import static java.util.Collections.singletonList;
28 34
29 -// TODO @puhui999: 下次提交完善  
30 -  
31 /** 35 /**
32 * 积分商城活动 Service 实现类 36 * 积分商城活动 Service 实现类
33 * 37 *
@@ -47,13 +51,27 @@ public class PointActivityServiceImpl implements PointActivityService { @@ -47,13 +51,27 @@ public class PointActivityServiceImpl implements PointActivityService {
47 @Resource 51 @Resource
48 private ProductSkuApi productSkuApi; 52 private ProductSkuApi productSkuApi;
49 53
  54 + private static List<PointProductDO> buildPointProductDO(PointActivityDO pointActivity, List<PointProductSaveReqVO> products) {
  55 + return BeanUtils.toBean(products, PointProductDO.class, product -> {
  56 + product.setActivityId(pointActivity.getId()).setActivityStatus(pointActivity.getStatus());
  57 + });
  58 + }
  59 +
50 @Override 60 @Override
51 public Long createPointActivity(PointActivitySaveReqVO createReqVO) { 61 public Long createPointActivity(PointActivitySaveReqVO createReqVO) {
52 - // 1. 校验商品是否存在 62 + // 1.1 校验商品是否存在
53 validateProductExists(createReqVO.getSpuId(), createReqVO.getProducts()); 63 validateProductExists(createReqVO.getSpuId(), createReqVO.getProducts());
54 - // 插入  
55 - PointActivityDO pointActivity = BeanUtils.toBean(createReqVO, PointActivityDO.class); 64 + // 1.2 校验商品是否已经参加别的活动
  65 + validatePointActivityProductConflicts(null, createReqVO.getProducts());
  66 +
  67 + // 2.1 插入积分商城活动
  68 + PointActivityDO pointActivity = BeanUtils.toBean(createReqVO, PointActivityDO.class)
  69 + .setStatus(CommonStatusEnum.ENABLE.getStatus())
  70 + .setStock(getSumValue(createReqVO.getProducts(), PointProductSaveReqVO::getStock, Integer::sum));
  71 + pointActivity.setTotalStock(pointActivity.getStock());
56 pointActivityMapper.insert(pointActivity); 72 pointActivityMapper.insert(pointActivity);
  73 + // 2.2 插入积分商城活动商品
  74 + pointProductMapper.insertBatch(buildPointProductDO(pointActivity, createReqVO.getProducts()));
57 // 返回 75 // 返回
58 return pointActivity.getId(); 76 return pointActivity.getId();
59 } 77 }
@@ -61,27 +79,92 @@ public class PointActivityServiceImpl implements PointActivityService { @@ -61,27 +79,92 @@ public class PointActivityServiceImpl implements PointActivityService {
61 @Override 79 @Override
62 public void updatePointActivity(PointActivitySaveReqVO updateReqVO) { 80 public void updatePointActivity(PointActivitySaveReqVO updateReqVO) {
63 // 1.1 校验存在 81 // 1.1 校验存在
64 - validatePointActivityExists(updateReqVO.getId()); 82 + PointActivityDO activity = validatePointActivityExists(updateReqVO.getId());
  83 + if (CommonStatusEnum.DISABLE.getStatus().equals(activity.getStatus())) {
  84 + throw exception(POINT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED);
  85 + }
65 // 1.2 校验商品是否存在 86 // 1.2 校验商品是否存在
66 validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts()); 87 validateProductExists(updateReqVO.getSpuId(), updateReqVO.getProducts());
  88 + // 1.3 校验商品是否已经参加别的活动
  89 + validatePointActivityProductConflicts(updateReqVO.getId(), updateReqVO.getProducts());
  90 +
  91 + // 2.1 更新积分商城活动
  92 + PointActivityDO updateObj = BeanUtils.toBean(updateReqVO, PointActivityDO.class)
  93 + .setStock(getSumValue(updateReqVO.getProducts(), PointProductSaveReqVO::getStock, Integer::sum));
  94 + if (updateObj.getStock() > activity.getTotalStock()) { // 如果更新的库存大于原来的库存,则更新总库存
  95 + updateObj.setTotalStock(updateObj.getStock());
  96 + }
  97 + pointActivityMapper.updateById(updateObj);
  98 + // 2.2 更新商品
  99 + updateSeckillProduct(updateObj, updateReqVO.getProducts());
  100 + }
  101 +
  102 + @Override
  103 + public void closePointActivity(Long id) {
  104 + // 校验存在
  105 + PointActivityDO pointActivity = validatePointActivityExists(id);
  106 + if (CommonStatusEnum.DISABLE.getStatus().equals(pointActivity.getStatus())) {
  107 + throw exception(POINT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED);
  108 + }
67 109
68 // 更新 110 // 更新
69 - PointActivityDO updateObj = BeanUtils.toBean(updateReqVO, PointActivityDO.class);  
70 - pointActivityMapper.updateById(updateObj); 111 + pointActivityMapper.updateById(new PointActivityDO().setId(id).setStatus(CommonStatusEnum.DISABLE.getStatus()));
  112 + // 更新活动商品状态
  113 + pointProductMapper.updateByActivityId(new PointProductDO().setActivityId(id).setActivityStatus(
  114 + CommonStatusEnum.DISABLE.getStatus()));
  115 + }
  116 +
  117 + /**
  118 + * 更新秒杀商品
  119 + *
  120 + * @param activity 秒杀活动
  121 + * @param products 该活动的最新商品配置
  122 + */
  123 + private void updateSeckillProduct(PointActivityDO activity, List<PointProductSaveReqVO> products) {
  124 + // 第一步,对比新老数据,获得添加、修改、删除的列表
  125 + List<PointProductDO> newList = buildPointProductDO(activity, products);
  126 + List<PointProductDO> oldList = pointProductMapper.selectListByActivityId(activity.getId());
  127 + List<List<PointProductDO>> diffList = diffList(oldList, newList, (oldVal, newVal) -> {
  128 + boolean same = ObjectUtil.equal(oldVal.getSkuId(), newVal.getSkuId());
  129 + if (same) {
  130 + newVal.setId(oldVal.getId());
  131 + }
  132 + return same;
  133 + });
  134 +
  135 + // 第二步,批量添加、修改、删除
  136 + if (isNotEmpty(diffList.get(0))) {
  137 + pointProductMapper.insertBatch(diffList.get(0));
  138 + }
  139 + if (isNotEmpty(diffList.get(1))) {
  140 + pointProductMapper.updateBatch(diffList.get(1));
  141 + }
  142 + if (isNotEmpty(diffList.get(2))) {
  143 + pointProductMapper.deleteByIds(convertList(diffList.get(2), PointProductDO::getId));
  144 + }
71 } 145 }
72 146
73 @Override 147 @Override
74 public void deletePointActivity(Long id) { 148 public void deletePointActivity(Long id) {
75 // 校验存在 149 // 校验存在
76 - validatePointActivityExists(id);  
77 - // 删除 150 + PointActivityDO pointActivity = validatePointActivityExists(id);
  151 + if (CommonStatusEnum.ENABLE.getStatus().equals(pointActivity.getStatus())) {
  152 + throw exception(POINT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END);
  153 + }
  154 +
  155 + // 删除商城活动
78 pointActivityMapper.deleteById(id); 156 pointActivityMapper.deleteById(id);
  157 + // 删除活动商品
  158 + List<PointProductDO> products = pointProductMapper.selectListByActivityId(id);
  159 + pointProductMapper.deleteByIds(convertSet(products, PointProductDO::getId));
79 } 160 }
80 161
81 - private void validatePointActivityExists(Long id) {  
82 - if (pointActivityMapper.selectById(id) == null) { 162 + private PointActivityDO validatePointActivityExists(Long id) {
  163 + PointActivityDO pointActivityDO = pointActivityMapper.selectById(id);
  164 + if (pointActivityDO == null) {
83 throw exception(POINT_ACTIVITY_NOT_EXISTS); 165 throw exception(POINT_ACTIVITY_NOT_EXISTS);
84 } 166 }
  167 + return pointActivityDO;
85 } 168 }
86 169
87 /** 170 /**
@@ -107,6 +190,35 @@ public class PointActivityServiceImpl implements PointActivityService { @@ -107,6 +190,35 @@ public class PointActivityServiceImpl implements PointActivityService {
107 }); 190 });
108 } 191 }
109 192
  193 + /**
  194 + * 校验商品是否冲突
  195 + *
  196 + * @param id 编号
  197 + * @param products 商品列表
  198 + */
  199 + private void validatePointActivityProductConflicts(Long id, List<PointProductSaveReqVO> products) {
  200 + // 1.1 查询所有开启的积分商城活动
  201 + List<PointActivityDO> activityList = pointActivityMapper.selectList(PointActivityDO::getStatus,
  202 + CommonStatusEnum.ENABLE.getStatus());
  203 + if (id != null) { // 更新时排除自己
  204 + activityList.removeIf(item -> ObjectUtil.equal(item.getId(), id));
  205 + }
  206 + // 1.2 查询活动下的所有商品
  207 + List<PointProductDO> productList = pointProductMapper.selectListByActivityId(
  208 + convertList(activityList, PointActivityDO::getId));
  209 + Map<Long, List<PointProductDO>> productListMap = convertMultiMap(productList, PointProductDO::getActivityId);
  210 +
  211 + // 2. 校验商品是否冲突
  212 + activityList.forEach(item -> {
  213 + findAndThen(productListMap, item.getId(), discountProducts -> {
  214 + if (!intersectionDistinct(convertList(discountProducts, PointProductDO::getSpuId),
  215 + convertList(products, PointProductSaveReqVO::getSpuId)).isEmpty()) {
  216 + throw exception(POINT_ACTIVITY_SPU_CONFLICTS);
  217 + }
  218 + });
  219 + });
  220 + }
  221 +
110 @Override 222 @Override
111 public PointActivityDO getPointActivity(Long id) { 223 public PointActivityDO getPointActivity(Long id) {
112 return pointActivityMapper.selectById(id); 224 return pointActivityMapper.selectById(id);