sync: 同步 RuoYi-Vue-Plus(v4.4.0) 更新
重大更新
[重大更新] 优化支持 oss 私有库功能(数据库字段改动) #cd9c3c3f
[重大更新] 连接池由 druid 修改为 hikari 更新相关配置(原因可看文档) #1f42bd3d
[重大更新] 移除 tlog(不支持UI界面 使用的人太少)建议使用 skywalking
[重大更新] 增加 skywalking 集成 默认注释不开启(使用看文档)
依赖升级
update springboot 2.7.5 => 2.7.6
update springboot-admin 2.7.6 => 2.7.7
update satoken 1.31.0 => 1.33.0
update spring-doc 1.6.12 => 1.6.13
update easyexcel 3.1.1 => 3.1.3
update hutool 5.8.8 => 5.8.10
update redisson 3.17.7 => 3.18.0
update lock4j 2.2.2 => 2.2.3
update s3-adk 1.12.324 => 1.12.349
update mysql-docker 8.0.29 => 8.0.31 功能更新
update 优化 oss 云厂商增加 华为obs关键字
update 优化 冗余的三元表达式
update 优化 重置时取消部门选中
update 优化 新增返回警告消息提示
update 优化 hikari 参数顺序 最常用的放上面 删除无用 druid 监控页面
update 优化 p6spy 排除健康检查 sql 执行记录
update 优化 Dockerfile 创建目录命令
update 优化 将空‘catch’块形参重命名为‘ignored’
update 优化 使用本地缓存优化 excel 导出 数据量大字典转换慢问题
update 优化 字典转换实现去除字符串查找拼接优化效率
update 优化 减小腾讯短信引入jar包的体积
update 消除Vue3控制台出现的警告信息
update 忽略不必要的属性数据返回
update 替换 mysql-jdbc 最新坐标
新增功能
add 新增 junit5 单元测试案例 #6e8ef308
add 增加 sys_oss_config access_policy 桶权限类型字段
add 增加 4.3-4.4 更新 sql 文件
add 新增 字典数据映射注解 #da94e898
add 增加 RedisUtils 获取缓存Map的key列表
问题修复
fix 修复 上传png透明图片 生成头像透明部分变成黑色
fix 修复 sqlserver sql文件 重复主键数据问题
fix 修复 sqlserver 特定情况下报 ssl 证书问题 默认关闭 ssl 认证
fix 修复 table中更多按钮切换主题色未生效修复问题
fix 修复 菜单激活无法修改其填充颜色去除某些svg图标的fill="#bfbfbf"属性
fix 修复 使用缓冲流 导致上传异常问题
fix 修复 过滤器链使用IoUtil.read方法导致request流关闭
fix 修复 Log注解GET请求记录不到参数问题
fix 修复 某些特性的环境生成代码变乱码TXT文件问题
fix 修复 开启TopNav没有子菜单隐藏侧边栏
fix 修复 回显数据字典数组异常问题
移除功能
remove 移除过期 Anonymous 注解与其实现代码
remove 移除 tlog(不支持UI界面 使用的人太少) 建议使用 skywalking
This commit is contained in:
@@ -21,7 +21,6 @@ import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -92,7 +91,6 @@ public class LogAspect {
|
||||
SpringUtils.getBean(OperLogService.class).recordOper(operLog);
|
||||
} catch (Exception exp) {
|
||||
// 记录本地异常日志
|
||||
log.error("==前置通知异常==");
|
||||
log.error("异常信息:{}", exp.getMessage());
|
||||
exp.printStackTrace();
|
||||
}
|
||||
@@ -135,8 +133,9 @@ public class LogAspect {
|
||||
String params = argsArrayToString(joinPoint.getArgs());
|
||||
operLog.setOperParam(StringUtils.substring(params, 0, 2000));
|
||||
} else {
|
||||
Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||
operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
|
||||
Map<String, String> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
|
||||
MapUtil.removeAny(paramsMap, EXCLUDE_PROPERTIES);
|
||||
operLog.setOperParam(StringUtils.substring(JsonUtils.toJsonString(paramsMap), 0, 2000));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* druid 配置多数据源
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class DruidConfig {
|
||||
|
||||
/**
|
||||
* 去除监控页面底部的广告
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
|
||||
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) {
|
||||
// 获取web监控页面的参数
|
||||
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
|
||||
// 提取common.js的配置路径
|
||||
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
|
||||
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
|
||||
final String filePath = "support/http/resources/js/common.js";
|
||||
// 创建filter进行过滤
|
||||
Filter filter = new Filter() {
|
||||
@Override
|
||||
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
chain.doFilter(request, response);
|
||||
// 重置缓冲区,响应头不会被重置
|
||||
// response.resetBuffer();
|
||||
// 获取common.js
|
||||
String text = Utils.readFromResource(filePath);
|
||||
// 正则替换banner, 除去底部的广告信息
|
||||
text = text.replaceAll("<a.*?banner\"></a><br/>", "");
|
||||
text = text.replaceAll("powered.*?shrek.wang</a>", "");
|
||||
response.getWriter().write(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
};
|
||||
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
|
||||
registrationBean.setFilter(filter);
|
||||
registrationBean.addUrlPatterns(commonJsPattern);
|
||||
return registrationBean;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
import com.ruoyi.framework.interceptor.PlusWebInvokeTimeInterceptor;
|
||||
import com.yomahub.tlog.web.interceptor.TLogWebInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
@@ -21,8 +20,6 @@ public class ResourcesConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 全局链路跟踪拦截器
|
||||
registry.addInterceptor(new TLogWebInterceptor());
|
||||
// 全局访问性能拦截
|
||||
registry.addInterceptor(new PlusWebInvokeTimeInterceptor());
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpLogic;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import com.ruoyi.framework.config.properties.ExcludeUrlProperties;
|
||||
import com.ruoyi.framework.config.properties.SecurityProperties;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -34,14 +32,10 @@ public class SaTokenConfig implements WebMvcConfigurer {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
// 注册路由拦截器,自定义验证规则
|
||||
registry.addInterceptor(new SaInterceptor(handler -> {
|
||||
// 自定义注解 @Anonymous 匿名访问配置,后续版本将删除
|
||||
ExcludeUrlProperties excludeUrlProperties = SpringUtils.getBean(ExcludeUrlProperties.class);
|
||||
// 登录验证 -- 排除多个路径
|
||||
SaRouter
|
||||
// 获取所有的
|
||||
.match("/**")
|
||||
// 排除下不需要拦截的(每次匹配)
|
||||
.notMatch(excludeUrlProperties.getExcludes())
|
||||
// 对未排除的路径进行检查
|
||||
.check(() -> {
|
||||
// 检查是否登录 是否有token
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
import com.yomahub.tlog.springboot.TLogWebAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 整合 TLog 框架配置
|
||||
*
|
||||
* @author Lion Li
|
||||
* @since 3.3.0
|
||||
*/
|
||||
@Configuration
|
||||
// 排除 web 自动配置 自定义实现
|
||||
@EnableAutoConfiguration(exclude = TLogWebAutoConfiguration.class)
|
||||
public class TLogConfig {
|
||||
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package com.ruoyi.framework.config.properties;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import lombok.Getter;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.util.pattern.PathPattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 设置注解允许匿名访问的url
|
||||
*
|
||||
* @author Lion Li
|
||||
* @deprecated 将在后续版本使用Sa-Token注解 {@link SaIgnore} 代替,
|
||||
* 底层过滤方法详见 {@link SaInterceptor#preHandle(HttpServletRequest, HttpServletResponse, Object)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Lazy
|
||||
@Component
|
||||
public class ExcludeUrlProperties implements InitializingBean {
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
|
||||
|
||||
@Getter
|
||||
private final List<String> excludes = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
String asterisk = "*";
|
||||
RequestMappingHandlerMapping mapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
|
||||
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
|
||||
|
||||
map.keySet().forEach(info -> {
|
||||
HandlerMethod handlerMethod = map.get(info);
|
||||
|
||||
// 获取方法上边的注解 替代path variable 为 *
|
||||
Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
|
||||
Optional.ofNullable(method).ifPresent(anonymous -> {
|
||||
Set<PathPattern> patterns = info.getPathPatternsCondition().getPatterns();
|
||||
patterns.forEach(url -> {
|
||||
excludes.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, asterisk));
|
||||
});
|
||||
});
|
||||
|
||||
// 获取类上边的注解, 替代path variable 为 *
|
||||
Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
|
||||
Optional.ofNullable(controller).ifPresent(anonymous -> {
|
||||
Set<PathPattern> patterns = info.getPathPatternsCondition().getPatterns();
|
||||
patterns.forEach(url -> {
|
||||
excludes.add(ReUtil.replaceAll(url.getPatternString(), PATTERN, asterisk));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -102,6 +102,20 @@ public class UserActionListener implements SaTokenListener {
|
||||
public void doUntieDisable(String loginType, Object loginId, String service) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次打开二级认证时触发
|
||||
*/
|
||||
@Override
|
||||
public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次创建Session时触发
|
||||
*/
|
||||
@Override
|
||||
public void doCloseSafe(String loginType, String tokenValue, String service) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 每次创建Session时触发
|
||||
*/
|
||||
|
||||
@@ -105,7 +105,7 @@ public class GlobalExceptionHandler {
|
||||
public R<Void> handleServiceException(ServiceException e, HttpServletRequest request) {
|
||||
log.error(e.getMessage(), e);
|
||||
Integer code = e.getCode();
|
||||
return ObjectUtil.isNotNull(code) ? R.fail(code.intValue(), e.getMessage()) : R.fail(e.getMessage());
|
||||
return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user