“mitao”
2026-04-07 a013b0c9d580b0a10200bfc60d1ea3af15e45740
tcm-training-admin-backend/src/main/java/com/tcm/training/admin/app/auth/service/AppSmsCodeService.java
@@ -15,6 +15,7 @@
public class AppSmsCodeService {
    private static final String LOGIN_CODE_CACHE_PREFIX = "app:sms:login:";
    private static final String REGISTER_CODE_CACHE_PREFIX = "app:sms:register:";
    private final StringRedisTemplate stringRedisTemplate;
    private final AppSmsSender appSmsSender;
@@ -35,26 +36,58 @@
     * 生成并发送登录验证码,同时写入缓存。
     */
    public AppSmsCodeSendResponse createLoginCode(String phone) {
        String code = generateCode();
        stringRedisTemplate.opsForValue().set(
                buildCacheKey(phone),
                code,
                appSmsAuthProperties.getExpireSeconds(),
                TimeUnit.SECONDS
        );
        appSmsSender.sendLoginCode(phone, code);
        return new AppSmsCodeSendResponse(appSmsAuthProperties.getExpireSeconds());
        return createCode(phone, LOGIN_CODE_CACHE_PREFIX, true);
    }
    /**
     * 生成并发送注册验证码,同时写入缓存。
     */
    public AppSmsCodeSendResponse createRegisterCode(String phone) {
        return createCode(phone, REGISTER_CODE_CACHE_PREFIX, false);
    }
    /**
     * 校验登录验证码,成功后销毁缓存中的一次性验证码。
     */
    public void validateLoginCode(String phone, String code) {
        validateCode(phone, code, LOGIN_CODE_CACHE_PREFIX);
    }
    /**
     * 校验注册验证码,成功后销毁缓存中的一次性验证码。
     */
    public void validateRegisterCode(String phone, String code) {
        validateCode(phone, code, REGISTER_CODE_CACHE_PREFIX);
    }
    /**
     * 统一生成指定场景的验证码并写入缓存。
     */
    private AppSmsCodeSendResponse createCode(String phone, String cachePrefix, boolean loginScene) {
        String code = generateCode();
        stringRedisTemplate.opsForValue().set(
                buildCacheKey(cachePrefix, phone),
                code,
                appSmsAuthProperties.getExpireSeconds(),
                TimeUnit.SECONDS
        );
        if (loginScene) {
            appSmsSender.sendLoginCode(phone, code);
        } else {
            appSmsSender.sendRegisterCode(phone, code);
        }
        return new AppSmsCodeSendResponse(appSmsAuthProperties.getExpireSeconds());
    }
    /**
     * 统一校验指定场景的验证码并执行一次性销毁。
     */
    private void validateCode(String phone, String code, String cachePrefix) {
        if (matchesDebugCode(code)) {
            // 开发环境允许固定验证码直通,便于前后端联调。
            return;
        }
        String cacheKey = buildCacheKey(phone);
        String cacheKey = buildCacheKey(cachePrefix, phone);
        String cachedCode = stringRedisTemplate.opsForValue().get(cacheKey);
        if (cachedCode == null || cachedCode.trim().isEmpty()) {
            throw new IllegalArgumentException("验证码已失效,请重新获取");
@@ -88,7 +121,7 @@
    /**
     * 构造手机号维度的验证码缓存 key。
     */
    private String buildCacheKey(String phone) {
        return LOGIN_CODE_CACHE_PREFIX + phone;
    private String buildCacheKey(String cachePrefix, String phone) {
        return cachePrefix + phone;
    }
}