fix(pricing): 修复优惠券库存检查逻辑

- 修正totalQuantity为NULL或0时不限制总量的判断逻辑
- 优化claimedQuantity为空时的默认值处理
- 仅在totalQuantity大于0时更新已领取数量
- 完善MD文档中字段语义描述和配置示例
- 更新SQL表字段说明及典型配置组合示例
This commit is contained in:
2025-11-17 00:30:58 +08:00
parent 7835283f0f
commit 88ad6d6b6f
2 changed files with 39 additions and 16 deletions

View File

@@ -128,40 +128,54 @@ public enum CouponStatus { CLAIMED("claimed", ...), USED("used", ...), EXPIRED("
#### 优惠券数量管理机制 (v1.0.0更新) #### 优惠券数量管理机制 (v1.0.0更新)
```java ```java
// PriceCouponConfig 实体新增字段 // PriceCouponConfig 实体字段
private Integer userClaimLimit; // 每个用户可领取数量限制(NULL表示不限制) private Integer totalQuantity; // 发行总量(NULL或0表示不限制)
private Integer userClaimLimit; // 每个用户可领取数量限制(NULL或0表示不限制)
private Integer claimedQuantity; // 已领取数量(区分于已使用数量) private Integer claimedQuantity; // 已领取数量(区分于已使用数量)
private Integer usedQuantity; // 已使用数量(实际消耗时更新) private Integer usedQuantity; // 已使用数量(实际消耗时更新)
// 字段语义
totalQuantity: NULL/0=不限总量, >0=限制总量
userClaimLimit: NULL/0=不限用户, >0=限制单用户
claimedQuantity: 仅在totalQuantity>0时更新
usedQuantity: 实际使用时更新
// 领取流程检查顺序 // 领取流程检查顺序
1. 检查优惠券是否存在且启用 1. 检查优惠券是否存在且启用
2. 检查有效期 2. 检查有效期
3. 检查总量库存: claimedQuantity < totalQuantity 3. 检查总量库存: totalQuantity>0 ,检查 claimedQuantity < totalQuantity
4. 检查用户领取限制: countUserClaims(userId, couponId) < userClaimLimit 4. 检查用户领取限制: userClaimLimit>0 ,检查 countUserClaims(userId, couponId) < userClaimLimit
5. 创建领取记录并更新 claimedQuantity + 1 5. 创建领取记录并更新 claimedQuantity (仅当totalQuantity>0时)
``` ```
#### 用户领取限制配置示例 #### 用户领取限制配置示例
```java ```java
// 场景1: 新人专享券,每人限领1张 // 场景1: 新人专享券,每人限领1张,总量1000张
{ {
"couponName": "新人专享券", "couponName": "新人专享券",
"userClaimLimit": 1, "userClaimLimit": 1,
"totalQuantity": 1000 "totalQuantity": 1000
} }
// 场景2: 活动券,每人限领3张 // 场景2: 活动券,每人限领3张,总量5000张
{ {
"couponName": "618促销券", "couponName": "618促销券",
"userClaimLimit": 3, "userClaimLimit": 3,
"totalQuantity": 5000 "totalQuantity": 5000
} }
// 场景3: 不限制领取次数 // 场景3: 不限制领取次数,不限制总量
{ {
"couponName": "会员专享券", "couponName": "会员专享券",
"userClaimLimit": null, // 或 0 "userClaimLimit": null, // 或 0
"totalQuantity": 10000 "totalQuantity": null // 或 0,表示无限量
}
// 场景4: 不限用户次数,但限制总量
{
"couponName": "限量抢购券",
"userClaimLimit": null, // 不限单用户
"totalQuantity": 500 // 总共500张
} }
``` ```
@@ -602,14 +616,20 @@ public class PriceCalculationResult {
### price_coupon_config 表字段说明 (v1.0.0更新) ### price_coupon_config 表字段说明 (v1.0.0更新)
```sql ```sql
-- 核心数量管理字段 -- 核心数量管理字段
total_quantity INT -- 发行总量 total_quantity INT -- 发行总量(NULL或0表示不限制,>0表示限量)
claimed_quantity INT -- 已领取数量(v1.0.0新增,领取时+1) claimed_quantity INT -- 已领取数量(v1.0.0新增,领取时+1,仅在total_quantity>0时更新)
used_quantity INT -- 已使用数量(实际使用时+1) used_quantity INT -- 已使用数量(实际使用时+1)
user_claim_limit INT -- 每个用户可领取数量限制(v1.0.0新增,NULL表示不限制) user_claim_limit INT -- 每个用户可领取数量限制(v1.0.0新增,NULL或0表示不限制,>0表示限制)
-- 字段关系 -- 字段关系
-- claimed_quantity >= used_quantity (已领取 >= 已使用) -- claimed_quantity >= used_quantity (已领取 >= 已使用)
-- claimed_quantity <= total_quantity (已领取 <= 总量) -- claimed_quantity <= total_quantity (已领取 <= 总量,仅当total_quantity>0时适用)
-- 典型配置组合
-- 1. 无限量发行: total_quantity=NULL/0, user_claim_limit=NULL/0
-- 2. 限量限人: total_quantity=1000, user_claim_limit=1
-- 3. 限量不限人: total_quantity=500, user_claim_limit=NULL/0
-- 4. 不限量但限人: total_quantity=NULL/0, user_claim_limit=3
``` ```
### 新增表结构 ### 新增表结构

View File

@@ -231,8 +231,10 @@ public class CouponServiceImpl implements ICouponService {
} }
// 5. 检查库存(如果有总量限制) // 5. 检查库存(如果有总量限制)
if (coupon.getTotalQuantity() != null && coupon.getClaimedQuantity() != null) { // totalQuantity为NULL或0表示不限制总量
if (coupon.getClaimedQuantity() >= coupon.getTotalQuantity()) { if (coupon.getTotalQuantity() != null && coupon.getTotalQuantity() > 0) {
int currentClaimed = (coupon.getClaimedQuantity() == null ? 0 : coupon.getClaimedQuantity());
if (currentClaimed >= coupon.getTotalQuantity()) {
return CouponClaimResult.failure(CouponClaimResult.ERROR_COUPON_OUT_OF_STOCK, "优惠券已领完"); return CouponClaimResult.failure(CouponClaimResult.ERROR_COUPON_OUT_OF_STOCK, "优惠券已领完");
} }
} }
@@ -276,7 +278,8 @@ public class CouponServiceImpl implements ICouponService {
} }
// 10. 更新优惠券已领取数量(区分于已使用数量) // 10. 更新优惠券已领取数量(区分于已使用数量)
if (coupon.getTotalQuantity() != null) { // 仅在有总量限制时才更新claimedQuantity(totalQuantity为正整数)
if (coupon.getTotalQuantity() != null && coupon.getTotalQuantity() > 0) {
int updatedClaimedQuantity = (coupon.getClaimedQuantity() == null ? 0 : coupon.getClaimedQuantity()) + 1; int updatedClaimedQuantity = (coupon.getClaimedQuantity() == null ? 0 : coupon.getClaimedQuantity()) + 1;
coupon.setClaimedQuantity(updatedClaimedQuantity); coupon.setClaimedQuantity(updatedClaimedQuantity);
couponConfigMapper.updateById(coupon); couponConfigMapper.updateById(coupon);