sync -- 同步 RuoYi-Vue-Plus 更新。
优化 logback 日志 异步输出 增加 短信登录 与 小程序登录 示例 修复 用户绑定角色 与 角色绑定用户 异常 编写错误 update springboot 2.6.4 => 2.6.5 update springboot-admin 2.6.2 => 2.6.3 update hutool 5.7.21 => 5.7.22 update springboot-admin 2.6.3 => 2.6.5 update dynamic-datasource 3.5.0 => 3.5.1 update redisson 3.16.8 => 3.17.0 update springboot 2.6.5 => 2.6.6 修复 CVE-2022-22965 漏洞 更名 SaInterfaceImpl 为 SaPermissionImpl 完善相关注释 增加 Mybatis 全局异常处理 开启多数据源切换 严格模式 找不到数据源报错
This commit is contained in:
@@ -18,10 +18,10 @@ import java.awt.*;
|
||||
@Configuration
|
||||
public class CaptchaConfig {
|
||||
|
||||
private final int width = 160;
|
||||
private final int height = 60;
|
||||
private final Color background = Color.PINK;
|
||||
private final Font font = new Font("Arial", Font.BOLD, 48);
|
||||
private static final int WIDTH = 160;
|
||||
private static final int HEIGHT = 60;
|
||||
private static final Color BACKGROUND = Color.PINK;
|
||||
private static final Font FONT = new Font("Arial", Font.BOLD, 48);
|
||||
|
||||
/**
|
||||
* 圆圈干扰验证码
|
||||
@@ -29,9 +29,9 @@ public class CaptchaConfig {
|
||||
@Lazy
|
||||
@Bean
|
||||
public CircleCaptcha circleCaptcha() {
|
||||
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(width, height);
|
||||
captcha.setBackground(background);
|
||||
captcha.setFont(font);
|
||||
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(WIDTH, HEIGHT);
|
||||
captcha.setBackground(BACKGROUND);
|
||||
captcha.setFont(FONT);
|
||||
return captcha;
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ public class CaptchaConfig {
|
||||
@Lazy
|
||||
@Bean
|
||||
public LineCaptcha lineCaptcha() {
|
||||
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(width, height);
|
||||
captcha.setBackground(background);
|
||||
captcha.setFont(font);
|
||||
LineCaptcha captcha = CaptchaUtil.createLineCaptcha(WIDTH, HEIGHT);
|
||||
captcha.setBackground(BACKGROUND);
|
||||
captcha.setFont(FONT);
|
||||
return captcha;
|
||||
}
|
||||
|
||||
@@ -53,9 +53,9 @@ public class CaptchaConfig {
|
||||
@Lazy
|
||||
@Bean
|
||||
public ShearCaptcha shearCaptcha() {
|
||||
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(width, height);
|
||||
captcha.setBackground(background);
|
||||
captcha.setFont(font);
|
||||
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(WIDTH, HEIGHT);
|
||||
captcha.setBackground(BACKGROUND);
|
||||
captcha.setFont(FONT);
|
||||
return captcha;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import cn.dev33.satoken.interceptor.SaRouteInterceptor;
|
||||
import cn.dev33.satoken.jwt.StpLogicJwtForStyle;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.framework.config.properties.SecurityProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -43,15 +43,17 @@ public class SaTokenConfig implements WebMvcConfigurer {
|
||||
.match("/**")
|
||||
// 排除下不需要拦截的
|
||||
.notMatch(securityProperties.getExcludes())
|
||||
// 对未排除的路径进行检查
|
||||
.check(() -> {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
if (ObjectUtil.isNotNull(userId)) {
|
||||
// 有效率影响 用于临时测试
|
||||
// if (log.isDebugEnabled()) {
|
||||
// log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
|
||||
// log.debug("临时有效时间: {}", StpUtil.getTokenActivityTimeout());
|
||||
// }
|
||||
}
|
||||
// 检查是否登录 是否有token
|
||||
StpUtil.checkLogin();
|
||||
|
||||
// 有效率影响 用于临时测试
|
||||
// if (log.isDebugEnabled()) {
|
||||
// log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
|
||||
// log.debug("临时有效时间: {}", StpUtil.getTokenActivityTimeout());
|
||||
// }
|
||||
|
||||
});
|
||||
}) {
|
||||
@SuppressWarnings("all")
|
||||
|
||||
@@ -53,7 +53,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
dto.setUserName(user.getUsername());
|
||||
dto.setDeptName(user.getDeptName());
|
||||
RedisUtils.setCacheObject(Constants.ONLINE_TOKEN_KEY + tokenValue, dto, tokenConfig.getTimeout(), TimeUnit.SECONDS);
|
||||
log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
|
||||
} else if (userType == UserType.APP_USER) {
|
||||
// app端 自行根据业务编写
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
@Override
|
||||
public void doLogout(String loginType, Object loginId, String tokenValue) {
|
||||
RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue);
|
||||
log.info("user doLogout, useId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,7 +74,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
@Override
|
||||
public void doKickout(String loginType, Object loginId, String tokenValue) {
|
||||
RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue);
|
||||
log.info("user doLogoutByLoginId, useId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("user doLogoutByLoginId, userId:{}, token:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +83,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
@Override
|
||||
public void doReplaced(String loginType, Object loginId, String tokenValue) {
|
||||
RedisUtils.deleteObject(Constants.ONLINE_TOKEN_KEY + tokenValue);
|
||||
log.info("user doReplaced, useId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,9 +9,17 @@ import org.springframework.stereotype.Component;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* sa-token 权限管理实现类
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Component
|
||||
public class SaInterfaceImpl implements StpInterface {
|
||||
public class SaPermissionImpl implements StpInterface {
|
||||
|
||||
/**
|
||||
* 获取菜单权限列表
|
||||
*/
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
@@ -19,11 +27,14 @@ public class SaInterfaceImpl implements StpInterface {
|
||||
if (userType == UserType.SYS_USER) {
|
||||
return new ArrayList<>(loginUser.getMenuPermission());
|
||||
} else if (userType == UserType.APP_USER) {
|
||||
// app端权限返回 自行根据业务编写
|
||||
// 其他端 自行根据业务编写
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色权限列表
|
||||
*/
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
@@ -31,7 +42,7 @@ public class SaInterfaceImpl implements StpInterface {
|
||||
if (userType == UserType.SYS_USER) {
|
||||
return new ArrayList<>(loginUser.getRolePermission());
|
||||
} else if (userType == UserType.APP_USER) {
|
||||
// app端权限返回 自行根据业务编写
|
||||
// 其他端 自行根据业务编写
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.common.exception.DemoModeException;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mybatis.spring.MyBatisSystemException;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
@@ -71,6 +73,31 @@ public class GlobalExceptionHandler {
|
||||
return R.fail(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键或UNIQUE索引,数据重复异常
|
||||
*/
|
||||
@ExceptionHandler(DuplicateKeyException.class)
|
||||
public R<Void> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',数据库中已存在记录'{}'", requestURI, e.getMessage());
|
||||
return R.fail("数据库中已存在该记录,请联系管理员确认");
|
||||
}
|
||||
|
||||
/**
|
||||
* Mybatis系统异常 通用处理
|
||||
*/
|
||||
@ExceptionHandler(MyBatisSystemException.class)
|
||||
public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
String message = e.getMessage();
|
||||
if (message.contains("CannotFindDataSourceException")) {
|
||||
log.error("请求地址'{}', 未找到数据源", requestURI);
|
||||
return R.fail("未找到数据源,请联系管理员确认");
|
||||
}
|
||||
log.error("请求地址'{}', Mybatis系统异常", requestURI, e);
|
||||
return R.fail(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user