Commit a6ec3fefcf1d9174be7f273f63c7019829ceb827

Authored by YunaiV
1 parent c06d3c3d

code review:优惠劵发放

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&lt;CouponTemplateDO&gt; { @@ -33,7 +33,7 @@ public interface CouponTemplateMapper extends BaseMapperX&lt;CouponTemplateDO&gt; {
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 }