From 3f4414c0f936b146883386ab729a87044cf6aa93 Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Mon, 6 Jul 2026 17:45:35 +0800 Subject: [PATCH] sms --- .../domain/exception/ErrorCode.java | 1 + .../infrastructure/remote/SmsRemote.java | 36 +++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java index ee5f0ec..6ff7542 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java @@ -96,6 +96,7 @@ public enum ErrorCode { SMS_SOURCE_CODE_NOT_EXIST("04-01-001", "短信码不存在"), SMS_CODE_EXPIRED("04-01-002", "验证码过期,请重新发送"), SMS_CODE_NOT_RIGHT("04-01-003", "验证码不正确"), + SMS_CODE_TOO_FREQUENT("04-01-004", "操作过于频繁,请稍后再试"), // gbs GBS_USER_ERROR("04-01-001", "gbs用户未登录"), diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/remote/SmsRemote.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/remote/SmsRemote.java index e849b0f..d9966b2 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/remote/SmsRemote.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/remote/SmsRemote.java @@ -13,6 +13,8 @@ import org.apache.commons.lang3.StringUtils; import org.apache.dubbo.config.annotation.DubboReference; import org.qinan.safetyeval.client.dto.SendMessageCmd; import org.qinan.safetyeval.domain.exception.BizException; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -33,6 +35,7 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; import static org.qinan.safetyeval.domain.exception.ErrorCode.*; @@ -59,6 +62,7 @@ public class SmsRemote { @DubboReference private MessageFacade messageFacade; private final RedisService redisService; + private final RedissonClient redissonClient; @Value("${sms.sign.sourceCode:}") @@ -97,14 +101,34 @@ public class SmsRemote { } public SingleResponse signValidCode(String bizId, String validCode) { - Object code = redisService.get(bizId); - if (code == null) { - throw new BizException(SMS_CODE_EXPIRED); + // 以 bizId 为 key 加分布式锁,锁 1s,防止刷验证码 + RLock lock = redissonClient.getLock(bizId); + boolean locked; + try { + // 不等待,拿不到锁即视为频繁操作;锁自动 1s 后释放 + locked = lock.tryLock(0, 1, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new BizException(SMS_CODE_TOO_FREQUENT); } - if (code.toString().equals(validCode)) { - throw new BizException(SMS_CODE_NOT_RIGHT); + if (!locked) { + throw new BizException(SMS_CODE_TOO_FREQUENT); + } + try { + Object code = redisService.get(bizId); + if (code == null) { + throw new BizException(SMS_CODE_EXPIRED); + } + + if (code.toString().equals(validCode)) { + throw new BizException(SMS_CODE_NOT_RIGHT); + } + return SingleResponse.of(bizId); + } finally { + if (lock.isHeldByCurrentThread()) { + lock.unlock(); + } } - return SingleResponse.of(bizId); } /**