【改进】短信发送增加次数验证
This commit is contained in:
@@ -25,6 +25,7 @@ import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 应用用户 Service 实现类
|
||||
@@ -315,14 +316,27 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
|
||||
// 发送验证码
|
||||
if (StringUtils.hasText(user.getTelephone())) {
|
||||
// 发送短信验证码
|
||||
boolean success = smsBaoUtil.sendVerifyCode(user.getTelephone(), code);
|
||||
if (!success) {
|
||||
throw new RuntimeException(I18nUtil.getMessage("error.sms.send.failed"));
|
||||
|
||||
// 获取当前ip
|
||||
String clientIp = IpUtil.getClientIp(CommonServletUtil.getRequest());
|
||||
clientIp = clientIp.replaceAll(":", "");
|
||||
// 使用 setIfAbsent 初始化计数器(只在键不存在时创建,并设置过期时间为1天)
|
||||
boolean isNew = redisUtil.setIfAbsent("exceed_" + clientIp, 1, 1, TimeUnit.DAYS);
|
||||
// 如果键已存在,递增计数器
|
||||
long sendCount = isNew ? 1 : redisUtil.incr("exceed_" + clientIp, 1);
|
||||
|
||||
if (sendCount <= 4) {
|
||||
|
||||
// 发送短信验证码
|
||||
boolean success = smsBaoUtil.sendVerifyCode(user.getTelephone(), code);
|
||||
if (!success) {
|
||||
throw new RuntimeException(I18nUtil.getMessage("error.sms.send.failed"));
|
||||
}
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("account", user.getTelephone());
|
||||
return Result.success(map);
|
||||
}
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("account", user.getTelephone());
|
||||
return Result.success(map);
|
||||
throw new RuntimeException(I18nUtil.getMessage("error.sms.send.exceed"));
|
||||
} else {
|
||||
// 发送邮件验证码
|
||||
boolean success = emailUtil.sendVerifyCode(user.getEmail(), code);
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 验证码服务实现类
|
||||
@@ -30,6 +30,7 @@ public class VerifyCodeServiceImpl implements VerifyCodeService {
|
||||
|
||||
@Override
|
||||
public boolean sendCode(String account, String type) {
|
||||
|
||||
if (!StringUtils.hasText(account)) {
|
||||
throw new RuntimeException(I18nUtil.getMessage("error.account.empty"));
|
||||
}
|
||||
@@ -53,10 +54,23 @@ public class VerifyCodeServiceImpl implements VerifyCodeService {
|
||||
|
||||
// 发送验证码
|
||||
if (AccountUtil.isPhone(account)) {
|
||||
// 发送短信验证码
|
||||
boolean success = smsBaoUtil.sendVerifyCode(account, code);
|
||||
if (!success) {
|
||||
throw new RuntimeException(I18nUtil.getMessage("error.sms.send.failed"));
|
||||
// 获取当前ip
|
||||
String clientIp = IpUtil.getClientIp(CommonServletUtil.getRequest());
|
||||
clientIp = clientIp.replaceAll(":", "");
|
||||
// 校验IP发短信次数
|
||||
// 使用 setIfAbsent 初始化计数器(只在键不存在时创建,并设置过期时间为1天)
|
||||
boolean isNew = redisUtil.setIfAbsent("exceed_" + clientIp, 1, 1, TimeUnit.DAYS);
|
||||
// 如果键已存在,递增计数器
|
||||
long sendCount = isNew ? 1 : redisUtil.incr("exceed_" + clientIp, 1);
|
||||
|
||||
if (sendCount <= 4) {
|
||||
// 发送短信验证码
|
||||
boolean success = smsBaoUtil.sendVerifyCode(account, code);
|
||||
if (!success) {
|
||||
throw new RuntimeException(I18nUtil.getMessage("error.sms.send.failed"));
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(I18nUtil.getMessage("error.sms.send.exceed"));
|
||||
}
|
||||
} else {
|
||||
// 发送邮件验证码
|
||||
|
||||
@@ -133,6 +133,43 @@ public class RedisUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间(天)
|
||||
* @return true成功 false 失败
|
||||
*/
|
||||
public boolean set(String key, Object value, Integer time, TimeUnit timeUnit) {
|
||||
try {
|
||||
redisTemplate.opsForValue().set(key, value, time, timeUnit);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 普通缓存放入并设置时间(仅在键不存在时设置)
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param time 时间
|
||||
* @param timeUnit 时间单位
|
||||
* @return true成功 false失败(键已存在或设置失败)
|
||||
*/
|
||||
public boolean setIfAbsent(String key, Object value, long time, TimeUnit timeUnit) {
|
||||
try {
|
||||
Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
|
||||
return result != null && result;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*
|
||||
|
||||
@@ -35,6 +35,7 @@ error.verify.type.empty=Verification type cannot be empty
|
||||
error.account.format.invalid=Please enter a valid phone number or email
|
||||
error.sms.send.failed=SMS sending failed, please try again later
|
||||
error.email.send.failed=Email sending failed, please try again later
|
||||
error.sms.send.exceed=SMS sending failed, the number of available times on that day exceeded
|
||||
|
||||
# ==================== Feedback Module ====================
|
||||
# Feedback Controller
|
||||
|
||||
@@ -35,6 +35,7 @@ error.verify.type.empty=验证码类型不能为空
|
||||
error.account.format.invalid=请输入正确的手机号或邮箱
|
||||
error.sms.send.failed=短信发送失败,请稍后重试
|
||||
error.email.send.failed=邮件发送失败,请稍后重试
|
||||
error.sms.send.exceed=短信发送失败,当天可用次数超出
|
||||
|
||||
# ==================== 反馈模块 ====================
|
||||
# 反馈Controller
|
||||
|
||||
Reference in New Issue
Block a user