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:
konbai
2022-04-16 00:06:21 +08:00
parent cf30d29f9b
commit 9295c85421
50 changed files with 1268 additions and 269 deletions

View File

@@ -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;
}

View File

@@ -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")

View File

@@ -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);
}
/**

View File

@@ -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<>();
}

View File

@@ -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);
}
/**
* 业务异常
*/