Ver Fonte

fix: 申请退款增加账户行锁,杜绝并发双退

- account 读取改为 SELECT ... FOR UPDATE,并发退款请求串行化
- 校验口径修正:以充值余额(recharge_balance)而非总余额(balance)判断,
  纯赠款余额用户不再生成 0 元退款单
- account 为 null 时给出明确业务异常而非 NPE

Co-Authored-By: Claude <noreply@anthropic.com>
skyline há 3 semanas atrás
pai
commit
71367dda87

+ 8 - 3
car-wash-service/src/main/java/com/kym/service/wechat/impl/WxPayServiceImpl.java

@@ -508,9 +508,14 @@ public class WxPayServiceImpl implements WxPayService {
             throw new BusinessException("存在未完结的订单,请完成所有订单完结之后重试");
         }
 
-        var account = accountService.getAccountByUserId(userId);
-        if (account.getBalance() <= 0) {
-            throw new BusinessException("账户余额不足,无需退款");
+        // 行锁读取账户,防止并发退款请求同时通过余额校验造成重复退款
+        var account = accountService.lambdaQuery().eq(Account::getUserId, userId).last("FOR UPDATE").one();
+        if (account == null) {
+            throw new BusinessException("用户账户不存在");
+        }
+        // 退款金额以充值余额为准(纯赠款余额不可退),校验与冻结/退款口径一致
+        if (account.getRechargeBalance() <= 0) {
+            throw new BusinessException("充值余额不足,无需退款");
         }
         // // 校验余额大于优惠金额
         // if (account.getBalance() <= account.getDiscountAmount()) {