feat(coupon): 优化优惠券领取结果返回逻辑

- 移除控制器中只返回首个错误的限制,改为返回完整的领取结果列表
- 在 CouponClaimResult DTO 中新增 claimedRecords 字段用于返回已领取记录
- 添加 failureWithClaimedRecords 静态方法支持携带已领取记录的失败结果
- 当用户达到领取上限时查询并返回其已领取的券记录供前端展示
- 实现无论成功或失败都向客户端返回完整结果数据的功能
This commit is contained in:
2026-01-23 18:04:13 +08:00
parent 918ff860c3
commit 4fc0984994
3 changed files with 31 additions and 9 deletions

View File

@@ -60,13 +60,7 @@ public class SceneCouponClaimController {
List<CouponClaimResult> results = sceneCouponService.claimCoupons(req, userId);
// 判断整体结果
boolean hasSuccess = results.stream().anyMatch(CouponClaimResult::isSuccess);
if (!hasSuccess && !results.isEmpty()) {
// 全部失败,返回第一个错误信息
return ApiResponse.fail(results.get(0).getErrorMessage());
}
// 无论成功或失败,都返回完整结果列表(包含已领取的券信息)
return ApiResponse.success(results);
} catch (Exception e) {
log.error("场景优惠券|领取失败 req={}", req, e);

View File

@@ -5,6 +5,7 @@ import com.ycwl.basic.pricing.entity.PriceCouponConfig;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* 优惠券领取结果DTO
@@ -58,6 +59,11 @@ public class CouponClaimResult {
private String scenicId;
private PriceCouponConfig coupon;
/**
* 已领取的记录列表(领取失败时返回,帮助前端展示用户已有的券)
*/
private List<PriceCouponClaimRecord> claimedRecords;
/**
* 创建成功结果
*/
@@ -84,6 +90,23 @@ public class CouponClaimResult {
result.errorMessage = errorMessage;
return result;
}
/**
* 创建失败结果(带已领取的券列表)
*/
public static CouponClaimResult failureWithClaimedRecords(String errorCode, String errorMessage,
List<PriceCouponClaimRecord> claimedRecords,
PriceCouponConfig coupon) {
CouponClaimResult result = new CouponClaimResult();
result.success = false;
result.errorCode = errorCode;
result.errorMessage = errorMessage;
result.claimedRecords = claimedRecords;
result.coupon = coupon;
result.couponId = coupon != null ? coupon.getId() : null;
result.couponName = coupon != null ? coupon.getCouponName() : null;
return result;
}
/**
* 创建失败结果(仅错误消息)

View File

@@ -371,9 +371,14 @@ public class CouponServiceImpl implements ICouponService {
request.getUserId(), request.getCouponId());
// countUserCouponClaims 使用 FOR UPDATE + 复合索引,确保并发下的计数准确
if (userClaimCount >= coupon.getUserClaimLimit()) {
return CouponClaimResult.failure(
// 查询用户已领取的记录,返回给前端展示
List<PriceCouponClaimRecord> claimedRecords = couponClaimRecordMapper.selectUserCouponRecords(
request.getUserId(), request.getCouponId());
return CouponClaimResult.failureWithClaimedRecords(
CouponClaimResult.ERROR_CLAIM_LIMIT_REACHED,
"您已达到该优惠券的领取上限(" + coupon.getUserClaimLimit() + "张)");
"您已达到该优惠券的领取上限(" + coupon.getUserClaimLimit() + "张)",
claimedRecords,
coupon);
}
}