短信相关逻辑,仅仅接口状态标记

This commit is contained in:
zk
2026-06-04 17:22:41 +08:00
parent e3ed3e94d4
commit f318e44481
3 changed files with 39 additions and 39 deletions
@@ -26,8 +26,8 @@ public class LoginController {
private LoginService loginService;
@PostMapping("/sms/sendCode")
public boolean sendCode(@RequestParam @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") String mobileNumber) {
return loginService.sendCode(mobileNumber);
public void sendCode(@RequestParam @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") String mobileNumber) {
loginService.sendCode(mobileNumber);
}
@PostMapping("/login/smsLogin")
@@ -66,16 +66,16 @@ public class LoginService {
/**
* 发送短信验证码
* <p>1. 生成6位随机验证码 2. 委托SmsService发送</p>
* <p>1. 生成6位随机验证码 2. 委托SmsService发送,失败抛异常</p>
*/
public boolean sendCode(String mobileNumber) {
public void sendCode(String mobileNumber) {
Assert.hasText(mobileNumber, "手机号不能为空");
UniversalSmsVariable variable = new UniversalSmsVariable();
String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
variable.setCode(code);
return smsService.send(mobileNumber, SmsTemplateEnum.UNIVERSAL, variable);
smsService.send(mobileNumber, SmsTemplateEnum.UNIVERSAL, variable);
}
/**
@@ -5,6 +5,8 @@ import lombok.extern.slf4j.Slf4j;
import org.jiayunet.constant.SmsTemplateEnum;
import org.jiayunet.constant.sms.SmsVariableAllows;
import org.jiayunet.constant.sms.UniversalSmsVariable;
import org.jiayunet.exception.BusinessException;
import org.jiayunet.exception.BusinessExpCodeEnum;
import org.jiayunet.sms.AliYunSmsAbility;
import org.jiayunet.tool.server.RedisServerTool;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,10 +43,9 @@ public class SmsService {
* @param phone 目标手机号,不能为空
* @param template 短信模板枚举,必须与 {@code variable} 的类型匹配
* @param variable 短信参数对象,可能是 {@link UniversalSmsVariable}(验证码)或其他实现
* @return {@code true} 表示短信发送成功,{@code false} 表示发送失败或前置参数校验未通过
* @throws BusinessException 发送失败时抛出业务异常
*/
public boolean send(String phone, SmsTemplateEnum template, SmsVariableAllows variable) {
try {
public void send(String phone, SmsTemplateEnum template, SmsVariableAllows variable) {
Assert.hasText(phone, "手机号不能为空");
Assert.notNull(template, "短信模板不能为空");
Assert.notNull(variable, "短信参数不能为空");
@@ -52,21 +53,16 @@ public class SmsService {
// 校验参数类型是否匹配
if (!template.getVariableClass().isInstance(variable)) {
log.error("短信参数类型不匹配: template={}, expectedClass={}, actualClass={}", template.name(), template.getVariableClass().getName(), variable.getClass().getName());
throw new RuntimeException("短信发送失败");
throw new BusinessException(BusinessExpCodeEnum.UNKNOWN_ERROR, "短信发送失败");
}
// 判断是否激活验证码模式
boolean isVerifyMode = isVerifyCodeMode(template, variable);
if (isVerifyMode) {
return sendVerifyCode(phone, template, (UniversalSmsVariable) variable);
sendVerifyCode(phone, template, (UniversalSmsVariable) variable);
} else {
return sendNormalSms(phone, template, variable);
}
} catch (Exception e) {
log.error("发送短信异常: phone={}, template={}", phone, template.name(), e);
return false;
sendNormalSms(phone, template, variable);
}
}
@@ -163,7 +159,7 @@ public class SmsService {
return false;
}
/**
/**
* 发送验证码短信。
*
* 在发送前先检查 Redis 中是否已有未过期的验证码,防止重复发送。
@@ -172,9 +168,9 @@ public class SmsService {
* @param phone 目标手机号,不能为空
* @param template 短信模板枚举,必须包含验证码相关配置(如有效时间)
* @param variable {@link UniversalSmsVariable},其中必须包含非空的 {@code code}
* @return {@code true} 表示短信发送及缓存成功,{@code false} 表示发送被拦截或失败
* @throws BusinessException 发送被拦截或失败时抛出业务异常
*/
private boolean sendVerifyCode(String phone, SmsTemplateEnum template, UniversalSmsVariable variable) {
private void sendVerifyCode(String phone, SmsTemplateEnum template, UniversalSmsVariable variable) {
String key = buildVerifyCodeKey(template, phone);
// 检查是否允许重发
@@ -185,7 +181,7 @@ public class SmsService {
long elapsedSeconds = template.getEffectiveTime() * 60L - (remainSeconds != null ? remainSeconds : 0L);
if (elapsedSeconds < template.getRetryTime() * 60L) {
log.warn("重发间隔未到,请{}分钟后再试: phone={}, template={}", template.getRetryTime(), phone, template.name());
throw new RuntimeException("请勿重复发送");
throw new BusinessException(BusinessExpCodeEnum.UNKNOWN_ERROR, "请勿重复发送");
}
// 已超过重发间隔,允许重新发送,后续会覆盖旧验证码
}
@@ -203,30 +199,34 @@ public class SmsService {
variableMap
);
if (!success) {
throw new BusinessException(BusinessExpCodeEnum.UNKNOWN_ERROR, "短信发送失败,请稍后重试");
}
// 发送成功后存储验证码
if (success) {
redisServerTool.set(key, variable.getCode(), template.getEffectiveTime(), TimeUnit.MINUTES);
log.info("验证码已存储: phone={}, template={}, effectiveTime={}分钟",
phone, template.name(), template.getEffectiveTime());
}
return success;
}
/**
* 发送普通短信
*/
private boolean sendNormalSms(String phone, SmsTemplateEnum template, SmsVariableAllows variable) {
private void sendNormalSms(String phone, SmsTemplateEnum template, SmsVariableAllows variable) {
// 转换参数对象为 Map<String, String>
Map<String, String> variableMap = objectMapper.convertValue(variable, new com.fasterxml.jackson.core.type.TypeReference<Map<String, String>>() {});
// 直接发送短信
return aliYunSmsAbility.sendSms(
boolean success = aliYunSmsAbility.sendSms(
phone,
template.getSignName(),
template.getTemplateCode(),
variableMap
);
if (!success) {
throw new BusinessException(BusinessExpCodeEnum.UNKNOWN_ERROR, "短信发送失败,请稍后重试");
}
}
/**