发送邮箱验证码-基础设置
This commit is contained in:
parent
bbfe532bca
commit
1b7bf095dc
@ -2,17 +2,19 @@
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="true" />
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="YuNan-demo" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||
<module name="YuNan-cmd" options="" />
|
||||
<module name="YuNan-demo" options="" />
|
||||
<module name="YuNan-demo" options="-parameters" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -1,9 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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/resources" 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="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
@ -9,7 +9,7 @@
|
||||
</list>
|
||||
</option>
|
||||
</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" />
|
||||
</component>
|
||||
</project>
|
@ -10,14 +10,21 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>YuNan-demo</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- 添加特有的依赖 -->
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
@ -1,13 +1,31 @@
|
||||
package com.yunan;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootApplication(scanBasePackages = "com.yunan")
|
||||
public class YuNanDemoApplication {
|
||||
|
||||
public static void main(String[] 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>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<!-- 子模块列表 -->
|
||||
<module>YuNan-demo</module>
|
||||
</modules>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.3.4</version>
|
||||
<version>2.7.10</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
|
||||
|
||||
<!-- 版本控制 -->
|
||||
<!-- 版本控制 -->
|
||||
<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>
|
||||
|
||||
<!-- 依赖导入 -->
|
||||
<!-- 依赖导入 -->
|
||||
<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>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
@ -35,6 +70,47 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</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>
|
||||
|
||||
<build>
|
||||
|
Loading…
Reference in New Issue
Block a user