package com.example.tanwu.t4;import java.util.concurrent.TimeUnit;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;@Servicepublic class SmsVerificationCodeService { @Autowired private RedisTemplateredisTemplate; public boolean sendVerificationCode(String mobile) { // 1. 判断是否能够发送验证码 String lastSendTimeStr = redisTemplate.opsForValue().get("sms:sendtime:" + mobile); if (lastSendTimeStr != null) { long lastSendTime = Long.parseLong(lastSendTimeStr); if (System.currentTimeMillis() - lastSendTime < 60 * 1000) { // 距离上次发送时间不足1分钟,不能发送验证码 return false; } } // 2. 判断该手机号码是否超过发送次数限制 String countStr = redisTemplate.opsForValue().get("sms:count:" + mobile); if (countStr != null && Integer.parseInt(countStr) >= 3) { // 今天已经发送了3次,不能发送验证码 return false; } // 3. 生成验证码并存储 String verificationCode = generateVerificationCode(); redisTemplate.opsForValue().set("sms:code:" + mobile, verificationCode, 5, TimeUnit.MINUTES); // 更新发送时间和发送次数 if (lastSendTimeStr == null) { redisTemplate.opsForValue().set("sms:sendtime:" + mobile, String.valueOf(System.currentTimeMillis())); } else { redisTemplate.opsForValue().set("sms:sendtime:" + mobile, String.valueOf(System.currentTimeMillis()), 1, TimeUnit.MINUTES); } if (countStr == null) { redisTemplate.opsForValue().set("sms:count:" + mobile, "1", 1, TimeUnit.DAYS); } else { redisTemplate.opsForValue().increment("sms:count:" + mobile); } // 4. TODO:发送短信验证码 return true; } public boolean verifyVerificationCode(String mobile, String verificationCode) { String code = redisTemplate.opsForValue().get("sms:code:" + mobile); if (code != null && code.equals(verificationCode)) { redisTemplate.delete("sms:code:" + mobile); return true; } return false; } private String generateVerificationCode() { // TODO:生成随机数字验证码 return "123456"; }}
package com.example.tanwu.t4;import com.baomidou.mybatisplus.core.toolkit.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.RequestParam;import java.util.Random;import java.util.concurrent.TimeUnit;//@RestControllerpublic class SmsController { @Autowired private RedisTemplateredisTemplate; //@PostMapping("/sms") public ResponseEntity sendSms(@RequestParam("phone") String phone) { // 判断该手机号码是否已经发送过验证码 String lastSendTime = redisTemplate.opsForValue().get("sms:lastSendTime:" + phone); if (StringUtils.isNotBlank(lastSendTime)) { long interval = System.currentTimeMillis() - Long.parseLong(lastSendTime); if (interval < 60000) { // 一分钟只能发送一次 return ResponseEntity.badRequest().body("短信发送频率过高,请稍后再试。"); } } // 判断该手机号码今天是否发送过超过三次验证码 String count = redisTemplate.opsForValue().get("sms:count:" + phone); if (StringUtils.isNotBlank(count) && Integer.parseInt(count) >= 3) { return ResponseEntity.badRequest().body("该手机号码今天发送验证码的次数已达到上限。"); } // 生成验证码 String code = generateCode(); // 将验证码存入 Redis 中,并设置有效期为 5 分钟 redisTemplate.opsForValue().set("sms:code:" + phone, code, 5, TimeUnit.MINUTES); // 更新该手机号码的发送时间和发送次数 redisTemplate.opsForValue().set("sms:lastSendTime:" + phone, String.valueOf(System.currentTimeMillis())); redisTemplate.opsForValue().increment("sms:count:" + phone, 1); // 发送短信验证码 sendSms(phone, code); return ResponseEntity.ok("短信验证码已发送。"); } // 生成随机验证码 private String generateCode() { Random random = new Random(); return String.valueOf(100000 + random.nextInt(900000)); } // 发送短信验证码 private void sendSms(String phone, String code) { // 省略发送短信验证码的代码 }}
package com.example.tanwu.t4;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.Scheduled;import java.util.Set;@Configuration@EnableSchedulingpublic class ScheduleConfig { @Autowired private RedisTemplateredisTemplate; // 每天凌晨 0 点清除 Redis 中的验证码发送次数 @Scheduled(cron = "0 0 0 * * ?") public void clearSmsCount() { Set keys = redisTemplate.keys("sms:count:*"); redisTemplate.delete(keys); }}