diff --git a/pom.xml b/pom.xml
index 278ec98..2079d64 100644
--- a/pom.xml
+++ b/pom.xml
@@ -148,6 +148,12 @@
spring-boot-starter-mail
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
diff --git a/src/main/java/com/bao/dating/common/ResultCode.java b/src/main/java/com/bao/dating/common/ResultCode.java
index 2c7b892..9da6ee0 100644
--- a/src/main/java/com/bao/dating/common/ResultCode.java
+++ b/src/main/java/com/bao/dating/common/ResultCode.java
@@ -19,6 +19,14 @@ public enum ResultCode {
FORBIDDEN(403, "无权限"),
/** 数据不存在 */
NOT_FOUND(404, "数据不存在"),
+ /** 验证码已发送 */
+ CODE_SENT(200, "验证码已发送"),
+ /** 验证码错误 */
+ CODE_ERROR(400, "验证码错误"),
+ /** 验证码已过期 */
+ CODE_EXPIRED(400, "验证码已过期"),
+ /** 验证码发送失败 */
+ CODE_SEND_FAIL(500, "验证码发送失败"),
/** 系统异常 */
SYSTEM_ERROR(500, "系统异常"),
/** 操作失败 */
diff --git a/src/main/java/com/bao/dating/common/aliyun/SmsUtil.java b/src/main/java/com/bao/dating/common/aliyun/SmsUtil.java
index b09f8bc..290c766 100644
--- a/src/main/java/com/bao/dating/common/aliyun/SmsUtil.java
+++ b/src/main/java/com/bao/dating/common/aliyun/SmsUtil.java
@@ -149,3 +149,4 @@ public class SmsUtil {
+
diff --git a/src/main/java/com/bao/dating/controller/VerificationCodeController.java b/src/main/java/com/bao/dating/controller/VerificationCodeController.java
new file mode 100644
index 0000000..6d5084a
--- /dev/null
+++ b/src/main/java/com/bao/dating/controller/VerificationCodeController.java
@@ -0,0 +1,90 @@
+package com.bao.dating.controller;
+
+import com.bao.dating.common.Result;
+import com.bao.dating.common.ResultCode;
+import com.bao.dating.service.VerificationCodeService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 验证码控制器
+ * @author KilLze
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/verification")
+public class VerificationCodeController {
+
+ @Autowired
+ private VerificationCodeService verificationCodeService;
+
+ /**
+ * 发送邮箱验证码
+ * @param email 邮箱地址
+ * @return 结果
+ */
+ @PostMapping("/send-email-code")
+ public Result sendEmailCode(@RequestParam String email) {
+ // 参数校验
+ if (!StringUtils.hasText(email)) {
+ return Result.error(ResultCode.PARAM_ERROR, "邮箱地址不能为空");
+ }
+
+ // 简单的邮箱格式校验
+ if (!isValidEmail(email)) {
+ return Result.error(ResultCode.PARAM_ERROR, "邮箱格式不正确");
+ }
+
+ // 发送验证码
+ boolean success = verificationCodeService.sendEmailCode(email);
+
+ if (success) {
+ return Result.success(ResultCode.CODE_SENT, "验证码已发送到您的邮箱,请查收");
+ } else {
+ return Result.error(ResultCode.CODE_SEND_FAIL, "验证码发送失败,请稍后重试");
+ }
+ }
+
+ /**
+ * 验证邮箱验证码
+ * @param email 邮箱地址
+ * @param code 验证码
+ * @return 结果
+ */
+ @PostMapping("/verify-email-code")
+ public Result verifyEmailCode(@RequestParam String email, @RequestParam String code) {
+ // 参数校验
+ if (!StringUtils.hasText(email)) {
+ return Result.error(ResultCode.PARAM_ERROR, "邮箱地址不能为空");
+ }
+
+ if (!StringUtils.hasText(code)) {
+ return Result.error(ResultCode.PARAM_ERROR, "验证码不能为空");
+ }
+
+ // 验证验证码
+ boolean success = verificationCodeService.verifyEmailCode(email, code);
+
+ if (success) {
+ return Result.success(ResultCode.SUCCESS, "验证码验证成功");
+ } else {
+ return Result.error(ResultCode.CODE_ERROR, "验证码错误或已过期");
+ }
+ }
+
+ /**
+ * 简单的邮箱格式校验
+ * @param email 邮箱地址
+ * @return 是否有效
+ */
+ private boolean isValidEmail(String email) {
+ if (email == null || email.trim().isEmpty()) {
+ return false;
+ }
+ // 简单的邮箱格式校验:包含@和.
+ return email.contains("@") && email.contains(".") && email.length() > 5;
+ }
+}
+
diff --git a/src/main/java/com/bao/dating/service/VerificationCodeService.java b/src/main/java/com/bao/dating/service/VerificationCodeService.java
new file mode 100644
index 0000000..81bcd76
--- /dev/null
+++ b/src/main/java/com/bao/dating/service/VerificationCodeService.java
@@ -0,0 +1,31 @@
+package com.bao.dating.service;
+
+/**
+ * 验证码服务接口
+ * @author KilLze
+ */
+public interface VerificationCodeService {
+
+ /**
+ * 发送邮箱验证码
+ * @param email 邮箱地址
+ * @return 是否发送成功
+ */
+ boolean sendEmailCode(String email);
+
+ /**
+ * 验证邮箱验证码
+ * @param email 邮箱地址
+ * @param code 验证码
+ * @return 是否验证成功
+ */
+ boolean verifyEmailCode(String email, String code);
+
+ /**
+ * 生成验证码
+ * @param length 验证码长度(默认6位)
+ * @return 验证码字符串
+ */
+ String generateCode(int length);
+}
+
diff --git a/src/main/java/com/bao/dating/service/impl/VerificationCodeServiceImpl.java b/src/main/java/com/bao/dating/service/impl/VerificationCodeServiceImpl.java
new file mode 100644
index 0000000..19bae75
--- /dev/null
+++ b/src/main/java/com/bao/dating/service/impl/VerificationCodeServiceImpl.java
@@ -0,0 +1,122 @@
+package com.bao.dating.service.impl;
+
+import com.bao.dating.service.VerificationCodeService;
+import com.bao.dating.util.EmailUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 验证码服务实现类
+ * @author KilLze
+ */
+@Slf4j
+@Service
+public class VerificationCodeServiceImpl implements VerificationCodeService {
+
+ @Autowired
+ private EmailUtil emailUtil;
+
+ @Autowired
+ private StringRedisTemplate redisTemplate;
+
+ /**
+ * Redis中验证码的key前缀
+ */
+ private static final String CODE_KEY_PREFIX = "email:code:";
+
+ /**
+ * 验证码过期时间(分钟)
+ */
+ private static final long CODE_EXPIRE_MINUTES = 10;
+
+ /**
+ * 验证码长度
+ */
+ private static final int CODE_LENGTH = 6;
+
+ /**
+ * 发送邮箱验证码
+ * @param email 邮箱地址
+ * @return 是否发送成功
+ */
+ @Override
+ public boolean sendEmailCode(String email) {
+ try {
+ // 生成验证码
+ String code = generateCode(CODE_LENGTH);
+
+ // 存储到Redis,设置过期时间
+ String key = CODE_KEY_PREFIX + email;
+ redisTemplate.opsForValue().set(key, code, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
+
+ // 发送邮件
+ boolean sendResult = emailUtil.sendVerificationCode(email, code);
+
+ if (sendResult) {
+ log.info("邮箱验证码发送成功,邮箱:{},验证码:{}", email, code);
+ return true;
+ } else {
+ // 如果发送失败,删除Redis中的验证码
+ redisTemplate.delete(key);
+ log.error("邮箱验证码发送失败,邮箱:{}", email);
+ return false;
+ }
+ } catch (Exception e) {
+ log.error("发送邮箱验证码异常,邮箱:{},异常信息:{}", email, e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 验证邮箱验证码
+ * @param email 邮箱地址
+ * @param code 验证码
+ * @return 是否验证成功
+ */
+ @Override
+ public boolean verifyEmailCode(String email, String code) {
+ try {
+ String key = CODE_KEY_PREFIX + email;
+ String storedCode = redisTemplate.opsForValue().get(key);
+
+ if (storedCode == null) {
+ log.warn("验证码不存在或已过期,邮箱:{}", email);
+ return false;
+ }
+
+ if (storedCode.equals(code)) {
+ // 验证成功后,删除验证码(防止重复使用)
+ redisTemplate.delete(key);
+ log.info("邮箱验证码验证成功,邮箱:{}", email);
+ return true;
+ } else {
+ log.warn("邮箱验证码错误,邮箱:{},输入的验证码:{},正确的验证码:{}", email, code, storedCode);
+ return false;
+ }
+ } catch (Exception e) {
+ log.error("验证邮箱验证码异常,邮箱:{},异常信息:{}", email, e.getMessage(), e);
+ return false;
+ }
+ }
+
+ /**
+ * 生成验证码
+ * @param length 验证码长度
+ * @return 验证码字符串
+ */
+ @Override
+ public String generateCode(int length) {
+ Random random = new Random();
+ StringBuilder code = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ code.append(random.nextInt(10)); // 生成0-9的随机数字
+ }
+ return code.toString();
+ }
+}
+
diff --git a/src/main/java/com/bao/dating/util/MD5Util.java b/src/main/java/com/bao/dating/util/MD5Util.java
index 1e8cfc7..e69de29 100644
--- a/src/main/java/com/bao/dating/util/MD5Util.java
+++ b/src/main/java/com/bao/dating/util/MD5Util.java
@@ -1,93 +0,0 @@
-package com.bao.dating.util;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * MD5工具类
- * 提供MD5加密功能
- * @author KilLze
- */
-public class MD5Util {
-
- /**
- * 对字符串进行MD5加密
- * @param input 待加密的字符串
- * @return MD5加密后的32位小写字符串
- */
- public static String encrypt(String input) {
- if (input == null || input.isEmpty()) {
- return null;
- }
-
- try {
- MessageDigest md = MessageDigest.getInstance("MD5");
- byte[] digest = md.digest(input.getBytes());
- return bytesToHex(digest);
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException("MD5算法不可用", e);
- }
- }
-
- /**
- * 对字符串进行MD5加密(带盐值)
- * @param input 待加密的字符串
- * @param salt 盐值
- * @return MD5加密后的32位小写字符串
- */
- public static String encryptWithSalt(String input, String salt) {
- if (input == null || input.isEmpty()) {
- return null;
- }
- if (salt == null) {
- salt = "";
- }
- return encrypt(input + salt);
- }
-
- /**
- * 验证字符串与MD5值是否匹配
- * @param input 原始字符串
- * @param md5Hash MD5哈希值
- * @return 是否匹配
- */
- public static boolean verify(String input, String md5Hash) {
- if (input == null || md5Hash == null) {
- return false;
- }
- return encrypt(input).equalsIgnoreCase(md5Hash);
- }
-
- /**
- * 验证字符串与MD5值是否匹配(带盐值)
- * @param input 原始字符串
- * @param salt 盐值
- * @param md5Hash MD5哈希值
- * @return 是否匹配
- */
- public static boolean verifyWithSalt(String input, String salt, String md5Hash) {
- if (input == null || md5Hash == null) {
- return false;
- }
- if (salt == null) {
- salt = "";
- }
- return encryptWithSalt(input, salt).equalsIgnoreCase(md5Hash);
- }
-
- /**
- * 将字节数组转换为十六进制字符串
- * @param bytes 字节数组
- * @return 十六进制字符串
- */
- private static String bytesToHex(byte[] bytes) {
- StringBuilder sb = new StringBuilder();
- for (byte b : bytes) {
- sb.append(String.format("%02x", b));
- }
- return sb.toString();
- }
-}
-
-
-
diff --git a/src/test/java/com/bao/dating/service/VerificationCodeServiceTest.java b/src/test/java/com/bao/dating/service/VerificationCodeServiceTest.java
new file mode 100644
index 0000000..b809304
--- /dev/null
+++ b/src/test/java/com/bao/dating/service/VerificationCodeServiceTest.java
@@ -0,0 +1,91 @@
+package com.bao.dating.service;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+/**
+ * 验证码服务测试类
+ * @author KilLze
+ */
+@SpringBootTest
+public class VerificationCodeServiceTest {
+
+ @Autowired
+ private VerificationCodeService verificationCodeService;
+
+ /**
+ * 测试发送邮箱验证码
+ */
+ @Test
+ public void testSendEmailCode() {
+ String email = "test@example.com"; // 请修改为实际邮箱地址
+
+ System.out.println("========== 发送邮箱验证码测试 ==========");
+ System.out.println("邮箱地址: " + email);
+
+ boolean result = verificationCodeService.sendEmailCode(email);
+
+ System.out.println("发送结果: " + (result ? "成功" : "失败"));
+ System.out.println("=====================================");
+ }
+
+ /**
+ * 测试验证邮箱验证码
+ */
+ @Test
+ public void testVerifyEmailCode() {
+ String email = "test@example.com"; // 请修改为实际邮箱地址
+ String code = "123456"; // 请修改为实际收到的验证码
+
+ System.out.println("========== 验证邮箱验证码测试 ==========");
+ System.out.println("邮箱地址: " + email);
+ System.out.println("验证码: " + code);
+
+ boolean result = verificationCodeService.verifyEmailCode(email, code);
+
+ System.out.println("验证结果: " + (result ? "成功" : "失败"));
+ System.out.println("=====================================");
+ }
+
+ /**
+ * 测试完整流程:发送验证码 -> 验证验证码
+ */
+ @Test
+ public void testCompleteFlow() {
+ String email = "test@example.com"; // 请修改为实际邮箱地址
+
+ System.out.println("========== 完整流程测试 ==========");
+ System.out.println("邮箱地址: " + email);
+
+ // 1. 发送验证码
+ System.out.println("\n1. 发送验证码...");
+ boolean sendResult = verificationCodeService.sendEmailCode(email);
+ System.out.println("发送结果: " + (sendResult ? "成功" : "失败"));
+
+ if (sendResult) {
+ // 2. 等待用户输入验证码(这里模拟,实际应该从控制台或API获取)
+ System.out.println("\n2. 请查看邮箱获取验证码,然后手动测试验证功能");
+ System.out.println(" 使用 testVerifyEmailCode() 方法进行验证");
+ }
+
+ System.out.println("\n=====================================");
+ }
+
+ /**
+ * 测试生成验证码
+ */
+ @Test
+ public void testGenerateCode() {
+ System.out.println("========== 生成验证码测试 ==========");
+
+ // 测试不同长度的验证码
+ for (int length = 4; length <= 8; length++) {
+ String code = verificationCodeService.generateCode(length);
+ System.out.println(length + "位验证码: " + code);
+ }
+
+ System.out.println("=====================================");
+ }
+}
+
diff --git a/src/test/java/com/bao/dating/util/EmailAndSmsTest.java b/src/test/java/com/bao/dating/util/EmailAndSmsTest.java
index 55014bf..86ced71 100644
--- a/src/test/java/com/bao/dating/util/EmailAndSmsTest.java
+++ b/src/test/java/com/bao/dating/util/EmailAndSmsTest.java
@@ -75,3 +75,4 @@ public class EmailAndSmsTest {
+