发送邮箱验证码-基础设置
This commit is contained in:
parent
bbfe532bca
commit
1b7bf095dc
@ -2,17 +2,19 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<annotationProcessing>
|
<annotationProcessing>
|
||||||
|
<profile default="true" name="Default" enabled="true" />
|
||||||
<profile name="Maven default annotation processors profile" enabled="true">
|
<profile name="Maven default annotation processors profile" enabled="true">
|
||||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
<outputRelativeToContentRoot value="true" />
|
<outputRelativeToContentRoot value="true" />
|
||||||
|
<module name="YuNan-demo" />
|
||||||
</profile>
|
</profile>
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
</component>
|
</component>
|
||||||
<component name="JavacSettings">
|
<component name="JavacSettings">
|
||||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||||
<module name="YuNan-cmd" options="" />
|
<module name="YuNan-cmd" options="" />
|
||||||
<module name="YuNan-demo" options="" />
|
<module name="YuNan-demo" options="-parameters" />
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Encoding">
|
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
||||||
<file url="file://$PROJECT_DIR$/YuNan-demo/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/YuNan-demo/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/YuNan-demo/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/YuNan-demo/src/main/resources" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="PROJECT" charset="UTF-8" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -9,7 +9,7 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -10,14 +10,21 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>YuNan-demo</artifactId>
|
<artifactId>YuNan-demo</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- 添加特有的依赖 -->
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,13 +1,31 @@
|
|||||||
package com.yunan;
|
package com.yunan;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
@SpringBootApplication
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@SpringBootApplication(scanBasePackages = "com.yunan")
|
||||||
public class YuNanDemoApplication {
|
public class YuNanDemoApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(YuNanDemoApplication.class, args);
|
SpringApplication.run(YuNanDemoApplication.class, args);
|
||||||
|
|
||||||
|
// 获取本地 IP 地址
|
||||||
|
String ip;
|
||||||
|
try {
|
||||||
|
ip = InetAddress.getLocalHost().getHostAddress(); // 获取本地 IP 地址
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
ip = "localhost"; // 如果无法获取 IP,设为 localhost
|
||||||
|
}
|
||||||
|
// 打印 Swagger 文档的 URL
|
||||||
|
log.info("\n----------------------------------------------------------\n\t" +
|
||||||
|
"Swagger文档: \thttp://" + ip + ":8080/doc.html\n" +
|
||||||
|
"----------------------------------------------------------");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.yunan.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class GlobalCorsConfig {
|
||||||
|
/**
|
||||||
|
* 解决跨域问题
|
||||||
|
* @return {@link CorsFilter }
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CorsFilter corsFilter() {
|
||||||
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
|
// 设置你要允许的网站域名
|
||||||
|
config.addAllowedOrigin("http://localhost:3100");
|
||||||
|
//允许跨域发送cookie
|
||||||
|
config.setAllowCredentials(true);
|
||||||
|
//放行全部原始头信息
|
||||||
|
config.addAllowedHeader("*");
|
||||||
|
//允许所有请求方法跨域调用
|
||||||
|
config.addAllowedMethod("*");
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
return new CorsFilter(source);
|
||||||
|
}
|
||||||
|
}
|
26
YuNan-demo/src/main/java/com/yunan/config/RedisConfig.java
Normal file
26
YuNan-demo/src/main/java/com/yunan/config/RedisConfig.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package com.yunan.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
|
||||||
|
/*告诉spring,运行的时候加载读取这个类*/
|
||||||
|
@Configuration
|
||||||
|
public class RedisConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, Object>
|
||||||
|
redisTemplate(RedisConnectionFactory connectionFactory) {
|
||||||
|
RedisTemplate<String, Object> redisTemplate = new
|
||||||
|
RedisTemplate<String, Object>();
|
||||||
|
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||||
|
redisTemplate.setValueSerializer
|
||||||
|
(new JdkSerializationRedisSerializer());
|
||||||
|
redisTemplate.setConnectionFactory(connectionFactory);
|
||||||
|
return redisTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
106
YuNan-demo/src/main/java/com/yunan/config/SwaggerConfig.java
Normal file
106
YuNan-demo/src/main/java/com/yunan/config/SwaggerConfig.java
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package com.yunan.config;
|
||||||
|
//
|
||||||
|
//import org.springframework.context.annotation.Bean;
|
||||||
|
//import org.springframework.context.annotation.Configuration;
|
||||||
|
//import springfox.documentation.builders.ApiInfoBuilder;
|
||||||
|
//import springfox.documentation.builders.PathSelectors;
|
||||||
|
//import springfox.documentation.builders.RequestHandlerSelectors;
|
||||||
|
//import springfox.documentation.oas.annotations.EnableOpenApi;
|
||||||
|
//import springfox.documentation.service.ApiInfo;
|
||||||
|
//import springfox.documentation.service.Contact;
|
||||||
|
//import springfox.documentation.spi.DocumentationType;
|
||||||
|
//import springfox.documentation.spring.web.plugins.Docket;
|
||||||
|
//
|
||||||
|
//import java.util.Collections;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//@Configuration //声明配置类
|
||||||
|
//@EnableOpenApi //开启swagger支持
|
||||||
|
//public class SwaggerConfig {
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Docket类是Swagger的配置类,要自定义修改Swagger的默认配置信息,我们需要覆盖该对象
|
||||||
|
// *
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// @Bean
|
||||||
|
// public Docket docket() {
|
||||||
|
// //1.以OAS_30标准构建Docket配置类
|
||||||
|
// return new Docket(DocumentationType.OAS_30)
|
||||||
|
// //2.配置Swagger接口文档基本信息apiInfo
|
||||||
|
// .apiInfo(apiInfo())
|
||||||
|
// //3.select方法开启配置扫描接口的Builder
|
||||||
|
// .select()
|
||||||
|
// //4.指定要扫描/维护接口文档的包(否则就全部扫描)
|
||||||
|
// .apis(RequestHandlerSelectors.basePackage("com.yunan.controller"))
|
||||||
|
// //5.路径过滤:该Docket-UI展示时,只展示指定路径下的接口文档(any表示都展示)
|
||||||
|
// .paths(PathSelectors.any())
|
||||||
|
// .build();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 配置 Swagger 接口文档的基本信息
|
||||||
|
// *
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// private ApiInfo apiInfo() {
|
||||||
|
// return new ApiInfoBuilder()
|
||||||
|
// //1.接口文档标题
|
||||||
|
// .title("SpringBoot整合Swagger")
|
||||||
|
// //2.接口文档描述内容
|
||||||
|
// .description("这里是SpringBoot整合Swagger的详细信息......,包括...")
|
||||||
|
// //3.项目文档迭代版本
|
||||||
|
// .version("9.0")
|
||||||
|
// //4.主要联系人信息(姓名name,个人主页url,邮箱email)
|
||||||
|
//// .contact(new Contact("阿安", "www.baidu.com", "3194726156@qq.com"))
|
||||||
|
// //5.相关许可证信息
|
||||||
|
//// .license("The CSDN License")
|
||||||
|
// //6.相关许可证链接
|
||||||
|
//// .licenseUrl("www.baidu.com")
|
||||||
|
// //7.返回构建的ApiInfo对象
|
||||||
|
// .build();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import springfox.documentation.builders.PathSelectors;
|
||||||
|
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||||
|
import springfox.documentation.service.ApiInfo;
|
||||||
|
import springfox.documentation.service.Contact;
|
||||||
|
import springfox.documentation.spi.DocumentationType;
|
||||||
|
import springfox.documentation.spring.web.plugins.Docket;
|
||||||
|
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableSwagger2
|
||||||
|
public class SwaggerConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Docket api() {
|
||||||
|
return new Docket(DocumentationType.SWAGGER_2)
|
||||||
|
.select()
|
||||||
|
.apis(RequestHandlerSelectors.basePackage("com.yunan.controller")) // 替换为你的包名
|
||||||
|
.paths(PathSelectors.any())
|
||||||
|
.build()
|
||||||
|
.apiInfo(apiInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiInfo apiInfo() {
|
||||||
|
return new ApiInfo(
|
||||||
|
"API标题", // 标题
|
||||||
|
"API描述", // 描述
|
||||||
|
"版本信息", // 版本
|
||||||
|
"服务条款URL", // 服务条款URL
|
||||||
|
new Contact("联系人姓名", "网址", "邮箱"), // 联系人信息
|
||||||
|
"许可证", // 许可证
|
||||||
|
"许可证URL", // 许可证URL
|
||||||
|
Collections.emptyList() // 扩展列表
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.yunan.constant;
|
||||||
|
|
||||||
|
public class ResponseCode {
|
||||||
|
|
||||||
|
// 成功
|
||||||
|
public static final int SUCCESS = 200;
|
||||||
|
|
||||||
|
// 失败
|
||||||
|
public static final int ERROR = 500;
|
||||||
|
|
||||||
|
// 其他常用的状态码
|
||||||
|
public static final int BAD_REQUEST = 400;
|
||||||
|
public static final int UNAUTHORIZED = 401;
|
||||||
|
public static final int FORBIDDEN = 403;
|
||||||
|
public static final int NOT_FOUND = 404;
|
||||||
|
|
||||||
|
// 你可以根据需要继续添加其他状态码
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,90 @@
|
|||||||
|
package com.yunan.controller;
|
||||||
|
|
||||||
|
import com.yunan.constant.ResponseCode;
|
||||||
|
import com.yunan.dto.ApiResponse;
|
||||||
|
import com.yunan.dto.LoginDTO;
|
||||||
|
import com.yunan.dto.RegisterDTO;
|
||||||
|
import com.yunan.entity.Mail;
|
||||||
|
import com.yunan.pojo.User;
|
||||||
|
import com.yunan.service.AuthService;
|
||||||
|
import com.yunan.service.EmailService;
|
||||||
|
import com.yunan.util.VerificationCodeUtils;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.v3.oas.annotations.parameters.RequestBody;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController //注解标识这是一个控制器类
|
||||||
|
@RequestMapping("/auth")
|
||||||
|
@Slf4j
|
||||||
|
@Api(tags = "身份验证接口")
|
||||||
|
public class AuthController {
|
||||||
|
@Resource
|
||||||
|
private AuthService authService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailService emailService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登入
|
||||||
|
* @param loginDTO
|
||||||
|
*/
|
||||||
|
@PostMapping("/login")
|
||||||
|
@ApiOperation("用户登入")
|
||||||
|
public void login(@RequestBody LoginDTO loginDTO) {
|
||||||
|
// authService.login(loginDTO.getUsername(), loginDTO.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户注册
|
||||||
|
* @param registerDTO
|
||||||
|
*/
|
||||||
|
@PostMapping("/register")
|
||||||
|
@ApiOperation("用户注册")
|
||||||
|
public ResponseEntity<User> register(@RequestBody RegisterDTO registerDTO) {
|
||||||
|
// return authService.register(registerDTO);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存储已发送的验证码
|
||||||
|
private final Map<String, String> emailCodeMap = new ConcurrentHashMap<>(16);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送验证码
|
||||||
|
* @param mail
|
||||||
|
* @return {@link ApiResponse }<{@link String }>
|
||||||
|
* @throws MessagingException
|
||||||
|
*/
|
||||||
|
@PostMapping("/sendEmail")
|
||||||
|
@ApiOperation("邮箱验证码")
|
||||||
|
public ApiResponse<String> sendEmail(@RequestBody Mail mail) throws MessagingException {
|
||||||
|
// 生成验证码
|
||||||
|
String code = VerificationCodeUtils.generateCode(6);
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
|
String subject = "注册验证码";
|
||||||
|
String content = "尊敬的用户,您的验证码为:" + code;
|
||||||
|
emailService.sendMail(mail.email, subject, content);
|
||||||
|
|
||||||
|
// 保存验证码
|
||||||
|
emailCodeMap.put(mail.email, code);
|
||||||
|
|
||||||
|
return new ApiResponse<>(ResponseCode.SUCCESS,"验证码已发送");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
46
YuNan-demo/src/main/java/com/yunan/dto/ApiResponse.java
Normal file
46
YuNan-demo/src/main/java/com/yunan/dto/ApiResponse.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package com.yunan.dto;
|
||||||
|
|
||||||
|
|
||||||
|
public class ApiResponse<T> {
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
private String message;
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public ApiResponse(int code, String message) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiResponse(int code, String message, T data) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(T data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
57
YuNan-demo/src/main/java/com/yunan/dto/LoginDTO.java
Normal file
57
YuNan-demo/src/main/java/com/yunan/dto/LoginDTO.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package com.yunan.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@ApiModel("用户登入请求")
|
||||||
|
public class LoginDTO {
|
||||||
|
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
@ApiModelProperty(value = "用户名", required = true)
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Email(message = "请输入有效的邮箱")
|
||||||
|
@ApiModelProperty(value = "邮箱")
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
@ApiModelProperty(value = "密码", required = true)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
}
|
67
YuNan-demo/src/main/java/com/yunan/dto/RegisterDTO.java
Normal file
67
YuNan-demo/src/main/java/com/yunan/dto/RegisterDTO.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package com.yunan.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Email;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@ApiModel("用户注册请求")
|
||||||
|
public class RegisterDTO {
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
@ApiModelProperty(value = "用户名", required = true)
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Email(message = "请输入有效的邮箱")
|
||||||
|
@ApiModelProperty(value = "邮箱", required = true)
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@NotBlank(message = "密码不能为空")
|
||||||
|
@ApiModelProperty(value = "密码", required = true)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "验证码")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
}
|
12
YuNan-demo/src/main/java/com/yunan/entity/Mail.java
Normal file
12
YuNan-demo/src/main/java/com/yunan/entity/Mail.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.yunan.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Mail {
|
||||||
|
public String email;
|
||||||
|
public String username;
|
||||||
|
public String password;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
13
YuNan-demo/src/main/java/com/yunan/mapper/AuthMapper.java
Normal file
13
YuNan-demo/src/main/java/com/yunan/mapper/AuthMapper.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.yunan.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.yunan.dto.RegisterDTO;
|
||||||
|
import com.yunan.pojo.User;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AuthMapper extends BaseMapper<User> {
|
||||||
|
void insertUser(RegisterDTO registerDTO);
|
||||||
|
|
||||||
|
User findUserByEmail(String email);
|
||||||
|
}
|
90
YuNan-demo/src/main/java/com/yunan/pojo/User.java
Normal file
90
YuNan-demo/src/main/java/com/yunan/pojo/User.java
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package com.yunan.pojo;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户实体类
|
||||||
|
*/
|
||||||
|
public class User implements Serializable {
|
||||||
|
private int id;
|
||||||
|
/** 用户名*/
|
||||||
|
private String username;
|
||||||
|
/** 密码*/
|
||||||
|
private String password;
|
||||||
|
/** 邮箱*/
|
||||||
|
private String email;
|
||||||
|
/** 创建用户信息时间 */
|
||||||
|
private String createTime;
|
||||||
|
/** 修改用户信息时间 */
|
||||||
|
private String updateTime;
|
||||||
|
/** 用户状态*/
|
||||||
|
private int state;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User{" +
|
||||||
|
"username='" + username + '\'' +
|
||||||
|
", password='" + password + '\'' +
|
||||||
|
", email='" + email + '\'' +
|
||||||
|
", createTime='" + createTime + '\'' +
|
||||||
|
", updateTime='" + updateTime + '\'' +
|
||||||
|
", state=" + state +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsername(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmai() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmai(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setState(int state) {
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCreate_Time() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreate_Time(String create_Time) {
|
||||||
|
this.createTime = create_Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUpdate_Time() {
|
||||||
|
return updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdate_Time(String update_Time) {
|
||||||
|
this.updateTime = update_Time;
|
||||||
|
}
|
||||||
|
}
|
17
YuNan-demo/src/main/java/com/yunan/service/AuthService.java
Normal file
17
YuNan-demo/src/main/java/com/yunan/service/AuthService.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.yunan.service;
|
||||||
|
|
||||||
|
|
||||||
|
import com.yunan.dto.ApiResponse;
|
||||||
|
import com.yunan.dto.RegisterDTO;
|
||||||
|
import com.yunan.entity.Mail;
|
||||||
|
import com.yunan.pojo.User;
|
||||||
|
|
||||||
|
import javax.mail.internet.AddressException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
public interface AuthService {
|
||||||
|
|
||||||
|
|
||||||
|
User register(RegisterDTO registerDTO) throws AddressException, UnsupportedEncodingException;
|
||||||
|
|
||||||
|
}
|
43
YuNan-demo/src/main/java/com/yunan/service/EmailService.java
Normal file
43
YuNan-demo/src/main/java/com/yunan/service/EmailService.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package com.yunan.service;
|
||||||
|
|
||||||
|
|
||||||
|
import com.yunan.dto.ApiResponse;
|
||||||
|
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.Service;
|
||||||
|
|
||||||
|
import javax.mail.MessagingException;
|
||||||
|
import javax.mail.internet.MimeMessage;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class EmailService {
|
||||||
|
@Autowired
|
||||||
|
private JavaMailSender mailSender;
|
||||||
|
|
||||||
|
@Value("${spring.mail.username}")
|
||||||
|
private String from;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮件
|
||||||
|
*
|
||||||
|
* @param to 收件人邮箱
|
||||||
|
* @param subject 邮件主题
|
||||||
|
* @param content 邮件内容
|
||||||
|
*/
|
||||||
|
public void sendMail(String to, String subject, String content) throws MessagingException {
|
||||||
|
// 创建邮件消息
|
||||||
|
MimeMessage message = mailSender.createMimeMessage();
|
||||||
|
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||||
|
helper.setFrom(from);
|
||||||
|
helper.setTo(to);
|
||||||
|
helper.setSubject(subject);
|
||||||
|
helper.setText(content, true);
|
||||||
|
|
||||||
|
// 发送邮件
|
||||||
|
mailSender.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,124 @@
|
|||||||
|
package com.yunan.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.yunan.constant.ResponseCode;
|
||||||
|
import com.yunan.dto.ApiResponse;
|
||||||
|
import com.yunan.dto.RegisterDTO;
|
||||||
|
import com.yunan.mapper.AuthMapper;
|
||||||
|
import com.yunan.pojo.User;
|
||||||
|
import com.yunan.service.AuthService;
|
||||||
|
import com.yunan.util.VerificationCodeUtils;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ValueOperations;
|
||||||
|
import org.springframework.mail.SimpleMailMessage;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.mail.internet.AddressException;
|
||||||
|
import javax.mail.internet.InternetAddress;
|
||||||
|
import javax.mail.internet.MimeUtility;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AuthServiceImpl implements AuthService {
|
||||||
|
@Resource
|
||||||
|
private AuthMapper authMapper;
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private JavaMailSender mailSender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送邮箱验证码
|
||||||
|
*
|
||||||
|
* @param email
|
||||||
|
* @return {@link String }
|
||||||
|
*/
|
||||||
|
public String sendEmail(@PathVariable String email) throws UnsupportedEncodingException, AddressException {
|
||||||
|
String key = "msg_" + email;
|
||||||
|
|
||||||
|
ValueOperations valueOperations = stringRedisTemplate.opsForValue();
|
||||||
|
String already_have = (String) valueOperations.get(key);
|
||||||
|
if (already_have == null) {
|
||||||
|
// 随机生成一个6位数字型的字符串
|
||||||
|
String code = "123456";
|
||||||
|
// 邮件对象
|
||||||
|
SimpleMailMessage message = new SimpleMailMessage();
|
||||||
|
message.setSubject("医院小程序邮箱验证码");
|
||||||
|
message.setText("尊敬的用户您好!\n\n感谢您使用XX医院。\n\n尊敬的: " + email + "您的校验验证码为: " + code + ",有效期2分钟,请不要把验证码信息泄露给其他人,如非本人请勿操作");
|
||||||
|
message.setTo(email);
|
||||||
|
// 对方看到的发送人
|
||||||
|
message.setFrom(new InternetAddress(MimeUtility.encodeText("医院官方") + "<2774668116@qq.com>").toString());
|
||||||
|
//发送邮件
|
||||||
|
mailSender.send(message);
|
||||||
|
valueOperations.set(key, code, 5L, TimeUnit.MINUTES);
|
||||||
|
return code;
|
||||||
|
} else {
|
||||||
|
return already_have;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证码验证是否正确
|
||||||
|
* @param email
|
||||||
|
* @param code
|
||||||
|
* @return {@link Integer }
|
||||||
|
*/
|
||||||
|
public Integer verifyCode(String email, String code) {
|
||||||
|
int result = 1;
|
||||||
|
ValueOperations valueOperations = stringRedisTemplate.opsForValue();
|
||||||
|
String msgKey = "msg_" + email;
|
||||||
|
Object value = valueOperations.get(msgKey);
|
||||||
|
if(value == null){
|
||||||
|
result = -1;
|
||||||
|
}else if(!code.equals(value)) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
// 如果验证码正确,则删除从redis
|
||||||
|
if(result == 1){
|
||||||
|
stringRedisTemplate.delete(msgKey);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
1 验证码正确
|
||||||
|
0 验证码错误
|
||||||
|
-1 验证码过期
|
||||||
|
*/
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User register(RegisterDTO registerDTO) throws AddressException, UnsupportedEncodingException {
|
||||||
|
String code = sendEmail(registerDTO.getEmail());
|
||||||
|
Integer result = verifyCode(registerDTO.getEmail(), registerDTO.getCode());
|
||||||
|
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
if(result == 1){
|
||||||
|
queryWrapper.eq(User::getUsername, registerDTO.getUsername());
|
||||||
|
Long l = authMapper.selectCount(queryWrapper);
|
||||||
|
if(l == 0){
|
||||||
|
// 插入用户到数据库
|
||||||
|
authMapper.insertUser(registerDTO);
|
||||||
|
// emailServiceImpl.sendEmail(registerDTO.getEmail(), "注册确认", "请点击以下链接进行确认...");
|
||||||
|
|
||||||
|
// 返回注册成功的用户对象(可根据需求返回具体的 User 对象)
|
||||||
|
// LambdaQueryWrapper<User> queryWrapperByEmail = new LambdaQueryWrapper<>();
|
||||||
|
// queryWrapperByEmail.eq(User::getEmai, registerDTO.getEmail());
|
||||||
|
return authMapper.findUserByEmail(registerDTO.getEmail()); // 假设有这个方法来查询用户
|
||||||
|
}else{
|
||||||
|
throw new RuntimeException("用户存在,请重新输入");
|
||||||
|
}
|
||||||
|
} else if (result == -1) { // 验证码过期
|
||||||
|
throw new RuntimeException("验证码已过期,请重新获取"); // 或者定义自定义异常
|
||||||
|
} else { // 验证码错误
|
||||||
|
throw new RuntimeException("验证码错误,请检查后重试"); // 或者定义自定义异常
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
571
YuNan-demo/src/main/java/com/yunan/util/RedisUtils.java
Normal file
571
YuNan-demo/src/main/java/com/yunan/util/RedisUtils.java
Normal file
@ -0,0 +1,571 @@
|
|||||||
|
package com.yunan.util;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* redis 工具类
|
||||||
|
*
|
||||||
|
* @author simon
|
||||||
|
* @date 2018-11-28 10:35
|
||||||
|
**/
|
||||||
|
@Component
|
||||||
|
public class RedisUtils {
|
||||||
|
/**
|
||||||
|
* 注入redisTemplate bean
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String,Object> redisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定缓存失效时间
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param time 时间(秒)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean expire(String key, long time) {
|
||||||
|
try {
|
||||||
|
if (time > 0) {
|
||||||
|
redisTemplate.expire(key, time, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据key获取过期时间
|
||||||
|
*
|
||||||
|
* @param key 键 不能为null
|
||||||
|
* @return 时间(秒) 返回0代表为永久有效
|
||||||
|
*/
|
||||||
|
public long getExpire(String key) {
|
||||||
|
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断key是否存在
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return true 存在 false不存在
|
||||||
|
*/
|
||||||
|
public boolean hasKey(String key) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.hasKey(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除缓存
|
||||||
|
*
|
||||||
|
* @param key 可以传一个值 或多个
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void del(String... key) {
|
||||||
|
if (key != null && key.length > 0) {
|
||||||
|
if (key.length == 1) {
|
||||||
|
redisTemplate.delete(key[0]);
|
||||||
|
} else {
|
||||||
|
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ============================String(字符串)=============================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普通缓存获取
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public Object get(String key) {
|
||||||
|
return key == null ? null : redisTemplate.opsForValue().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普通缓存放入
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @return true成功 false失败
|
||||||
|
*/
|
||||||
|
public boolean set(String key, Object value) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForValue().set(key, value);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 普通缓存放入并设置时间
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
|
||||||
|
* @return true成功 false 失败
|
||||||
|
*/
|
||||||
|
public boolean set(String key, Object value, long time) {
|
||||||
|
try {
|
||||||
|
if (time > 0) {
|
||||||
|
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
|
||||||
|
} else {
|
||||||
|
set(key, value);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递增
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param delta 要增加几(大于0)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long incr(String key, long delta) {
|
||||||
|
if (delta < 0) {
|
||||||
|
throw new RuntimeException("递增因子必须大于0");
|
||||||
|
}
|
||||||
|
return redisTemplate.opsForValue().increment(key, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递减
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param delta 要减少几(小于0)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long decr(String key, long delta) {
|
||||||
|
if (delta < 0) {
|
||||||
|
throw new RuntimeException("递减因子必须大于0");
|
||||||
|
}
|
||||||
|
return redisTemplate.opsForValue().increment(key, -delta);
|
||||||
|
}
|
||||||
|
// ================================Hash(哈希)=================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HashGet
|
||||||
|
*
|
||||||
|
* @param key 键 不能为null
|
||||||
|
* @param item 项 不能为null
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public Object hget(String key, String item) {
|
||||||
|
return redisTemplate.opsForHash().get(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取hashKey对应的所有键值
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return 对应的多个键值
|
||||||
|
*/
|
||||||
|
public Map<Object, Object> hmget(String key) {
|
||||||
|
return redisTemplate.opsForHash().entries(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HashSet
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param map 对应多个键值
|
||||||
|
* @return true 成功 false 失败
|
||||||
|
*/
|
||||||
|
public boolean hmset(String key, Map <String, Object> map) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForHash().putAll(key, map);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HashSet 并设置时间
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param map 对应多个键值
|
||||||
|
* @param time 时间(秒)
|
||||||
|
* @return true成功 false失败
|
||||||
|
*/
|
||||||
|
public boolean hmset(String key, Map <String, Object> map, long time) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForHash().putAll(key, map);
|
||||||
|
if (time > 0) {
|
||||||
|
expire(key, time);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向一张hash表中放入数据,如果不存在将创建
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param item 项
|
||||||
|
* @param value 值
|
||||||
|
* @return true 成功 false失败
|
||||||
|
*/
|
||||||
|
public boolean hset(String key, String item, Object value) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForHash().put(key, item, value);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向一张hash表中放入数据,如果不存在将创建
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param item 项
|
||||||
|
* @param value 值
|
||||||
|
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
|
||||||
|
* @return true 成功 false失败
|
||||||
|
*/
|
||||||
|
public boolean hset(String key, String item, Object value, long time) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForHash().put(key, item, value);
|
||||||
|
if (time > 0) {
|
||||||
|
expire(key, time);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除hash表中的值
|
||||||
|
*
|
||||||
|
* @param key 键 不能为null
|
||||||
|
* @param item 项 可以使多个 不能为null
|
||||||
|
*/
|
||||||
|
public void hdel(String key, Object... item) {
|
||||||
|
redisTemplate.opsForHash().delete(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断hash表中是否有该项的值
|
||||||
|
*
|
||||||
|
* @param key 键 不能为null
|
||||||
|
* @param item 项 不能为null
|
||||||
|
* @return true 存在 false不存在
|
||||||
|
*/
|
||||||
|
public boolean hHasKey(String key, String item) {
|
||||||
|
return redisTemplate.opsForHash().hasKey(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param item 项
|
||||||
|
* @param by 要增加几(大于0)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public double hincr(String key, String item, double by) {
|
||||||
|
return redisTemplate.opsForHash().increment(key, item, by);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hash递减
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param item 项
|
||||||
|
* @param by 要减少记(小于0)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public double hdecr(String key, String item, double by) {
|
||||||
|
return redisTemplate.opsForHash().increment(key, item, -by);
|
||||||
|
}
|
||||||
|
// ============================Set(集合)=============================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据key获取Set中的所有值
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Set<Object> sGet(String key) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.opsForSet().members(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据value从一个set中查询,是否存在
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @return true 存在 false不存在
|
||||||
|
*/
|
||||||
|
public boolean sHasKey(String key, Object value) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.opsForSet().isMember(key, value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将数据放入set缓存
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param values 值 可以是多个
|
||||||
|
* @return 成功个数
|
||||||
|
*/
|
||||||
|
public long sSet(String key, Object... values) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.opsForSet().add(key, values);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将set数据放入缓存
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param time 时间(秒)
|
||||||
|
* @param values 值 可以是多个
|
||||||
|
* @return 成功个数
|
||||||
|
*/
|
||||||
|
public long sSetAndTime(String key, long time, Object... values) {
|
||||||
|
try {
|
||||||
|
Long count = redisTemplate.opsForSet().add(key, values);
|
||||||
|
if (time > 0)
|
||||||
|
expire(key, time);
|
||||||
|
return count;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取set缓存的长度
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long sGetSetSize(String key) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.opsForSet().size(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除值为value的
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param values 值 可以是多个
|
||||||
|
* @return 移除的个数
|
||||||
|
*/
|
||||||
|
public long setRemove(String key, Object... values) {
|
||||||
|
try {
|
||||||
|
Long count = redisTemplate.opsForSet().remove(key, values);
|
||||||
|
return count;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ===============================List(列表)=================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取list缓存的内容
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param start 开始
|
||||||
|
* @param end 结束 0 到 -1代表所有值
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<Object> lGet(String key, long start, long end) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.opsForList().range(key, start, end);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取list缓存的长度
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long lGetListSize(String key) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.opsForList().size(key);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过索引 获取list中的值
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Object lGetIndex(String key, long index) {
|
||||||
|
try {
|
||||||
|
return redisTemplate.opsForList().index(key, index);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将list放入缓存
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean lSet(String key, Object value) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForList().rightPush(key, value);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将list放入缓存
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @param time 时间(秒)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean lSet(String key, Object value, long time) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForList().rightPush(key, value);
|
||||||
|
if (time > 0)
|
||||||
|
expire(key, time);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将list放入缓存
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean lSet(String key, List <Object> value) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForList().rightPushAll(key, value);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将list放入缓存
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param value 值
|
||||||
|
* @param time 时间(秒)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean lSet(String key, List <Object> value, long time) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForList().rightPushAll(key, value);
|
||||||
|
if (time > 0)
|
||||||
|
expire(key, time);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据索引修改list中的某条数据
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param index 索引
|
||||||
|
* @param value 值
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean lUpdateIndex(String key, long index, Object value) {
|
||||||
|
try {
|
||||||
|
redisTemplate.opsForList().set(key, index, value);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除N个值为value
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @param count 移除多少个
|
||||||
|
* @param value 值
|
||||||
|
* @return 移除的个数
|
||||||
|
*/
|
||||||
|
public long lRemove(String key, long count, Object value) {
|
||||||
|
try {
|
||||||
|
Long remove = redisTemplate.opsForList().remove(key, count, value);
|
||||||
|
return remove;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.yunan.util;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class VerificationCodeUtils {
|
||||||
|
/**
|
||||||
|
* 生成随机验证码
|
||||||
|
*
|
||||||
|
* @param length 验证码长度
|
||||||
|
* @return 验证码
|
||||||
|
*/
|
||||||
|
public static String generateCode(int length) {
|
||||||
|
StringBuilder s = new StringBuilder();
|
||||||
|
Random random = new Random();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int n = random.nextInt(10);
|
||||||
|
s.append(n);
|
||||||
|
}
|
||||||
|
return s.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
55
YuNan-demo/src/main/resources/application.yml
Normal file
55
YuNan-demo/src/main/resources/application.yml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: YuNan-demo
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://localhost:3306/yuna_blog_sys
|
||||||
|
username: root
|
||||||
|
password: wucong.0235332
|
||||||
|
mvc:
|
||||||
|
pathmatch:
|
||||||
|
matching-strategy: ant-path-matcher
|
||||||
|
|
||||||
|
#****************************mail***************************
|
||||||
|
mail:
|
||||||
|
# SMTP服务器,这个是QQ邮箱的 其他邮箱请另行百度
|
||||||
|
host: smtp.qq.com
|
||||||
|
port: 465
|
||||||
|
# 发送验证码的邮箱
|
||||||
|
username: 3194726156@qq.com
|
||||||
|
# 授权码
|
||||||
|
password: ljtcrhshbfjodgfh
|
||||||
|
# 编码
|
||||||
|
default-encoding: utf-8
|
||||||
|
# 其它参数
|
||||||
|
properties:
|
||||||
|
mail:
|
||||||
|
smtp:
|
||||||
|
# 如果是用 SSL 方式,需要配置如下属性,使用qq邮箱的话需要开启
|
||||||
|
ssl:
|
||||||
|
enable: true
|
||||||
|
required: true
|
||||||
|
# 邮件接收时间的限制,单位毫秒
|
||||||
|
timeout: 10000
|
||||||
|
# 连接时间的限制,单位毫秒
|
||||||
|
connectiontimeout: 10000
|
||||||
|
# 邮件发送时间的限制,单位毫秒
|
||||||
|
writetimeout: 10000
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#****************************Redis***************************
|
||||||
|
redis:
|
||||||
|
host: localhost # Redis 服务器地址
|
||||||
|
port: 6379 # Redis 服务器端口
|
||||||
|
password: # 如果 Redis 设置了密码
|
||||||
|
database: 0 # 使用的数据库索引,默认是 0
|
||||||
|
|
||||||
|
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
org.springframework.boot.context.web: DEBUG
|
88
pom.xml
88
pom.xml
@ -8,23 +8,58 @@
|
|||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<!-- 子模块列表 -->
|
||||||
|
<module>YuNan-demo</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.3.4</version>
|
<version>2.7.10</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<!-- 版本控制 -->
|
||||||
|
|
||||||
<!-- 版本控制 -->
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>17</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
<mysql.version>8.0.32</mysql.version>
|
||||||
|
<mybatis-plus.version>3.5.3</mybatis-plus.version>
|
||||||
|
<testng.version>7.4.0</testng.version>
|
||||||
|
<swagger.version>3.0.0</swagger.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- 依赖导入 -->
|
<!-- 依赖导入 -->
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testng</groupId>
|
||||||
|
<artifactId>testng</artifactId>
|
||||||
|
<version>${testng.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
@ -35,6 +70,47 @@
|
|||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<version>${mysql.version}</version> <!-- 请根据需要调整版本 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
<version>${mybatis-plus.version}</version> <!-- 确保使用正确的版本 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.springfox</groupId>
|
||||||
|
<artifactId>springfox-boot-starter</artifactId>
|
||||||
|
<version>${swagger.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
|
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||||
|
<version>3.0.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--mail邮件发送pom支持-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!--redis场景启动器-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- redis 连接池 -->
|
||||||
|
<!--新版本连接池lettuce-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
Loading…
Reference in New Issue
Block a user