feat: 新增验证码和代码优化重构
This commit is contained in:
24
pom.xml
24
pom.xml
@@ -21,11 +21,11 @@
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
|
||||
<hutool.version>5.8.12</hutool.version>
|
||||
<hutool.version>5.8.15</hutool.version>
|
||||
|
||||
<mysql.version>8.0.19</mysql.version>
|
||||
<mysql.version>8.0.28</mysql.version>
|
||||
<druid.version>1.2.4</druid.version>
|
||||
<mybatis-plus.version>3.5.3</mybatis-plus.version>
|
||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
||||
|
||||
<knife4j.version>4.0.0</knife4j.version>
|
||||
|
||||
@@ -37,8 +37,12 @@
|
||||
|
||||
<easyexcel.version>3.2.1</easyexcel.version>
|
||||
|
||||
<minio.version>8.3.7</minio.version>
|
||||
<!-- 分布式文件存储 -->
|
||||
<minio.version>8.5.2</minio.version>
|
||||
<okhttp3.version>4.8.1</okhttp3.version>
|
||||
|
||||
<!-- 验证码 -->
|
||||
<easy-captcha.version>1.6.2</easy-captcha.version>
|
||||
</properties>
|
||||
|
||||
|
||||
@@ -161,6 +165,18 @@
|
||||
<version>${minio.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.whvcse</groupId>
|
||||
<artifactId>easy-captcha</artifactId>
|
||||
<version>${easy-captcha.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.openjdk.nashorn</groupId>
|
||||
<artifactId>nashorn-core</artifactId>
|
||||
<version>15.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.youlai.system.common.constant;
|
||||
|
||||
/**
|
||||
* Redis 缓存常量
|
||||
*
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
public interface CacheConstants {
|
||||
|
||||
/**
|
||||
* 验证码缓存前缀
|
||||
*/
|
||||
String VERIFY_CODE_CACHE_PREFIX = "AUTH:VERIFY_CODE:";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.youlai.system.common.constant;
|
||||
|
||||
/**
|
||||
* Excel 常量
|
||||
*
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
public interface ExcelConstants {
|
||||
|
||||
/**
|
||||
* Excel 模板目录
|
||||
*/
|
||||
String EXCEL_TEMPLATE_DIR="excel-templates";
|
||||
|
||||
}
|
||||
@@ -23,4 +23,6 @@ public interface SystemConstants {
|
||||
* 超级管理员角色编码
|
||||
*/
|
||||
String ROOT_ROLE_CODE = "ROOT";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import lombok.NoArgsConstructor;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 响应码枚举
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2020-06-23
|
||||
**/
|
||||
@@ -25,6 +27,10 @@ public enum ResultCode implements IResultCode, Serializable {
|
||||
USERNAME_OR_PASSWORD_ERROR("A0210", "用户名或密码错误"),
|
||||
PASSWORD_ENTER_EXCEED_LIMIT("A0211", "用户输入密码次数超限"),
|
||||
CLIENT_AUTHENTICATION_FAILED("A0212", "客户端认证失败"),
|
||||
|
||||
VERIFY_CODE_TIMEOUT("A0213", "验证码已过期"),
|
||||
VERIFY_CODE_ERROR("A0214", "验证码错误"),
|
||||
|
||||
TOKEN_INVALID("A0230", "token无效或已过期"),
|
||||
TOKEN_ACCESS_FORBIDDEN("A0231", "token已被禁止访问"),
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.youlai.system.controller;
|
||||
|
||||
import com.youlai.system.common.result.Result;
|
||||
import com.youlai.system.framework.easycaptcha.service.EasyCaptchaService;
|
||||
import com.youlai.system.pojo.dto.CaptchaResult;
|
||||
import com.youlai.system.pojo.dto.LoginResult;
|
||||
import com.youlai.system.framework.security.JwtTokenManager;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -14,13 +16,14 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Tag(name = "01.认证管理")
|
||||
@Tag(name = "01.认证中心")
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/auth")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthController {
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final JwtTokenManager jwtTokenManager;
|
||||
private final EasyCaptchaService easyCaptchaService;
|
||||
|
||||
@Operation(summary = "登录")
|
||||
@PostMapping("/login")
|
||||
@@ -50,4 +53,11 @@ public class AuthController {
|
||||
return Result.success("注销成功");
|
||||
}
|
||||
|
||||
@Operation(summary = "获取验证码")
|
||||
@GetMapping("/captcha")
|
||||
public Result getCaptcha() {
|
||||
CaptchaResult captcha = easyCaptchaService.getCaptcha();
|
||||
return Result.success(captcha);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class SysDeptController {
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取部门详情", security = {@SecurityRequirement(name = "Authorization")})
|
||||
@Operation(summary = "获取部门表单数据", security = {@SecurityRequirement(name = "Authorization")})
|
||||
@GetMapping("/{deptId}/form")
|
||||
public Result<DeptForm> getDeptForm(
|
||||
@Parameter(description ="部门ID") @PathVariable Long deptId
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.youlai.system.common.constant.ExcelConstants;
|
||||
import com.youlai.system.common.result.PageResult;
|
||||
import com.youlai.system.common.result.Result;
|
||||
import com.youlai.system.common.util.ExcelUtils;
|
||||
@@ -136,7 +137,7 @@ public class SysUserController {
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
||||
|
||||
String fileClassPath = "excel-templates" + File.separator + fileName;
|
||||
String fileClassPath = ExcelConstants.EXCEL_TEMPLATE_DIR + File.separator + fileName;
|
||||
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileClassPath);
|
||||
|
||||
ServletOutputStream outputStream = response.getOutputStream();
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.youlai.system.framework.easycaptcha.config;
|
||||
|
||||
import com.youlai.system.framework.easycaptcha.enums.VerifyCodeTypeEnum;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "easycaptcha")
|
||||
@Configuration
|
||||
@Data
|
||||
public class EasyCaptchaConfig {
|
||||
|
||||
/**
|
||||
* 验证码类型
|
||||
*/
|
||||
private VerifyCodeTypeEnum verifyCodeType = VerifyCodeTypeEnum.ARITHMETIC;
|
||||
|
||||
|
||||
/**
|
||||
* 验证码缓存过期时间(单位:秒)
|
||||
*/
|
||||
private long ttl = 120l;
|
||||
|
||||
/**
|
||||
* 验证码内容长度
|
||||
*/
|
||||
private int length = 4;
|
||||
/**
|
||||
* 验证码宽度
|
||||
*/
|
||||
private int width = 120;
|
||||
/**
|
||||
* 验证码高度
|
||||
*/
|
||||
private int height = 36;
|
||||
|
||||
|
||||
/**
|
||||
* 验证码字体
|
||||
*/
|
||||
private String fontName = "Verdana";
|
||||
|
||||
/**
|
||||
* 字体风格
|
||||
*/
|
||||
private Integer fontStyle = Font.PLAIN;
|
||||
|
||||
/**
|
||||
* 字体大小
|
||||
*/
|
||||
private int fontSize = 20;
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.youlai.system.framework.easycaptcha.enums;
|
||||
|
||||
/**
|
||||
* EasyCaptcha 验证码类型枚举
|
||||
*
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
public enum VerifyCodeTypeEnum {
|
||||
|
||||
/**
|
||||
* 算数
|
||||
*/
|
||||
ARITHMETIC,
|
||||
/**
|
||||
* 中文
|
||||
*/
|
||||
CHINESE,
|
||||
/**
|
||||
* 中文闪图
|
||||
*/
|
||||
CHINESE_GIF,
|
||||
/**
|
||||
* 闪图
|
||||
*/
|
||||
GIF,
|
||||
SPEC
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.youlai.system.framework.easycaptcha.producer;
|
||||
|
||||
import com.wf.captcha.*;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import com.youlai.system.framework.easycaptcha.config.EasyCaptchaConfig;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* 验证码生成器
|
||||
*
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class EasyCaptchaProducer {
|
||||
private final EasyCaptchaConfig easyCaptchaConfig;
|
||||
|
||||
public Captcha getCaptcha() {
|
||||
Captcha captcha;
|
||||
int width = easyCaptchaConfig.getWidth();
|
||||
int height = easyCaptchaConfig.getHeight();
|
||||
int length = easyCaptchaConfig.getLength();
|
||||
String fontName = easyCaptchaConfig.getFontName();
|
||||
|
||||
switch (easyCaptchaConfig.getVerifyCodeType()) {
|
||||
case ARITHMETIC:
|
||||
captcha = new ArithmeticCaptcha(width, height);
|
||||
//固定设置为两位,图片为算数运算表达式
|
||||
captcha.setLen(2);
|
||||
break;
|
||||
case CHINESE:
|
||||
captcha = new ChineseCaptcha(width, height);
|
||||
captcha.setLen(length);
|
||||
break;
|
||||
case CHINESE_GIF:
|
||||
captcha = new ChineseGifCaptcha(width, height);
|
||||
captcha.setLen(length);
|
||||
break;
|
||||
case GIF:
|
||||
captcha = new GifCaptcha(width, height);//最后一位是位数
|
||||
captcha.setLen(length);
|
||||
break;
|
||||
case SPEC:
|
||||
captcha = new SpecCaptcha(width, height);
|
||||
captcha.setLen(length);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("验证码配置信息错误!正确配置查看 VerifyCodeTypeEnum ");
|
||||
}
|
||||
captcha.setFont(new Font(fontName, easyCaptchaConfig.getFontStyle(), easyCaptchaConfig.getFontSize()));
|
||||
return captcha;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.youlai.system.framework.easycaptcha.service;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.wf.captcha.base.Captcha;
|
||||
import com.youlai.system.common.constant.CacheConstants;
|
||||
import com.youlai.system.framework.easycaptcha.config.EasyCaptchaConfig;
|
||||
import com.youlai.system.framework.easycaptcha.producer.EasyCaptchaProducer;
|
||||
import com.youlai.system.pojo.dto.CaptchaResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* EasyCaptcha 业务类
|
||||
*
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class EasyCaptchaService {
|
||||
|
||||
private final EasyCaptchaProducer easyCaptchaProducer;
|
||||
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
private final EasyCaptchaConfig easyCaptchaConfig;
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CaptchaResult getCaptcha() {
|
||||
// 获取验证码
|
||||
Captcha captcha = easyCaptchaProducer.getCaptcha();
|
||||
String captchaText = captcha.text(); // 验证码文本
|
||||
String captchaBase64 = captcha.toBase64(); // 验证码图片Base64字符串
|
||||
|
||||
// 验证码文本缓存至Redis,用于登录比较
|
||||
String verifyCodeKey = IdUtil.fastSimpleUUID();
|
||||
redisTemplate.opsForValue().set(CacheConstants.VERIFY_CODE_CACHE_PREFIX + verifyCodeKey, captchaText,
|
||||
easyCaptchaConfig.getTtl(), TimeUnit.SECONDS);
|
||||
|
||||
CaptchaResult captchaResult = CaptchaResult.builder()
|
||||
.verifyCodeKey(verifyCodeKey)
|
||||
.verifyCodeBase64(captchaBase64)
|
||||
.build();
|
||||
return captchaResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.youlai.system.config;
|
||||
package com.youlai.system.framework.security.config;
|
||||
|
||||
import com.youlai.system.framework.security.filter.JwtAuthenticationFilter;
|
||||
import com.youlai.system.framework.security.exception.MyAccessDeniedHandler;
|
||||
import com.youlai.system.framework.security.exception.MyAuthenticationEntryPoint;
|
||||
import com.youlai.system.framework.security.JwtTokenManager;
|
||||
import com.youlai.system.framework.security.filter.VerifyCodeFilter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -44,6 +45,9 @@ public class SecurityConfig {
|
||||
.authorizeHttpRequests()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin()
|
||||
.loginProcessingUrl("/api/v1/auth/login").permitAll()
|
||||
.and()
|
||||
.exceptionHandling()
|
||||
.authenticationEntryPoint(myAuthenticationEntryPoint)
|
||||
.accessDeniedHandler(myAccessDeniedHandler)
|
||||
@@ -52,6 +56,9 @@ public class SecurityConfig {
|
||||
// disable cache
|
||||
http.headers().cacheControl();
|
||||
|
||||
// 验证码校验过滤器
|
||||
http.addFilterAt(new VerifyCodeFilter(),UsernamePasswordAuthenticationFilter.class);
|
||||
// JWT 校验过滤器
|
||||
http.addFilterBefore(new JwtAuthenticationFilter(jwtTokenManager), UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
return http.build();
|
||||
@@ -61,7 +68,7 @@ public class SecurityConfig {
|
||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
||||
return (web) -> web.ignoring()
|
||||
.requestMatchers(
|
||||
"/api/v1/auth/login",
|
||||
"/api/v1/auth/captcha",
|
||||
"/webjars/**",
|
||||
"/doc.html",
|
||||
"/swagger-resources/**",
|
||||
@@ -2,27 +2,29 @@ package com.youlai.system.framework.security.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.youlai.system.common.result.ResultCode;
|
||||
import com.youlai.system.framework.security.JwtTokenManager;
|
||||
import com.youlai.system.common.util.ResponseUtils;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import com.youlai.system.framework.security.JwtTokenManager;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* JWT token校验拦截器
|
||||
* JWT 校验过滤器
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2022/10/1
|
||||
*/
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/v1/auth/login", "POST");
|
||||
|
||||
private static final String TOKEN_PREFIX = "Bearer ";
|
||||
|
||||
private final JwtTokenManager tokenManager;
|
||||
@@ -32,15 +34,17 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
|
||||
if(HttpMethod.OPTIONS.matches(request.getMethod()) ){
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
if (DEFAULT_ANT_PATH_REQUEST_MATCHER.matches(request)) {
|
||||
// 非登录接口放行
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
String jwt = resolveToken(request);
|
||||
if (StrUtil.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
try {
|
||||
// 验证token
|
||||
// 验证JWT
|
||||
this.tokenManager.validateToken(jwt);
|
||||
|
||||
// JWT验证有效获取Authentication存入Security上下文
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.youlai.system.framework.security.filter;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.youlai.system.common.constant.CacheConstants;
|
||||
import com.youlai.system.common.result.ResultCode;
|
||||
import com.youlai.system.common.util.ResponseUtils;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 验证码校验过滤器
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2022/10/1
|
||||
*/
|
||||
public class VerifyCodeFilter extends OncePerRequestFilter {
|
||||
|
||||
/**
|
||||
* 拦截路径
|
||||
*/
|
||||
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/v1/auth/login", "POST");
|
||||
public static final String VERIFY_CODE = "verifyCode";
|
||||
public static final String VERIFY_CODE_KEY = "verifyCodeKey";
|
||||
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
public VerifyCodeFilter() {
|
||||
this.redisTemplate = SpringUtil.getBean(StringRedisTemplate.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
|
||||
if (!DEFAULT_ANT_PATH_REQUEST_MATCHER.matches(request)) {
|
||||
// 非登录接口放行
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
// 请求中的验证码
|
||||
String requestVerifyCode = request.getParameter(VERIFY_CODE);
|
||||
|
||||
// 缓存中的验证码
|
||||
String verifyCodeKey = request.getParameter(VERIFY_CODE_KEY);
|
||||
Object cacheVerifyCode = redisTemplate.opsForValue().get(CacheConstants.VERIFY_CODE_CACHE_PREFIX + verifyCodeKey);
|
||||
if (cacheVerifyCode == null) {
|
||||
ResponseUtils.writeErrMsg(response, ResultCode.VERIFY_CODE_TIMEOUT);
|
||||
} else {
|
||||
// 验证码比对
|
||||
if (StrUtil.equals(requestVerifyCode, Convert.toStr(cacheVerifyCode))) {
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
ResponseUtils.writeErrMsg(response, ResultCode.VERIFY_CODE_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
24
src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java
Normal file
24
src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.youlai.system.pojo.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 验证码响应对象
|
||||
*
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
@Schema(description ="验证码响应对象")
|
||||
@Builder
|
||||
@Data
|
||||
public class CaptchaResult {
|
||||
|
||||
@Schema(description = "验证码缓存key")
|
||||
private String verifyCodeKey;
|
||||
|
||||
@Schema(description = "验证码图片Base64字符串")
|
||||
private String verifyCodeBase64;
|
||||
|
||||
}
|
||||
@@ -36,6 +36,7 @@ mybatis-plus:
|
||||
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
|
||||
# 认证配置
|
||||
auth:
|
||||
token:
|
||||
@@ -62,3 +63,8 @@ springdoc:
|
||||
api-docs:
|
||||
enabled: true
|
||||
|
||||
# 验证码配置
|
||||
easycaptcha:
|
||||
verifyCodeType: arithmetic
|
||||
enable: true
|
||||
ttl: 120
|
||||
@@ -20,8 +20,8 @@
|
||||
FROM
|
||||
sys_user u
|
||||
LEFT JOIN sys_dept d ON u.dept_id = d.id
|
||||
LEFT JOIN sys_user_role sur ON u.id = sur.user_id
|
||||
LEFT JOIN sys_role r ON sur.role_id = r.id
|
||||
LEFT JOIN sys_user_role ur ON u.id = ur.user_id
|
||||
LEFT JOIN sys_role r ON ur.role_id = r.id
|
||||
<where>
|
||||
u.deleted = 0 AND u.username != 'root'
|
||||
<if test='queryParams.keywords!=null and queryParams.keywords.trim() neq ""'>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.youlai.system;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import com.youlai.system.pojo.entity.SysUser;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -7,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Redis 单元测试
|
||||
*
|
||||
@@ -25,7 +29,6 @@ public class RedisTests {
|
||||
*/
|
||||
@Test
|
||||
public void testRedisSerializer() {
|
||||
|
||||
SysUser user = new SysUser();
|
||||
user.setId(1l);
|
||||
user.setNickname("张三");
|
||||
|
||||
Reference in New Issue
Block a user