Commit a6ec3fefcf1d9174be7f273f63c7019829ceb827
1 parent
c06d3c3d
code review:优惠劵发放
Showing
6 changed files
with
34 additions
and
21 deletions
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java
| @@ -15,8 +15,9 @@ import java.util.Arrays; | @@ -15,8 +15,9 @@ import java.util.Arrays; | ||
| 15 | @AllArgsConstructor | 15 | @AllArgsConstructor |
| 16 | public enum PromotionProductScopeEnum implements IntArrayValuable { | 16 | public enum PromotionProductScopeEnum implements IntArrayValuable { |
| 17 | 17 | ||
| 18 | - ALL(1, "全部商品参与"), | ||
| 19 | - SPU(2, "指定商品参与"), | 18 | + ALL(1, "通用卷"), // 全部商品 |
| 19 | + SPU(2, "商品卷"), // 指定商品 | ||
| 20 | + CATEGORY(3, "品类卷"), // 指定商品 | ||
| 20 | ; | 21 | ; |
| 21 | 22 | ||
| 22 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray(); | 23 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray(); |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponTakeTypeEnum.java
| @@ -15,9 +15,9 @@ import java.util.Arrays; | @@ -15,9 +15,9 @@ import java.util.Arrays; | ||
| 15 | @Getter | 15 | @Getter |
| 16 | public enum CouponTakeTypeEnum implements IntArrayValuable { | 16 | public enum CouponTakeTypeEnum implements IntArrayValuable { |
| 17 | 17 | ||
| 18 | - BY_USER(1, "直接领取"), // 用户可在首页、每日领劵直接领取 | ||
| 19 | - BY_ADMIN(2, "指定发放"), // 后台指定会员赠送优惠劵 | ||
| 20 | - BY_REGISTER(3, "新人券"), // 注册时自动领取 | 18 | + USER(1, "直接领取"), // 用户可在首页、每日领劵直接领取 |
| 19 | + ADMIN(2, "指定发放"), // 后台指定会员赠送优惠劵 | ||
| 20 | + REGISTER(3, "新人券"), // 注册时自动领取 | ||
| 21 | ; | 21 | ; |
| 22 | 22 | ||
| 23 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponTakeTypeEnum::getValue).toArray(); | 23 | public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponTakeTypeEnum::getValue).toArray(); |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java
| 1 | package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; | 1 | package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 5 | +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum; | ||
| 4 | import io.swagger.v3.oas.annotations.media.Schema; | 6 | import io.swagger.v3.oas.annotations.media.Schema; |
| 5 | import lombok.Data; | 7 | import lombok.Data; |
| 6 | import lombok.EqualsAndHashCode; | 8 | import lombok.EqualsAndHashCode; |
| @@ -31,6 +33,8 @@ public class CouponTemplatePageReqVO extends PageParam { | @@ -31,6 +33,8 @@ public class CouponTemplatePageReqVO extends PageParam { | ||
| 31 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 33 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 32 | private LocalDateTime[] createTime; | 34 | private LocalDateTime[] createTime; |
| 33 | 35 | ||
| 34 | - @Schema(description = "可以领取的类型", example = "[1,2]") | 36 | + @Schema(description = "可以领取的类型", example = "[1,2, 3]") |
| 37 | + @InEnum(value = CouponTakeTypeEnum.class, message = "可以领取的类型,必须是 {value}") | ||
| 35 | private List<Integer> canTakeTypes; | 38 | private List<Integer> canTakeTypes; |
| 39 | + | ||
| 36 | } | 40 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java
| @@ -23,9 +23,9 @@ import java.util.function.Consumer; | @@ -23,9 +23,9 @@ import java.util.function.Consumer; | ||
| 23 | public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { | 23 | public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { |
| 24 | 24 | ||
| 25 | default PageResult<CouponTemplateDO> selectPage(CouponTemplatePageReqVO reqVO) { | 25 | default PageResult<CouponTemplateDO> selectPage(CouponTemplatePageReqVO reqVO) { |
| 26 | + // 构建可领取的查询条件, 好啰嗦 ( ╯-_-)╯┴—┴ | ||
| 26 | Consumer<LambdaQueryWrapper<CouponTemplateDO>> canTakeConsumer = null; | 27 | Consumer<LambdaQueryWrapper<CouponTemplateDO>> canTakeConsumer = null; |
| 27 | if (CollUtil.isNotEmpty(reqVO.getCanTakeTypes())) { | 28 | if (CollUtil.isNotEmpty(reqVO.getCanTakeTypes())) { |
| 28 | - // 构建可领取的查询条件, 好啰嗦 ( ╯-_-)╯┴—┴ | ||
| 29 | canTakeConsumer = w -> | 29 | canTakeConsumer = w -> |
| 30 | w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的 | 30 | w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的 |
| 31 | .in(CouponTemplateDO::getTakeType, reqVO.getCanTakeTypes()) // 2. 领取方式一致 | 31 | .in(CouponTemplateDO::getTakeType, reqVO.getCanTakeTypes()) // 2. 领取方式一致 |
| @@ -33,7 +33,7 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { | @@ -33,7 +33,7 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { | ||
| 33 | .or().gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now())) | 33 | .or().gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now())) |
| 34 | .apply(" take_count < total_count "); // 4. 剩余数量大于 0 | 34 | .apply(" take_count < total_count "); // 4. 剩余数量大于 0 |
| 35 | } | 35 | } |
| 36 | - | 36 | + // 执行分页查询 |
| 37 | return selectPage(reqVO, new LambdaQueryWrapperX<CouponTemplateDO>() | 37 | return selectPage(reqVO, new LambdaQueryWrapperX<CouponTemplateDO>() |
| 38 | .likeIfPresent(CouponTemplateDO::getName, reqVO.getName()) | 38 | .likeIfPresent(CouponTemplateDO::getName, reqVO.getName()) |
| 39 | .eqIfPresent(CouponTemplateDO::getStatus, reqVO.getStatus()) | 39 | .eqIfPresent(CouponTemplateDO::getStatus, reqVO.getStatus()) |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java
| @@ -94,7 +94,7 @@ public interface CouponService { | @@ -94,7 +94,7 @@ public interface CouponService { | ||
| 94 | * @param userIds 用户编号列表 | 94 | * @param userIds 用户编号列表 |
| 95 | */ | 95 | */ |
| 96 | default void takeCouponByAdmin(Long templateId, Set<Long> userIds) { | 96 | default void takeCouponByAdmin(Long templateId, Set<Long> userIds) { |
| 97 | - takeCoupon(templateId, userIds, CouponTakeTypeEnum.BY_ADMIN); | 97 | + takeCoupon(templateId, userIds, CouponTakeTypeEnum.ADMIN); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | /** | 100 | /** |
| @@ -104,7 +104,7 @@ public interface CouponService { | @@ -104,7 +104,7 @@ public interface CouponService { | ||
| 104 | * @param userId 用户编号 | 104 | * @param userId 用户编号 |
| 105 | */ | 105 | */ |
| 106 | default void takeCouponByUser(Long templateId, Long userId) { | 106 | default void takeCouponByUser(Long templateId, Long userId) { |
| 107 | - takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.BY_USER); | 107 | + takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.USER); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | /** | 110 | /** |
| @@ -114,6 +114,6 @@ public interface CouponService { | @@ -114,6 +114,6 @@ public interface CouponService { | ||
| 114 | * @param userId 用户编号列表 | 114 | * @param userId 用户编号列表 |
| 115 | */ | 115 | */ |
| 116 | default void takeCouponByRegister(Long templateId, Long userId) { | 116 | default void takeCouponByRegister(Long templateId, Long userId) { |
| 117 | - takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.BY_REGISTER); | 117 | + takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); |
| 118 | } | 118 | } |
| 119 | } | 119 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
| @@ -138,8 +138,8 @@ public class CouponServiceImpl implements CouponService { | @@ -138,8 +138,8 @@ public class CouponServiceImpl implements CouponService { | ||
| 138 | public void takeCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType) { | 138 | public void takeCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType) { |
| 139 | CouponTemplateDO template = couponTemplateService.getCouponTemplate(templateId); | 139 | CouponTemplateDO template = couponTemplateService.getCouponTemplate(templateId); |
| 140 | // 1. 过滤掉达到领取限制的用户 | 140 | // 1. 过滤掉达到领取限制的用户 |
| 141 | - removeTakeLimitUserId(template, userIds); | ||
| 142 | - // 2. 校验用户 | 141 | + removeTakeLimitUserId(userIds, template); |
| 142 | + // 2. 校验优惠劵是否可以领取 | ||
| 143 | validateCanTake(template, userIds, takeType); | 143 | validateCanTake(template, userIds, takeType); |
| 144 | 144 | ||
| 145 | // 3. 批量保存优惠劵 | 145 | // 3. 批量保存优惠劵 |
| @@ -158,7 +158,7 @@ public class CouponServiceImpl implements CouponService { | @@ -158,7 +158,7 @@ public class CouponServiceImpl implements CouponService { | ||
| 158 | */ | 158 | */ |
| 159 | private void validateCanTake(CouponTemplateDO couponTemplate, Set<Long> userIds, CouponTakeTypeEnum takeType) { | 159 | private void validateCanTake(CouponTemplateDO couponTemplate, Set<Long> userIds, CouponTakeTypeEnum takeType) { |
| 160 | // 如果所有用户都领取过,则抛出异常 | 160 | // 如果所有用户都领取过,则抛出异常 |
| 161 | - if (userIds.isEmpty()) { | 161 | + if (CollUtil.isEmpty(userIds)) { |
| 162 | throw exception(COUPON_TEMPLATE_USER_ALREADY_TAKE); | 162 | throw exception(COUPON_TEMPLATE_USER_ALREADY_TAKE); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| @@ -176,22 +176,30 @@ public class CouponServiceImpl implements CouponService { | @@ -176,22 +176,30 @@ public class CouponServiceImpl implements CouponService { | ||
| 176 | throw exception(COUPON_TEMPLATE_EXPIRED); | 176 | throw exception(COUPON_TEMPLATE_EXPIRED); |
| 177 | } | 177 | } |
| 178 | } | 178 | } |
| 179 | - | ||
| 180 | // 校验领取方式 | 179 | // 校验领取方式 |
| 181 | if (ObjectUtil.notEqual(couponTemplate.getTakeType(), takeType.getValue())) { | 180 | if (ObjectUtil.notEqual(couponTemplate.getTakeType(), takeType.getValue())) { |
| 182 | throw exception(COUPON_TEMPLATE_CANNOT_TAKE); | 181 | throw exception(COUPON_TEMPLATE_CANNOT_TAKE); |
| 183 | } | 182 | } |
| 184 | } | 183 | } |
| 185 | 184 | ||
| 186 | - private void removeTakeLimitUserId(CouponTemplateDO couponTemplate, Set<Long> userIds) { | 185 | + /** |
| 186 | + * 过滤掉达到领取上线的用户 | ||
| 187 | + * | ||
| 188 | + * @param userIds 用户编号数组 | ||
| 189 | + * @param couponTemplate 优惠劵模版 | ||
| 190 | + */ | ||
| 191 | + private void removeTakeLimitUserId(Set<Long> userIds, CouponTemplateDO couponTemplate) { | ||
| 192 | + if (couponTemplate.getTakeLimitCount() <= 0) { | ||
| 193 | + return; | ||
| 194 | + } | ||
| 187 | // 查询已领过券的用户 | 195 | // 查询已领过券的用户 |
| 188 | List<CouponDO> alreadyTakeCoupons = couponMapper.selectListByTemplateIdAndUserId(couponTemplate.getId(), userIds); | 196 | List<CouponDO> alreadyTakeCoupons = couponMapper.selectListByTemplateIdAndUserId(couponTemplate.getId(), userIds); |
| 189 | - | ||
| 190 | - // 移除达到领取限制的用户 | ||
| 191 | - if (couponTemplate.getTakeLimitCount() > 0) { | ||
| 192 | - Map<Long, Integer> userTakeCountMap = CollStreamUtil.groupBy(alreadyTakeCoupons, CouponDO::getUserId, Collectors.summingInt(c -> 1)); | ||
| 193 | - userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount()); | 197 | + if (CollUtil.isEmpty(alreadyTakeCoupons)) { |
| 198 | + return; | ||
| 194 | } | 199 | } |
| 200 | + // 移除达到领取限制的用户 | ||
| 201 | + Map<Long, Integer> userTakeCountMap = CollStreamUtil.groupBy(alreadyTakeCoupons, CouponDO::getUserId, Collectors.summingInt(c -> 1)); | ||
| 202 | + userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount()); | ||
| 195 | } | 203 | } |
| 196 | 204 | ||
| 197 | } | 205 | } |