Commit a9c7b584ccbf2ad377893c0316fd70df5bbbc40d
1 parent
a54e743a
fix:【MALL 商城管理】优惠劵扣减时,增加 WHERE 乐观锁
Showing
4 changed files
with
22 additions
and
11 deletions
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; | @@ -31,9 +31,13 @@ import java.util.List; | ||
| 31 | public class CouponTemplateDO extends BaseDO { | 31 | public class CouponTemplateDO extends BaseDO { |
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| 34 | - * 不限制领取数量 | 34 | + * 领取数量 - 不限制 |
| 35 | */ | 35 | */ |
| 36 | - public static final Integer TIME_LIMIT_COUNT_MAX = -1; | 36 | + public static final Integer TAKE_LIMIT_COUNT_MAX = -1; |
| 37 | + /** | ||
| 38 | + * 发放数量 - 不限制 | ||
| 39 | + */ | ||
| 40 | + public static final Integer TOTAL_COUNT_MAX = -1; | ||
| 37 | 41 | ||
| 38 | // ========== 基本信息 BEGIN ========== | 42 | // ========== 基本信息 BEGIN ========== |
| 39 | /** | 43 | /** |
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> { | @@ -40,10 +40,16 @@ public interface CouponTemplateMapper extends BaseMapperX<CouponTemplateDO> { | ||
| 40 | .orderByDesc(CouponTemplateDO::getId)); | 40 | .orderByDesc(CouponTemplateDO::getId)); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | - default void updateTakeCount(Long id, Integer incrCount) { | ||
| 44 | - update(null, new LambdaUpdateWrapper<CouponTemplateDO>() | 43 | + default int updateTakeCount(Long id, Integer incrCount) { |
| 44 | + LambdaUpdateWrapper<CouponTemplateDO> updateWrapper = new LambdaUpdateWrapper<CouponTemplateDO>() | ||
| 45 | .eq(CouponTemplateDO::getId, id) | 45 | .eq(CouponTemplateDO::getId, id) |
| 46 | - .setSql("take_count = take_count + " + incrCount)); | 46 | + .setSql("take_count = take_count + " + incrCount); |
| 47 | + // 增加已领取的数量(incrCount 为正数),需要考虑发放数量 totalCount 的限制 | ||
| 48 | + if (incrCount > 0) { | ||
| 49 | + updateWrapper.and(i -> i.apply("take_count < total_count") | ||
| 50 | + .or().eq(CouponTemplateDO::getTotalCount, CouponTemplateDO.TOTAL_COUNT_MAX)); | ||
| 51 | + } | ||
| 52 | + return update(updateWrapper); | ||
| 47 | } | 53 | } |
| 48 | 54 | ||
| 49 | default List<CouponTemplateDO> selectListByTakeType(Integer takeType) { | 55 | default List<CouponTemplateDO> selectListByTakeType(Integer takeType) { |
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 { | @@ -137,7 +137,6 @@ public class CouponServiceImpl implements CouponService { | ||
| 137 | 137 | ||
| 138 | // 4. 增加优惠劵模板的领取数量 | 138 | // 4. 增加优惠劵模板的领取数量 |
| 139 | couponTemplateService.updateCouponTemplateTakeCount(template.getId(), userIds.size()); | 139 | couponTemplateService.updateCouponTemplateTakeCount(template.getId(), userIds.size()); |
| 140 | - | ||
| 141 | return convertMultiMap(couponList, CouponDO::getUserId, CouponDO::getId); | 140 | return convertMultiMap(couponList, CouponDO::getUserId, CouponDO::getId); |
| 142 | } | 141 | } |
| 143 | 142 | ||
| @@ -281,7 +280,7 @@ public class CouponServiceImpl implements CouponService { | @@ -281,7 +280,7 @@ public class CouponServiceImpl implements CouponService { | ||
| 281 | } | 280 | } |
| 282 | // 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时) | 281 | // 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时) |
| 283 | if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType()) | 282 | if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType()) |
| 284 | - && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制 | 283 | + && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TAKE_LIMIT_COUNT_MAX) // 非不限制 |
| 285 | && couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) { | 284 | && couponTemplate.getTakeCount() + userIds.size() > couponTemplate.getTotalCount()) { |
| 286 | throw exception(COUPON_TEMPLATE_NOT_ENOUGH); | 285 | throw exception(COUPON_TEMPLATE_NOT_ENOUGH); |
| 287 | } | 286 | } |
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; | @@ -22,8 +22,7 @@ import java.util.List; | ||
| 22 | import java.util.Objects; | 22 | import java.util.Objects; |
| 23 | 23 | ||
| 24 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 24 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 25 | -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS; | ||
| 26 | -import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL; | 25 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; |
| 27 | 26 | ||
| 28 | /** | 27 | /** |
| 29 | * 优惠劵模板 Service 实现类 | 28 | * 优惠劵模板 Service 实现类 |
| @@ -60,7 +59,7 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { | @@ -60,7 +59,7 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { | ||
| 60 | CouponTemplateDO couponTemplate = validateCouponTemplateExists(updateReqVO.getId()); | 59 | CouponTemplateDO couponTemplate = validateCouponTemplateExists(updateReqVO.getId()); |
| 61 | // 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时) | 60 | // 校验发放数量不能过小(仅在 CouponTakeTypeEnum.USER 用户领取时) |
| 62 | if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType()) | 61 | if (CouponTakeTypeEnum.isUser(couponTemplate.getTakeType()) |
| 63 | - && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TIME_LIMIT_COUNT_MAX) // 非不限制 | 62 | + && ObjUtil.notEqual(couponTemplate.getTakeLimitCount(), CouponTemplateDO.TAKE_LIMIT_COUNT_MAX) // 非不限制 |
| 64 | && updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) { | 63 | && updateReqVO.getTotalCount() < couponTemplate.getTakeCount()) { |
| 65 | throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount()); | 64 | throw exception(COUPON_TEMPLATE_TOTAL_COUNT_TOO_SMALL, couponTemplate.getTakeCount()); |
| 66 | } | 65 | } |
| @@ -116,7 +115,10 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { | @@ -116,7 +115,10 @@ public class CouponTemplateServiceImpl implements CouponTemplateService { | ||
| 116 | 115 | ||
| 117 | @Override | 116 | @Override |
| 118 | public void updateCouponTemplateTakeCount(Long id, int incrCount) { | 117 | public void updateCouponTemplateTakeCount(Long id, int incrCount) { |
| 119 | - couponTemplateMapper.updateTakeCount(id, incrCount); | 118 | + int updateCount = couponTemplateMapper.updateTakeCount(id, incrCount); |
| 119 | + if (updateCount == 0) { | ||
| 120 | + throw exception(COUPON_TEMPLATE_NOT_ENOUGH); | ||
| 121 | + } | ||
| 120 | } | 122 | } |
| 121 | 123 | ||
| 122 | @Override | 124 | @Override |