diff --git a/pom.xml b/pom.xml
index 5da18bbc..67fad1be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,11 +21,11 @@
17
17
- 5.8.12
+ 5.8.15
- 8.0.19
+ 8.0.28
1.2.4
- 3.5.3
+ 3.5.3.1
4.0.0
@@ -37,8 +37,12 @@
3.2.1
- 8.3.7
+
+ 8.5.2
4.8.1
+
+
+ 1.6.2
@@ -161,6 +165,18 @@
${minio.version}
+
+ com.github.whvcse
+ easy-captcha
+ ${easy-captcha.version}
+
+
+
+ org.openjdk.nashorn
+ nashorn-core
+ 15.4
+
+
diff --git a/src/main/java/com/youlai/system/common/constant/CacheConstants.java b/src/main/java/com/youlai/system/common/constant/CacheConstants.java
new file mode 100644
index 00000000..17708e09
--- /dev/null
+++ b/src/main/java/com/youlai/system/common/constant/CacheConstants.java
@@ -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:";
+
+}
diff --git a/src/main/java/com/youlai/system/common/constant/ExcelConstants.java b/src/main/java/com/youlai/system/common/constant/ExcelConstants.java
new file mode 100644
index 00000000..b0fbe9a8
--- /dev/null
+++ b/src/main/java/com/youlai/system/common/constant/ExcelConstants.java
@@ -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";
+
+}
diff --git a/src/main/java/com/youlai/system/common/constant/SystemConstants.java b/src/main/java/com/youlai/system/common/constant/SystemConstants.java
index 7cc2fcca..d6e823d2 100644
--- a/src/main/java/com/youlai/system/common/constant/SystemConstants.java
+++ b/src/main/java/com/youlai/system/common/constant/SystemConstants.java
@@ -23,4 +23,6 @@ public interface SystemConstants {
* 超级管理员角色编码
*/
String ROOT_ROLE_CODE = "ROOT";
+
+
}
diff --git a/src/main/java/com/youlai/system/common/result/ResultCode.java b/src/main/java/com/youlai/system/common/result/ResultCode.java
index a90492ee..1fe230d7 100644
--- a/src/main/java/com/youlai/system/common/result/ResultCode.java
+++ b/src/main/java/com/youlai/system/common/result/ResultCode.java
@@ -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已被禁止访问"),
diff --git a/src/main/java/com/youlai/system/controller/AuthController.java b/src/main/java/com/youlai/system/controller/AuthController.java
index 62e41a2f..15fc016f 100644
--- a/src/main/java/com/youlai/system/controller/AuthController.java
+++ b/src/main/java/com/youlai/system/controller/AuthController.java
@@ -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);
+ }
+
}
diff --git a/src/main/java/com/youlai/system/controller/SysDeptController.java b/src/main/java/com/youlai/system/controller/SysDeptController.java
index a48e0d08..0aa31443 100644
--- a/src/main/java/com/youlai/system/controller/SysDeptController.java
+++ b/src/main/java/com/youlai/system/controller/SysDeptController.java
@@ -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 getDeptForm(
@Parameter(description ="部门ID") @PathVariable Long deptId
diff --git a/src/main/java/com/youlai/system/controller/SysUserController.java b/src/main/java/com/youlai/system/controller/SysUserController.java
index 566a4b6e..812a0e54 100644
--- a/src/main/java/com/youlai/system/controller/SysUserController.java
+++ b/src/main/java/com/youlai/system/controller/SysUserController.java
@@ -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();
diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/config/EasyCaptchaConfig.java b/src/main/java/com/youlai/system/framework/easycaptcha/config/EasyCaptchaConfig.java
new file mode 100644
index 00000000..04c237c2
--- /dev/null
+++ b/src/main/java/com/youlai/system/framework/easycaptcha/config/EasyCaptchaConfig.java
@@ -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;
+
+
+}
diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/enums/VerifyCodeTypeEnum.java b/src/main/java/com/youlai/system/framework/easycaptcha/enums/VerifyCodeTypeEnum.java
new file mode 100644
index 00000000..e5aa757a
--- /dev/null
+++ b/src/main/java/com/youlai/system/framework/easycaptcha/enums/VerifyCodeTypeEnum.java
@@ -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
+}
diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/producer/EasyCaptchaProducer.java b/src/main/java/com/youlai/system/framework/easycaptcha/producer/EasyCaptchaProducer.java
new file mode 100644
index 00000000..5972f844
--- /dev/null
+++ b/src/main/java/com/youlai/system/framework/easycaptcha/producer/EasyCaptchaProducer.java
@@ -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;
+
+ }
+
+
+}
diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/service/EasyCaptchaService.java b/src/main/java/com/youlai/system/framework/easycaptcha/service/EasyCaptchaService.java
new file mode 100644
index 00000000..79c6b2ff
--- /dev/null
+++ b/src/main/java/com/youlai/system/framework/easycaptcha/service/EasyCaptchaService.java
@@ -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;
+ }
+
+}
diff --git a/src/main/java/com/youlai/system/config/SecurityConfig.java b/src/main/java/com/youlai/system/framework/security/config/SecurityConfig.java
similarity index 88%
rename from src/main/java/com/youlai/system/config/SecurityConfig.java
rename to src/main/java/com/youlai/system/framework/security/config/SecurityConfig.java
index 23d41991..de91b1fc 100644
--- a/src/main/java/com/youlai/system/config/SecurityConfig.java
+++ b/src/main/java/com/youlai/system/framework/security/config/SecurityConfig.java
@@ -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/**",
diff --git a/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java b/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java
index 925b845a..9852ecd0 100644
--- a/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java
+++ b/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java
@@ -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上下文
diff --git a/src/main/java/com/youlai/system/framework/security/filter/VerifyCodeFilter.java b/src/main/java/com/youlai/system/framework/security/filter/VerifyCodeFilter.java
new file mode 100644
index 00000000..e4434f68
--- /dev/null
+++ b/src/main/java/com/youlai/system/framework/security/filter/VerifyCodeFilter.java
@@ -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);
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java b/src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java
new file mode 100644
index 00000000..f5c471d3
--- /dev/null
+++ b/src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java
@@ -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;
+
+}
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index 3b542f82..31f4c37f 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -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
\ No newline at end of file
diff --git a/src/main/resources/mapper/SysUserMapper.xml b/src/main/resources/mapper/SysUserMapper.xml
index 2f8d41fe..425a0b0e 100644
--- a/src/main/resources/mapper/SysUserMapper.xml
+++ b/src/main/resources/mapper/SysUserMapper.xml
@@ -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
u.deleted = 0 AND u.username != 'root'
diff --git a/src/test/java/com/youlai/system/RedisTests.java b/src/test/java/com/youlai/system/RedisTests.java
index 1b6bde42..b9cefd2b 100644
--- a/src/test/java/com/youlai/system/RedisTests.java
+++ b/src/test/java/com/youlai/system/RedisTests.java
@@ -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("张三");