Compare commits

..

2 Commits

Author SHA1 Message Date
luotaiqian 3b7303682f Merge remote-tracking branch 'origin/dev' into dev 2026-07-06 17:45:43 +08:00
luotaiqian 3f4414c0f9 sms 2026-07-06 17:45:35 +08:00
2 changed files with 31 additions and 6 deletions

View File

@ -97,6 +97,7 @@ public enum ErrorCode {
SMS_SOURCE_CODE_NOT_EXIST("04-01-001", "短信码不存在"), SMS_SOURCE_CODE_NOT_EXIST("04-01-001", "短信码不存在"),
SMS_CODE_EXPIRED("04-01-002", "验证码过期,请重新发送"), SMS_CODE_EXPIRED("04-01-002", "验证码过期,请重新发送"),
SMS_CODE_NOT_RIGHT("04-01-003", "验证码不正确"), SMS_CODE_NOT_RIGHT("04-01-003", "验证码不正确"),
SMS_CODE_TOO_FREQUENT("04-01-004", "操作过于频繁,请稍后再试"),
// gbs // gbs
GBS_USER_ERROR("04-01-001", "gbs用户未登录"), GBS_USER_ERROR("04-01-001", "gbs用户未登录"),

View File

@ -13,6 +13,8 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.DubboReference;
import org.qinan.safetyeval.client.dto.SendMessageCmd; import org.qinan.safetyeval.client.dto.SendMessageCmd;
import org.qinan.safetyeval.domain.exception.BizException; 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.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
@ -33,6 +35,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import static org.qinan.safetyeval.domain.exception.ErrorCode.*; import static org.qinan.safetyeval.domain.exception.ErrorCode.*;
@ -59,6 +62,7 @@ public class SmsRemote {
@DubboReference @DubboReference
private MessageFacade messageFacade; private MessageFacade messageFacade;
private final RedisService redisService; private final RedisService redisService;
private final RedissonClient redissonClient;
@Value("${sms.sign.sourceCode:}") @Value("${sms.sign.sourceCode:}")
@ -97,14 +101,34 @@ public class SmsRemote {
} }
public SingleResponse<String> signValidCode(String bizId, String validCode) { public SingleResponse<String> signValidCode(String bizId, String validCode) {
Object code = redisService.get(bizId); // 以 bizId 为 key 加分布式锁,锁 1s防止刷验证码
if (code == null) { RLock lock = redissonClient.getLock(bizId);
throw new BizException(SMS_CODE_EXPIRED); 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)) { if (!locked) {
throw new BizException(SMS_CODE_NOT_RIGHT); 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);
} }
/** /**