Commit 51797e0dede7441af34a3e3acd6af79e1298cc92

Authored by puhui999
1 parent afd5a9c8

【代码优化】商城: 满减送活动校验规则

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
... ... @@ -44,8 +44,7 @@ public interface ErrorCodeConstants {
44 44 ErrorCode REWARD_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_006_002, "满减送活动已关闭,不能修改");
45 45 ErrorCode REWARD_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_006_003, "满减送活动未关闭,不能删除");
46 46 ErrorCode REWARD_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_006_004, "满减送活动已关闭,不能重复关闭");
47   - ErrorCode REWARD_ACTIVITY_SCOPE_ALL_EXISTS = new ErrorCode(1_013_006_005, "该时间段已存在商品范围为全场的满减送活动");
48   - ErrorCode REWARD_ACTIVITY_SCOPE_CATEGORY_EXISTS = new ErrorCode(1_013_006_006, "该时间段存在商品类型参加了其它满减送活动");
  47 + ErrorCode REWARD_ACTIVITY_SCOPE_EXISTS = new ErrorCode(1_013_006_005, "与该时间段已存在的满减送活动商品范围冲突。注意商品范围 全部 > 分类 > 商品");
49 48  
50 49 // ========== TODO 空着 1-013-007-000 ============
51 50  
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardActivityServiceImpl.java
... ... @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 7 import cn.iocoder.yudao.module.product.api.category.ProductCategoryApi;
8 8 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
  9 +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
9 10 import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityBaseVO;
10 11 import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityCreateReqVO;
11 12 import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO;
... ... @@ -24,6 +25,7 @@ import java.util.Objects;
24 25  
25 26 import static cn.hutool.core.collection.CollUtil.intersectionDistinct;
26 27 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
27 29 import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
28 30  
29 31 /**
... ... @@ -121,8 +123,7 @@ public class RewardActivityServiceImpl implements RewardActivityService {
121 123 list.removeIf(activity -> id.equals(activity.getId()));
122 124 }
123 125  
124   - // TODO @puhui999:这个可能要完整对标有赞的校验。完全不允许重叠。
125   - // 例如说,rewardActivity 是全部活动,结果有个 db 里的 activity 是某个分类,它也是冲突的。也就是说,当前时间段内,有且仅有只能有一个活动!
  126 + // 完全不允许重叠。
126 127 for (RewardActivityDO item : list) {
127 128 // 1.1 校验满减送活动时间是否冲突,如果时段不冲突那么不同的时间段内则可以存在相同的商品范围
128 129 if (!LocalDateTimeUtil.isOverlap(item.getStartTime(), item.getEndTime(),
... ... @@ -130,15 +131,44 @@ public class RewardActivityServiceImpl implements RewardActivityService {
130 131 continue;
131 132 }
132 133 // 1.2 校验商品范围是否重叠
133   - if (PromotionProductScopeEnum.isAll(rewardActivity.getProductScope()) &&
134   - PromotionProductScopeEnum.isAll(item.getProductScope())) { // 情况一:全部商品参加
135   - throw exception(REWARD_ACTIVITY_SCOPE_ALL_EXISTS);
  134 + // 情况一:如果与该时间段内商品范围为全部的活动冲突,或 rewardActivity 商品范围为全部,那么则直接校验不通过
  135 + // 例如说,rewardActivity 是全部活动,结果有个 db 里的 activity 是某个分类,它也是冲突的。也就是说,当前时间段内,有且仅有只能有一个活动!
  136 + if (PromotionProductScopeEnum.isAll(item.getProductScope()) ||
  137 + PromotionProductScopeEnum.isAll(rewardActivity.getProductScope())) {
  138 + throw exception(REWARD_ACTIVITY_SCOPE_EXISTS);
136 139 }
137   - if (PromotionProductScopeEnum.isSpu(rewardActivity.getProductScope()) || // 情况二:指定商品参加
138   - PromotionProductScopeEnum.isCategory(rewardActivity.getProductScope())) { // 情况三:指定商品类型参加
139   - if (!intersectionDistinct(item.getProductScopeValues(), rewardActivity.getProductScopeValues()).isEmpty()) {
140   - throw exception(PromotionProductScopeEnum.isSpu(rewardActivity.getProductScope()) ?
141   - REWARD_ACTIVITY_SPU_CONFLICTS : REWARD_ACTIVITY_SCOPE_CATEGORY_EXISTS);
  140 + // 情况二:如果与该时间段内商品范围为类别的活动冲突
  141 + if (PromotionProductScopeEnum.isCategory(item.getProductScope())) {
  142 + // 校验分类是否冲突
  143 + if (PromotionProductScopeEnum.isCategory(rewardActivity.getProductScope())) {
  144 + if (!intersectionDistinct(item.getProductScopeValues(), rewardActivity.getProductScopeValues()).isEmpty()) {
  145 + throw exception(REWARD_ACTIVITY_SCOPE_EXISTS);
  146 + }
  147 + }
  148 + // 校验商品分类是否冲突
  149 + if (PromotionProductScopeEnum.isSpu(rewardActivity.getProductScope())) {
  150 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(rewardActivity.getProductScopeValues());
  151 + if (!intersectionDistinct(item.getProductScopeValues(),
  152 + convertSet(spuList, ProductSpuRespDTO::getCategoryId)).isEmpty()) {
  153 + throw exception(REWARD_ACTIVITY_SCOPE_EXISTS);
  154 + }
  155 + }
  156 + }
  157 + // 情况三:如果与该时间段内商品范围为商品的活动冲突
  158 + if (PromotionProductScopeEnum.isSpu(item.getProductScope())) {
  159 + // 校验商品是否冲突
  160 + if (PromotionProductScopeEnum.isSpu(rewardActivity.getProductScope())) {
  161 + if (!intersectionDistinct(item.getProductScopeValues(), rewardActivity.getProductScopeValues()).isEmpty()) {
  162 + throw exception(REWARD_ACTIVITY_SCOPE_EXISTS);
  163 + }
  164 + }
  165 + // 校验商品分类是否冲突
  166 + if (PromotionProductScopeEnum.isCategory(rewardActivity.getProductScope())) {
  167 + List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(item.getProductScopeValues());
  168 + if (!intersectionDistinct(rewardActivity.getProductScopeValues(),
  169 + convertSet(spuList, ProductSpuRespDTO::getCategoryId)).isEmpty()) {
  170 + throw exception(REWARD_ACTIVITY_SCOPE_EXISTS);
  171 + }
142 172 }
143 173 }
144 174 }
... ...