Compare commits

..

2 Commits

Author SHA1 Message Date
MichaelWin
facff46bb6 【改进】参数中心增加次数下载限制 2026-02-09 12:32:23 +08:00
MichaelWin
71589ab13a 【改进】短信发送增加次数验证 2026-02-09 12:24:31 +08:00
6 changed files with 97 additions and 16 deletions

View File

@@ -9,13 +9,16 @@ import com.corewing.app.dto.UpdateParamRequest;
import com.corewing.app.entity.ParamsCenter;
import com.corewing.app.service.ParamsCenterService;
import com.corewing.app.util.I18nUtil;
import com.corewing.app.util.RedisUtil;
import com.corewing.app.vo.ParamsCenterVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* 参数配置中心 Controller
@@ -25,11 +28,11 @@ import java.util.List;
@RequestMapping("/params")
public class AppParamsCenterController {
private final ParamsCenterService paramsService;
@Resource
private ParamsCenterService paramsService;
public AppParamsCenterController(ParamsCenterService paramsService) {
this.paramsService = paramsService;
}
@Resource
private RedisUtil redisUtil;
/**
* 创建参数配置
@@ -225,6 +228,15 @@ public class AppParamsCenterController {
@PostMapping("/{id}/download")
public Result<String> incrementDownloadCount(@PathVariable Long id) {
try {
Object loginId = StpUtil.getLoginId();
boolean isNew = redisUtil.setIfAbsent("paramCenter_" + loginId, 1, 1, TimeUnit.DAYS);
// 如果键已存在,递增计数器
long sendCount = isNew ? 1 : redisUtil.incr("paramCenter_" + loginId, 1);
if(sendCount > 3) {
return Result.error(I18nUtil.getMessage("params.download.exceed"));
}
ParamsCenter params = paramsService.getById(id);
if (params == null) {
return Result.error(I18nUtil.getMessage("params.not.found"));

View File

@@ -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,6 +316,17 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
// 发送验证码
if (StringUtils.hasText(user.getTelephone())) {
// 获取当前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) {
@@ -323,6 +335,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
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);

View File

@@ -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,11 +54,24 @@ public class VerifyCodeServiceImpl implements VerifyCodeService {
// 发送验证码
if (AccountUtil.isPhone(account)) {
// 获取当前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 {
// 发送邮件验证码
boolean success = emailUtil.sendVerifyCode(account, code);

View File

@@ -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;
}
}
/**
* 递增
*

View File

@@ -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
@@ -129,6 +130,7 @@ params.not.found=Parameter not found
params.no.permission=No permission to operate this parameter
params.download.success=Download successful
params.download.failed=Download failed
params.download.exceed=Exceeded the number of downloads
# ==================== Firmware Management Module ====================
# Firmware Controller

View File

@@ -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
@@ -129,6 +130,7 @@ params.not.found=参数不存在
params.no.permission=无权限操作该参数
params.download.success=下载成功
params.download.failed=下载失败
params.download.exceed=超出次数下载
# ==================== 固件管理模块 ====================
# 固件Controller