From c796623148fcb3cd142a369f27edd70cbdcb886f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 8 Jul 2025 15:18:11 +0000 Subject: [PATCH] Improve coupon template take count with stock validation logic Co-authored-by: zhijiantianya --- .../dal/mysql/coupon/CouponTemplateMapper.java | 16 ++++++++++++---- .../service/coupon/CouponServiceImpl.java | 8 ++------ .../coupon/CouponTemplateServiceImpl.java | 7 ++++++- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java index 3096a49f3c..01d079a0e5 100755 --- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java +++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java @@ -40,10 +40,18 @@ public interface CouponTemplateMapper extends BaseMapperX { .orderByDesc(CouponTemplateDO::getId)); } - default void updateTakeCount(Long id, Integer incrCount) { - update(null, new LambdaUpdateWrapper() - .eq(CouponTemplateDO::getId, id) - .setSql("take_count = take_count + " + incrCount)); + default int updateTakeCount(Long id, Integer incrCount) { + LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper() + .eq(CouponTemplateDO::getId, id); + + // 只在增加数量时检查库存(incrCount > 0) + if (incrCount > 0) { + // 添加库存判断:剩余数量 >= 领取的数量,或者总数量为-1(无限库存) + wrapper.and(w -> w.apply("total_count = -1 OR (total_count - take_count) >= {0}", incrCount)); + } + + wrapper.setSql("take_count = take_count + " + incrCount); + return update(null, wrapper); } default List selectListByTakeType(Integer takeType) { diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java index e6f82a69fc..3d6021e521 100644 --- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java @@ -279,12 +279,8 @@ public class CouponServiceImpl implements CouponService { if (ObjUtil.notEqual(couponTemplate.getTakeType(), takeType.getType())) { throw exception(COUPON_TEMPLATE_CANNOT_TAKE); } - // 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时) - if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType()) - && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制 - && couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) { - throw exception(COUPON_TEMPLATE_NOT_ENOUGH); - } + // 注意:库存检查现在在数据库层面的 updateCouponTemplateTakeCount 方法中进行 + // 如果库存不足,该方法会抛出 COUPON_TEMPLATE_NOT_ENOUGH 异常 // 校验"固定日期"的有效期类型是否过期 if (CouponTemplateValidityTypeEnum.DATE.getType().equals(couponTemplate.getValidityType())) { if (LocalDateTimeUtils.beforeNow(couponTemplate.getValidEndTime())) { diff --git a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java index 175e33b197..cc2fd6027b 100755 --- a/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java +++ b/yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java @@ -23,6 +23,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_ENOUGH; import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL; /** @@ -116,7 +117,11 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { @Override public void updateCouponTemplateTakeCount(Long id, int incrCount) { - couponTemplateMapper.updateTakeCount(id, incrCount); + int updateCount = couponTemplateMapper.updateTakeCount(id, incrCount); + // 只在增加数量且更新失败时,说明库存不足,抛出异常 + if (incrCount > 0 && updateCount == 0) { + throw exception(COUPON_TEMPLATE_NOT_ENOUGH); + } } @Override