Commit c3b5478a26c5366e4b2586074609e4cd65f1be69

Authored by 芋道源码
Committed by GitHub
2 parents 7cae2852 e912e570

Merge pull request #1256 from dadiyang/fix/promotion-register-coupon-expired-abort

[BUG] 促销:新用户完成注册并正常登录,但一张新人券都领不到(—— 任意一张新人券过期,整批发放中断)
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
@@ -215,9 +215,32 @@ public class CouponServiceImpl implements CouponService { @@ -215,9 +215,32 @@ public class CouponServiceImpl implements CouponService {
215 @Transactional(rollbackFor = Exception.class) 215 @Transactional(rollbackFor = Exception.class)
216 public void takeCouponByRegister(Long userId) { 216 public void takeCouponByRegister(Long userId) {
217 List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateListByTakeType(CouponTakeTypeEnum.REGISTER); 217 List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateListByTakeType(CouponTakeTypeEnum.REGISTER);
218 - for (CouponTemplateDO template : templates) {  
219 - takeCoupon(template, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER); 218 + // 1. 过滤不可领取(如已过期)的模板,避免单张异常中断整批
  219 + List<CouponTemplateDO> takeableTemplates = templates.stream()
  220 + .filter(this::isCouponTemplateNotExpired)
  221 + .collect(Collectors.toList());
  222 + if (takeableTemplates.size() < templates.size()) {
  223 + log.info("[takeCouponByRegister][用户({}) 过滤 {} 张不可领取的模板]", userId, templates.size() - takeableTemplates.size());
220 } 224 }
  225 + // 2. 逐个发放,单张失败不影响其余
  226 + int successCount = 0;
  227 + for (CouponTemplateDO template : takeableTemplates) {
  228 + try {
  229 + takeCoupon(template, CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER);
  230 + successCount++;
  231 + } catch (Exception e) {
  232 + log.error("[takeCouponByRegister][用户({}) 模板({}) 发放失败]", userId, template.getId(), e);
  233 + }
  234 + }
  235 + // 3. 应发全失败时留一条 ERROR 标记,供监控告警
  236 + if (CollUtil.isNotEmpty(takeableTemplates) && successCount == 0) {
  237 + log.error("[takeCouponByRegister][用户({}) 全部 {} 张新人券发放失败]", userId, takeableTemplates.size());
  238 + }
  239 + }
  240 +
  241 + private boolean isCouponTemplateNotExpired(CouponTemplateDO template) {
  242 + return !CouponTemplateValidityTypeEnum.DATE.getType().equals(template.getValidityType())
  243 + || !LocalDateTimeUtils.beforeNow(template.getValidEndTime());
221 } 244 }
222 245
223 @Override 246 @Override