Преглед изворни кода

fix:【MALL 商城管理】优惠劵扣减时,增加 WHERE 乐观锁

YunaiV пре 11 месеци
родитељ
комит
a9c7b584cc

+ 6 - 2
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java

@@ -31,9 +31,13 @@ import java.util.List;
 public class CouponTemplateDO extends BaseDO {
 
     /**
-     * 不限制领取数量
+     * 领取数量 - 不限制
      */
-    public static final Integer TIME_LIMIT_COUNT_MAX = -1;
+    public static final Integer TAKE_LIMIT_COUNT_MAX = -1;
+    /**
+     * 发放数量 - 不限制
+     */
+    public static final Integer TOTAL_COUNT_MAX = -1;
 
     // ========== 基本信息 BEGIN ==========
     /**

+ 9 - 3
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponTemplateMapper.java

@@ -40,10 +40,16 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> {
                 .orderByDesc(CouponTemplateDO::getId));
     }
 
-    default void updateTakeCount(Long id, Integer incrCount) {
-        update(null, new LambdaUpdateWrapper<CouponTemplateDO>()
+    default int updateTakeCount(Long id, Integer incrCount) {
+        LambdaUpdateWrapper<CouponTemplateDO> updateWrapper = new LambdaUpdateWrapper<CouponTemplateDO>()
                 .eq(CouponTemplateDO::getId, id)
-                .setSql("take_count = take_count + " + incrCount));
+                .setSql("take_count = take_count + " + incrCount);
+        // 增加已领取的数量(incrCount 为正数),需要考虑发放数量 totalCount 的限制
+        if (incrCount > 0) {
+            updateWrapper.and(i -> i.apply("take_count < total_count")
+                    .or().eq(CouponTemplateDO::getTotalCount, CouponTemplateDO.TOTAL_COUNT_MAX));
+        }
+        return update(updateWrapper);
     }
 
     default List<CouponTemplateDO> selectListByTakeType(Integer takeType) {

+ 1 - 2
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java

@@ -137,7 +137,6 @@ public class CouponServiceImpl implements CouponService {
 
         // 4. 增加优惠劵模板的领取数量
         couponTemplateService.updateCouponTemplateTakeCount(template.getId(), userIds.size());
-
         return convertMultiMap(couponList, CouponDO::getUserId, CouponDO::getId);
     }
 
@@ -281,7 +280,7 @@ public class CouponServiceImpl implements CouponService {
         }
         // 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时)
         if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType())
-                && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
+                && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TAKE_LIMIT_COUNT_MAX) // 非不限制
                 && couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) {
             throw exception(COUPON_TEMPLATE_NOT_ENOUGH);
         }

+ 6 - 4
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponTemplateServiceImpl.java

@@ -22,8 +22,7 @@ import java.util.List;
 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_TOTAL_COUNT_TOO_SMALL;
+import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
 
 /**
  * 优惠劵模板 Service 实现类
@@ -60,7 +59,7 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
         CouponTemplateDO couponTemplate = validateCouponTemplateExists(updateReqVO.getId());
         // 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时)
         if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType())
-                && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制
+                && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TAKE_LIMIT_COUNT_MAX) // 非不限制
                 && updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) {
             throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount());
         }
@@ -116,7 +115,10 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
 
     @Override
     public void updateCouponTemplateTakeCount(Long id, int incrCount) {
-        couponTemplateMapper.updateTakeCount(id, incrCount);
+        int updateCount = couponTemplateMapper.updateTakeCount(id, incrCount);
+        if (updateCount == 0) {
+            throw exception(COUPON_TEMPLATE_NOT_ENOUGH);
+        }
     }
 
     @Override