code review:优惠劵发放

This commit is contained in:
YunaiV 2023-09-02 00:31:23 +08:00
parent c06d3c3d26
commit a6ec3fefcf
6 changed files with 34 additions and 21 deletions

View File

@ -15,8 +15,9 @@ import java.util.Arrays;
@AllArgsConstructor
public enum PromotionProductScopeEnum implements IntArrayValuable {
ALL(1, "全部商品参与"),
SPU(2, "指定商品参与"),
ALL(1, "通用卷"), // 全部商品
SPU(2, "商品卷"), // 指定商品
CATEGORY(3, "品类卷"), // 指定商品
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray();

View File

@ -15,9 +15,9 @@ import java.util.Arrays;
@Getter
public enum CouponTakeTypeEnum implements IntArrayValuable {
BY_USER(1, "直接领取"), // 用户可在首页每日领劵直接领取
BY_ADMIN(2, "指定发放"), // 后台指定会员赠送优惠劵
BY_REGISTER(3, "新人券"), // 注册时自动领取
USER(1, "直接领取"), // 用户可在首页每日领劵直接领取
ADMIN(2, "指定发放"), // 后台指定会员赠送优惠劵
REGISTER(3, "新人券"), // 注册时自动领取
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponTakeTypeEnum::getValue).toArray();

View File

@ -1,6 +1,8 @@
package cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.template;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -31,6 +33,8 @@ public class CouponTemplatePageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "可以领取的类型", example = "[1,2]")
@Schema(description = "可以领取的类型", example = "[1,2, 3]")
@InEnum(value = CouponTakeTypeEnum.class, message = "可以领取的类型,必须是 {value}")
private List<Integer> canTakeTypes;
}

View File

@ -23,9 +23,9 @@ import java.util.function.Consumer;
public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> {
default PageResult<CouponTemplateDO> selectPage(CouponTemplatePageReqVO reqVO) {
// 构建可领取的查询条件, 好啰嗦 ( -_-)
Consumer<LambdaQueryWrapper<CouponTemplateDO>> canTakeConsumer = null;
if (CollUtil.isNotEmpty(reqVO.getCanTakeTypes())) {
// 构建可领取的查询条件, 好啰嗦 ( -_-)
canTakeConsumer = w ->
w.eq(CouponTemplateDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) // 1. 状态为可用的
.in(CouponTemplateDO::getTakeType, reqVO.getCanTakeTypes()) // 2. 领取方式一致
@ -33,7 +33,7 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> {
.or().gt(CouponTemplateDO::getValidEndTime, LocalDateTime.now()))
.apply(" take_count < total_count "); // 4. 剩余数量大于 0
}
// 执行分页查询
return selectPage(reqVO, new LambdaQueryWrapperX<CouponTemplateDO>()
.likeIfPresent(CouponTemplateDO::getName, reqVO.getName())
.eqIfPresent(CouponTemplateDO::getStatus, reqVO.getStatus())

View File

@ -94,7 +94,7 @@ public interface CouponService {
* @param userIds 用户编号列表
*/
default void takeCouponByAdmin(Long templateId, Set<Long> userIds) {
takeCoupon(templateId, userIds, CouponTakeTypeEnum.BY_ADMIN);
takeCoupon(templateId, userIds, CouponTakeTypeEnum.ADMIN);
}
/**
@ -104,7 +104,7 @@ public interface CouponService {
* @param userId 用户编号
*/
default void takeCouponByUser(Long templateId, Long userId) {
takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.BY_USER);
takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.USER);
}
/**
@ -114,6 +114,6 @@ public interface CouponService {
* @param userId 用户编号列表
*/
default void takeCouponByRegister(Long templateId, Long userId) {
takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.BY_REGISTER);
takeCoupon(templateId, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER);
}
}

View File

@ -138,8 +138,8 @@ public class CouponServiceImpl implements CouponService {
public void takeCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType) {
CouponTemplateDO template = couponTemplateService.getCouponTemplate(templateId);
// 1. 过滤掉达到领取限制的用户
removeTakeLimitUserId(template, userIds);
// 2. 校验用户
removeTakeLimitUserId(userIds, template);
// 2. 校验优惠劵是否可以领取
validateCanTake(template, userIds, takeType);
// 3. 批量保存优惠劵
@ -158,7 +158,7 @@ public class CouponServiceImpl implements CouponService {
*/
private void validateCanTake(CouponTemplateDO couponTemplate, Set<Long> userIds, CouponTakeTypeEnum takeType) {
// 如果所有用户都领取过则抛出异常
if (userIds.isEmpty()) {
if (CollUtil.isEmpty(userIds)) {
throw exception(COUPON_TEMPLATE_USER_ALREADY_TAKE);
}
@ -176,22 +176,30 @@ public class CouponServiceImpl implements CouponService {
throw exception(COUPON_TEMPLATE_EXPIRED);
}
}
// 校验领取方式
if (ObjectUtil.notEqual(couponTemplate.getTakeType(), takeType.getValue())) {
throw exception(COUPON_TEMPLATE_CANNOT_TAKE);
}
}
private void removeTakeLimitUserId(CouponTemplateDO couponTemplate, Set<Long> userIds) {
/**
* 过滤掉达到领取上线的用户
*
* @param userIds 用户编号数组
* @param couponTemplate 优惠劵模版
*/
private void removeTakeLimitUserId(Set<Long> userIds, CouponTemplateDO couponTemplate) {
if (couponTemplate.getTakeLimitCount() <= 0) {
return;
}
// 查询已领过券的用户
List<CouponDO> alreadyTakeCoupons = couponMapper.selectListByTemplateIdAndUserId(couponTemplate.getId(), userIds);
// 移除达到领取限制的用户
if (couponTemplate.getTakeLimitCount() > 0) {
Map<Long, Integer> userTakeCountMap = CollStreamUtil.groupBy(alreadyTakeCoupons, CouponDO::getUserId, Collectors.summingInt(c -> 1));
userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount());
if (CollUtil.isEmpty(alreadyTakeCoupons)) {
return;
}
// 移除达到领取限制的用户
Map<Long, Integer> userTakeCountMap = CollStreamUtil.groupBy(alreadyTakeCoupons, CouponDO::getUserId, Collectors.summingInt(c -> 1));
userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount());
}
}