diff --git a/Front/vue-unilife/package.json b/Front/vue-unilife/package.json index 97c4fc1..cf6438a 100644 --- a/Front/vue-unilife/package.json +++ b/Front/vue-unilife/package.json @@ -9,6 +9,7 @@ "preview": "vite preview" }, "dependencies": { + "@vue/shared": "^3.5.13", "axios": "^1.8.3", "element-plus": "^2.9.7", "vee-validate": "^4.15.0", diff --git a/unilife-server/pom.xml b/unilife-server/pom.xml index dc2290b..99ffc1d 100644 --- a/unilife-server/pom.xml +++ b/unilife-server/pom.xml @@ -49,6 +49,12 @@ hutool-all 5.8.16 + + + org.springframework.boot + spring-boot-starter-mail + + diff --git a/unilife-server/src/main/java/com/unilife/controller/UserController.java b/unilife-server/src/main/java/com/unilife/controller/UserController.java index e4fdbf9..8ea9ad6 100644 --- a/unilife-server/src/main/java/com/unilife/controller/UserController.java +++ b/unilife-server/src/main/java/com/unilife/controller/UserController.java @@ -1,20 +1,24 @@ package com.unilife.controller; import com.unilife.common.result.Result; +import com.unilife.model.dto.EmailDTO; import com.unilife.model.dto.LogDTO; import com.unilife.model.dto.LoginDTO; import com.unilife.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; + @Api(tags = "用户管理") @RestController @RequestMapping("/users") +@Slf4j public class UserController { @Autowired @@ -29,4 +33,14 @@ public class UserController { @ApiOperation(value = "用户登录") @PostMapping("login") public Result login(@RequestBody LogDTO logDTO) { return userService.login(logDTO); } + + @ApiOperation(value = "获取邮箱验证码") + @PostMapping("code") + public Result getCode(@RequestBody EmailDTO emailDto){ + String email=emailDto.getEmail(); + log.debug("收到的原始邮箱: {}", email); + return userService.sendVerificationCode(email); + } + + } diff --git a/unilife-server/src/main/java/com/unilife/model/dto/EmailDTO.java b/unilife-server/src/main/java/com/unilife/model/dto/EmailDTO.java new file mode 100644 index 0000000..f85e62f --- /dev/null +++ b/unilife-server/src/main/java/com/unilife/model/dto/EmailDTO.java @@ -0,0 +1,12 @@ +package com.unilife.model.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class EmailDTO { + String email; +} diff --git a/unilife-server/src/main/java/com/unilife/service/UserService.java b/unilife-server/src/main/java/com/unilife/service/UserService.java index 968da9f..2e693d7 100644 --- a/unilife-server/src/main/java/com/unilife/service/UserService.java +++ b/unilife-server/src/main/java/com/unilife/service/UserService.java @@ -9,4 +9,6 @@ import com.unilife.model.entity.User; public interface UserService { Result register(LoginDTO loginDTO); Result login(LogDTO logDTO); + + Result sendVerificationCode(String email); } diff --git a/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java b/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java index eea7766..2d40a17 100644 --- a/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java +++ b/unilife-server/src/main/java/com/unilife/service/impl/UserServiceImpl.java @@ -1,6 +1,7 @@ package com.unilife.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.RandomUtil; import com.unilife.common.result.Result; import com.unilife.mapper.UserMapper; import com.unilife.model.dto.LogDTO; @@ -9,11 +10,18 @@ import com.unilife.model.entity.User; import com.unilife.model.vo.LogVO; import com.unilife.model.vo.LoginVO; import com.unilife.service.UserService; +import com.unilife.utils.RegexUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; + @Slf4j @Component @Service @@ -22,8 +30,19 @@ public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; + @Autowired + private JavaMailSender mailSender; + + @Value("${spring.mail.username}") + private String from; + + + @Override public Result register(LoginDTO loginDTO) { + if(loginDTO.getEmail().equals("") || loginDTO.getPassword().equals("")) { + return Result.error(400,"邮箱或密码不能为空"); + } User user = new User(); BeanUtil.copyProperties(loginDTO,user); userMapper.insert(user); @@ -48,4 +67,60 @@ public class UserServiceImpl implements UserService { getuser.getAvatar(), getuser.getRole(), getuser.getIsVerified(), getuser.getStatus()); return Result.success(logVO); } + + @Override + public Result sendVerificationCode(String email) { + //1.校验邮箱是否合法 + boolean emailInvalid = RegexUtils.isEmailInvalid(email); + if(emailInvalid){ + return Result.error(400,"邮箱格式不正确"); + } + + //2.生成随机验证码 + String code = RandomUtil.randomNumbers(6); + log.debug("成功生成验证码,邮箱{},验证码{}", email, code); + + + + //3.发送验证码到邮箱 + + try { + //构建邮件 + MimeMessage message=mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true); + + helper.setFrom(from); + helper.setTo(email); + helper.setSubject("UniLife - 登录验证码"); + + String content = "
" + + "

您好!

" + + "

感谢您使用UniLife平台。您的验证码是:

" + + "
" + + code + + "
" + + "

此验证码将在10分钟内有效。

" + + "

如果您没有请求此验证码,请忽略此邮件。

" + + "

" + + "这是一封自动生成的邮件,请勿直接回复。" + + "

"; + + helper.setText(content, true); + + //4.发送邮件 + mailSender.send(message); + }catch (MessagingException e){ + log.error("邮件发送失败"); + return Result.error(400,"邮件发送失败"); + } + + + //4.存储随机产生的验证码 + //TODO + + + return Result.success(200,"验证码已发送"); + + + } } diff --git a/unilife-server/src/main/java/com/unilife/utils/RegexPatterns.java b/unilife-server/src/main/java/com/unilife/utils/RegexPatterns.java new file mode 100644 index 0000000..6f7c2b2 --- /dev/null +++ b/unilife-server/src/main/java/com/unilife/utils/RegexPatterns.java @@ -0,0 +1,21 @@ +package com.unilife.utils; + +public class RegexPatterns { + /** + * 手机号正则 + */ + public static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$"; + /** + * 邮箱正则 + */ + public static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$"; + /** + * 密码正则。4~32位的字母、数字、下划线 + */ + public static final String PASSWORD_REGEX = "^\\w{4,32}$"; + /** + * 验证码正则, 6位数字或字母 + */ + public static final String VERIFY_CODE_REGEX = "^[a-zA-Z\\d]{6}$"; + +} diff --git a/unilife-server/src/main/java/com/unilife/utils/RegexUtils.java b/unilife-server/src/main/java/com/unilife/utils/RegexUtils.java new file mode 100644 index 0000000..f71719d --- /dev/null +++ b/unilife-server/src/main/java/com/unilife/utils/RegexUtils.java @@ -0,0 +1,39 @@ +package com.unilife.utils; + +import cn.hutool.core.util.StrUtil; + +public class RegexUtils { + /** + * 是否是无效手机格式 + * @param phone 要校验的手机号 + * @return true:符合,false:不符合 + */ + public static boolean isPhoneInvalid(String phone){ + return mismatch(phone, RegexPatterns.PHONE_REGEX); + } + /** + * 是否是无效邮箱格式 + * @param email 要校验的邮箱 + * @return true:符合,false:不符合 + */ + public static boolean isEmailInvalid(String email){ + return mismatch(email, RegexPatterns.EMAIL_REGEX); + } + + /** + * 是否是无效验证码格式 + * @param code 要校验的验证码 + * @return true:符合,false:不符合 + */ + public static boolean isCodeInvalid(String code){ + return mismatch(code, RegexPatterns.VERIFY_CODE_REGEX); + } + + // 校验是否不符合正则格式 + private static boolean mismatch(String str, String regex){ + if (StrUtil.isBlank(str)) { + return true; + } + return !str.matches(regex); + } +} diff --git a/unilife-server/src/main/resources/application.yml b/unilife-server/src/main/resources/application.yml index 8d8e1f5..17b36cb 100644 --- a/unilife-server/src/main/resources/application.yml +++ b/unilife-server/src/main/resources/application.yml @@ -1,11 +1,25 @@ server: - port: 8087 + port: 8084 spring: datasource: url: jdbc:mysql://localhost:3306/UniLife?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 username: root - password: zhong20050428 + password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver + mail: + host: smtp.163.com + port: 465 + username: c2991692032@163.com + password: VPq5u3NcAAqtG9GT + properties: + mail: + smtp: + auth: true + ssl: + enable: true + socketFactory: + port: 465 + class: javax.net.ssl.SSLSocketFactory knife4j: enable: true openapi: @@ -28,3 +42,6 @@ mybatis: mapper-locations: classpath:mappers/*.xml configuration: map-underscore-to-camel-case: true +logging: + level: + com.unilife: debug