You've already forked FrameTour-BE
feat(pricing): 支持发放多个首次打印优惠券
- 修改自动发券逻辑,支持发放多个符合条件的首次优惠券 - 更新查找优惠券方法,返回所有匹配的优惠券ID列表 - 添加发券过程中的异常处理,确保部分失败不影响其他券发放 - 记录详细的发券日志,包括成功、跳过和失败的数量 - 优化日志输出,提供更清晰的调试信息
This commit is contained in:
@@ -36,39 +36,62 @@ public class AutoCouponServiceImpl implements IAutoCouponService {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 查找该景区、该商品类型的首次打印优惠券配置
|
||||
Long couponId = findFirstCouponId(scenicId, productType);
|
||||
if (couponId == null) {
|
||||
// 2. 查找该景区、该商品类型的所有首次打印优惠券配置
|
||||
List<Long> couponIds = findFirstCouponIds(scenicId, productType);
|
||||
if (couponIds == null || couponIds.isEmpty()) {
|
||||
log.debug("景区未配置首次打印优惠券: scenicId={}, productType={}", scenicId, productType);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. 检查用户是否已领取过该券(领券即消耗首次资格)
|
||||
PriceCouponClaimRecord existingRecord = couponClaimRecordMapper.selectUserCouponRecord(
|
||||
memberId,
|
||||
couponId
|
||||
);
|
||||
log.info("找到{}张首次优惠券待发放: scenicId={}, productType={}, couponIds={}",
|
||||
couponIds.size(), scenicId, productType, couponIds);
|
||||
|
||||
if (existingRecord != null) {
|
||||
log.debug("用户已领取过首次优惠券,不重复发券: memberId={}, couponId={}, claimTime={}",
|
||||
memberId, couponId, existingRecord.getClaimTime());
|
||||
return false;
|
||||
// 3. 遍历所有优惠券,逐一检查并发放
|
||||
int successCount = 0;
|
||||
int skipCount = 0;
|
||||
int failCount = 0;
|
||||
|
||||
for (Long couponId : couponIds) {
|
||||
try {
|
||||
// 检查用户是否已领取过该券(领券即消耗首次资格)
|
||||
PriceCouponClaimRecord existingRecord = couponClaimRecordMapper.selectUserCouponRecord(
|
||||
memberId,
|
||||
couponId
|
||||
);
|
||||
|
||||
if (existingRecord != null) {
|
||||
log.debug("用户已领取过优惠券,跳过: memberId={}, couponId={}, claimTime={}",
|
||||
memberId, couponId, existingRecord.getClaimTime());
|
||||
skipCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 自动发券
|
||||
CouponClaimRequest request = new CouponClaimRequest(
|
||||
memberId,
|
||||
couponId,
|
||||
scenicId.toString(),
|
||||
"AUTO_GRANT" // 标记为自动发券来源
|
||||
);
|
||||
|
||||
couponService.claimCoupon(request);
|
||||
successCount++;
|
||||
|
||||
log.info("成功自动发放首次优惠券: memberId={}, faceId={}, scenicId={}, productType={}, couponId={}",
|
||||
memberId, faceId, scenicId, productType, couponId);
|
||||
|
||||
} catch (Exception e) {
|
||||
failCount++;
|
||||
log.error("单张优惠券发放失败,继续处理其他券: memberId={}, couponId={}, error={}",
|
||||
memberId, couponId, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 自动发券
|
||||
CouponClaimRequest request = new CouponClaimRequest(
|
||||
memberId,
|
||||
couponId,
|
||||
scenicId.toString(),
|
||||
"AUTO_GRANT" // 标记为自动发券来源
|
||||
);
|
||||
log.info("自动发券完成: memberId={}, 成功{}张, 跳过{}张, 失败{}张",
|
||||
memberId, successCount, skipCount, failCount);
|
||||
|
||||
couponService.claimCoupon(request);
|
||||
|
||||
log.info("成功自动发放首次打印优惠券: memberId={}, faceId={}, scenicId={}, productType={}, couponId={}",
|
||||
memberId, faceId, scenicId, productType, couponId);
|
||||
|
||||
return true;
|
||||
// 只要有一张成功就返回true
|
||||
return successCount > 0;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("自动发券失败: memberId={}, faceId={}, scenicId={}, productType={}",
|
||||
@@ -78,14 +101,15 @@ public class AutoCouponServiceImpl implements IAutoCouponService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找指定景区、指定商品类型的首次打印优惠券ID
|
||||
* 查找指定景区、指定商品类型的所有首次打印优惠券ID
|
||||
* 规则:优惠券名称包含 "首次" 且 适用商品类型包含目标类型
|
||||
*
|
||||
* @param scenicId 景区ID
|
||||
* @param productType 商品类型
|
||||
* @return 优惠券ID,未找到返回null
|
||||
* @return 优惠券ID列表,未找到返回空列表
|
||||
*/
|
||||
private Long findFirstCouponId(Long scenicId, ProductType productType) {
|
||||
private List<Long> findFirstCouponIds(Long scenicId, ProductType productType) {
|
||||
List<Long> couponIds = new java.util.ArrayList<>();
|
||||
try {
|
||||
// 查询该景区的有效优惠券
|
||||
List<PriceCouponConfig> coupons = couponConfigMapper.selectValidCouponsByScenicId(
|
||||
@@ -100,17 +124,22 @@ public class AutoCouponServiceImpl implements IAutoCouponService {
|
||||
String applicableProducts = coupon.getApplicableProducts();
|
||||
if (applicableProducts != null &&
|
||||
applicableProducts.contains(productType.getCode())) {
|
||||
return coupon.getId();
|
||||
couponIds.add(coupon.getId());
|
||||
log.debug("找到匹配的首次优惠券: couponId={}, couponName={}, scenicId={}, productType={}",
|
||||
coupon.getId(), coupon.getCouponName(), scenicId, productType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("未找到匹配的首次打印优惠券: scenicId={}, productType={}", scenicId, productType);
|
||||
return null;
|
||||
if (couponIds.isEmpty()) {
|
||||
log.debug("未找到匹配的首次打印优惠券: scenicId={}, productType={}", scenicId, productType);
|
||||
}
|
||||
|
||||
return couponIds;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("查找首次打印优惠券失败: scenicId={}, productType={}", scenicId, productType, e);
|
||||
return null;
|
||||
return couponIds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user