mirror of
https://gitee.com/dromara/RuoYi-Cloud-Plus.git
synced 2026-10-06 06:52:58 +08:00
!270 发布 2.6.2 版本 依赖升级
* 🦁🦁🦁发布 2.6.2 版本 依赖升级 * update springboot 3.5.14 => 3.5.15 * update 优化 防止工作流保存被xss过滤 * update README.md * add 新增 赞助商 * fix 修复 mvc网关与flux网关 异常行为返回内容不同问题 * fix 修复 多次驳回无法锁定审批人问题 * update 优化 findInSet 方法 增加参数校验防止注入 * Revert "fix 修复 dubbo 元数据实现类 json工具使用错误问题" * fix 修复 dubbo 元数据实现类 json工具使用错误问题 * update 优化 findInSet 方法 增加参数校验防止注入 * fix 修复 gateway设置默认请求头无法覆盖问题 * fix 修复 gateway设置默认请求头无法覆盖问题 * fix 修复 前端输入性CVE漏洞 禁止使用代码生成到本地路径
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-auth" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-auth:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-auth:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-auth/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-gateway" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gateway:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gateway:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-gateway/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-gen" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gen:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-gen:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-gen/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-job" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-job:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-job:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-job/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-monitor" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-monitor:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-monitor/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-nacos" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-nacos:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-nacos:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-nacos/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-resource" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-resource:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-resource:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-resource/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-seata-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-seata-server:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-seata-server:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-seata-server/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-snailjob-server:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-visual/ruoyi-snailjob-server/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-system" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-system:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-system:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-system/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="ruoyi-workflow" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="ruoyi/ruoyi-workflow:2.6.1" />
|
||||
<option name="imageTag" value="ruoyi/ruoyi-workflow:2.6.2" />
|
||||
<option name="buildOnly" value="true" />
|
||||
<option name="sourceFilePath" value="ruoyi-modules/ruoyi-workflow/Dockerfile" />
|
||||
</settings>
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
## 平台简介
|
||||
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://github.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://github.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://gitcode.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus/blob/2.X/LICENSE)
|
||||
<br>
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus)
|
||||
[](https://gitee.com/dromara/RuoYi-Cloud-Plus)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
@@ -33,11 +33,11 @@
|
||||
MaxKey 业界领先单点登录产品 - https://gitee.com/dromara/MaxKey <br>
|
||||
CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow <br>
|
||||
数舵科技 软件定制开发APP小程序等 - https://www.shuduokeji.com/ <br>
|
||||
引迈信息 软件开发平台 - https://www.jnpfsoft.com/index.html?from=plus-doc <br>
|
||||
Mall4J 高质量Java商城系统 - https://www.mall4j.com/cn/?statId=11 <br>
|
||||
aizuda flowlong 工作流 - https://gitee.com/aizuda/flowlong <br>
|
||||
Ruoyi-Plus-Uniapp - https://ruoyi.plus <br>
|
||||
Topiam IAM/IDaaS身份管理平台 - https://www.topiam.cn/ <br>
|
||||
稳定低价的大模型中转站 - https://aicodelink.top/register?aff=pHeG <br>
|
||||
|
||||
[如何成为赞助商 加群联系作者详谈 每日PV2500-3000 IP1700-2500](https://plus-doc.dromara.org/#/common/add_group)
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<description>Dromara RuoYi-Cloud-Plus微服务系统</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.6.1</revision>
|
||||
<revision>2.6.2</revision>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>17</java.version>
|
||||
<spring-boot.version>3.5.14</spring-boot.version>
|
||||
<spring-cloud.version>2025.0.2</spring-cloud.version>
|
||||
<spring-boot.version>3.5.15</spring-boot.version>
|
||||
<spring-cloud.version>2025.0.3</spring-cloud.version>
|
||||
<spring-boot-admin.version>3.5.8</spring-boot-admin.version>
|
||||
<mybatis.version>3.5.19</mybatis.version>
|
||||
<mybatis-plus.version>3.5.16</mybatis-plus.version>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.6.1</revision>
|
||||
<revision>2.6.2</revision>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.6.1</revision>
|
||||
<revision>2.6.2</revision>
|
||||
<spring-cloud-alibaba.version>2025.0.0.0</spring-cloud-alibaba.version>
|
||||
<seata.version>2.6.0</seata.version>
|
||||
<nacos.client.version>2.5.1</nacos.client.version>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<revision>2.6.1</revision>
|
||||
<revision>2.6.2</revision>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
+15
-4
@@ -1,5 +1,6 @@
|
||||
package org.dromara.common.core.utils.sql;
|
||||
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
@@ -7,7 +8,7 @@ import org.dromara.common.core.utils.StringUtils;
|
||||
/**
|
||||
* sql操作工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
* @author Lion Li
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class SqlUtil {
|
||||
@@ -15,7 +16,7 @@ public class SqlUtil {
|
||||
/**
|
||||
* 定义常用的 sql关键字
|
||||
*/
|
||||
public static String SQL_REGEX = "\u000B|and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
|
||||
public static final String SQL_REGEX = "\u000B|%0A|and |extractvalue|updatexml|sleep|information_schema|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
|
||||
|
||||
/**
|
||||
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
|
||||
@@ -46,11 +47,21 @@ public class SqlUtil {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ==================== 核心增强:自动转义单引号 ====================
|
||||
// 不抛异常、不破坏业务、不改变原方法行为、自动防注入
|
||||
if (value.contains("'")) {
|
||||
throw new UtilException("请求参数包含非法字符【'】,已禁止执行");
|
||||
}
|
||||
|
||||
// ==================== 原有逻辑不变 ====================
|
||||
String normalizedValue = value.replaceAll("\\p{Z}|\\s", "");
|
||||
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
|
||||
for (String sqlKeyword : sqlKeywords) {
|
||||
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
|
||||
throw new IllegalArgumentException("参数存在SQL注入风险");
|
||||
if (StringUtils.indexOf(normalizedValue, sqlKeyword) > -1) {
|
||||
throw new UtilException("请求参数包含敏感关键词'" + sqlKeyword + "',可能存在安全风险");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+30
-15
@@ -2,10 +2,12 @@ package org.dromara.common.mybatis.helper;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
||||
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.sql.SqlUtil;
|
||||
import org.dromara.common.mybatis.enums.DataBaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
@@ -14,6 +16,8 @@ import java.sql.DatabaseMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 数据库助手
|
||||
@@ -24,6 +28,7 @@ import java.util.List;
|
||||
public class DataBaseHelper {
|
||||
|
||||
private static final DynamicRoutingDataSource DS = SpringUtils.getBean(DynamicRoutingDataSource.class);
|
||||
private static final Map<String, DataBaseType> DB_TYPE_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 获取当前数据源对应的数据库类型
|
||||
@@ -37,13 +42,17 @@ public class DataBaseHelper {
|
||||
*/
|
||||
public static DataBaseType getDataBaseType() {
|
||||
DataSource dataSource = DS.determineDataSource();
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
DatabaseMetaData metaData = conn.getMetaData();
|
||||
String databaseProductName = metaData.getDatabaseProductName();
|
||||
return DataBaseType.find(databaseProductName);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("获取数据库类型失败", e);
|
||||
}
|
||||
String dsKey = DynamicDataSourceContextHolder.peek();
|
||||
final String key = dsKey != null ? dsKey : "primary";
|
||||
return DB_TYPE_CACHE.computeIfAbsent(key, k -> {
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
DatabaseMetaData metaData = conn.getMetaData();
|
||||
String databaseProductName = metaData.getDatabaseProductName();
|
||||
return DataBaseType.find(databaseProductName);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("获取数据库类型失败", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,13 +64,15 @@ public class DataBaseHelper {
|
||||
*/
|
||||
public static DataBaseType getDataBaseType(String dsName) {
|
||||
DataSource dataSource = DS.getDataSource(dsName);
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
DatabaseMetaData metaData = conn.getMetaData();
|
||||
String databaseProductName = metaData.getDatabaseProductName();
|
||||
return DataBaseType.find(databaseProductName);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("获取数据库类型失败", e);
|
||||
}
|
||||
return DB_TYPE_CACHE.computeIfAbsent(dsName, k -> {
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
DatabaseMetaData metaData = conn.getMetaData();
|
||||
String databaseProductName = metaData.getDatabaseProductName();
|
||||
return DataBaseType.find(databaseProductName);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("获取数据库类型失败", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,6 +90,8 @@ public class DataBaseHelper {
|
||||
*/
|
||||
public static String findInSet(Object var1, String var2) {
|
||||
String var = Convert.toStr(var1);
|
||||
SqlUtil.filterKeyword(var);
|
||||
SqlUtil.filterKeyword(var2);
|
||||
return switch (getDataBaseType()) {
|
||||
// instr(',0,100,101,' , ',100,') <> 0
|
||||
case ORACLE -> "instr(','||%s||',' , ',%s,') <> 0".formatted(var2, var);
|
||||
@@ -92,7 +105,9 @@ public class DataBaseHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前加载的数据库名
|
||||
* 获取当前注册的数据源名称列表。
|
||||
*
|
||||
* @return 数据源名称列表
|
||||
*/
|
||||
public static List<String> getDataSourceNameList() {
|
||||
return new ArrayList<>(DS.getDataSources().keySet());
|
||||
|
||||
+6
@@ -6,7 +6,10 @@ import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.same.SaSameUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
import cn.dev33.satoken.util.SaTokenConsts;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.utils.ServletUtils;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -42,6 +45,9 @@ public class SecurityConfiguration implements WebMvcConfigurer {
|
||||
if (SaManager.getConfig().getCheckSameToken()) {
|
||||
SaSameUtil.checkCurrentRequestToken();
|
||||
}
|
||||
// 对响应体设置默认头 后续代码可以覆盖
|
||||
HttpServletResponse response = ServletUtils.getResponse();
|
||||
response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON);
|
||||
})
|
||||
.setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(HttpStatus.UNAUTHORIZED));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.dromara.gateway.filter;
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.filter.SaServletFilter;
|
||||
import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil;
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
@@ -14,23 +13,19 @@ import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.dromara.gateway.config.properties.IgnoreWhiteProperties;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* [Sa-Token 权限认证] 拦截器配置
|
||||
* [Sa-Token 权限认证] 过滤器配置
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@Configuration
|
||||
public class AuthFilter implements WebMvcConfigurer {
|
||||
public class AuthFilter {
|
||||
|
||||
private final IgnoreWhiteProperties ignoreWhite;
|
||||
|
||||
@@ -38,31 +33,39 @@ public class AuthFilter implements WebMvcConfigurer {
|
||||
this.ignoreWhite = ignoreWhite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new SaInterceptor(handler -> SaRouter.match("/**")
|
||||
.notMatch(ignoreWhite.getWhites())
|
||||
.check(() -> {
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
/**
|
||||
* 注册 Sa-Token 全局过滤器
|
||||
*/
|
||||
@Bean
|
||||
public SaServletFilter authSaServletFilter() {
|
||||
return new SaServletFilter()
|
||||
.addInclude("/**")
|
||||
.addExclude("/favicon.ico", "/actuator", "/actuator/**", "/resource/sse")
|
||||
.setAuth(obj -> SaRouter.match("/**")
|
||||
.notMatch(ignoreWhite.getWhites())
|
||||
.check(() -> {
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
|
||||
StpUtil.checkLogin();
|
||||
|
||||
String headerCid = request.getHeader(LoginHelper.CLIENT_KEY);
|
||||
String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY);
|
||||
Object extra = StpUtil.getExtra(LoginHelper.CLIENT_KEY);
|
||||
String clientId = extra == null ? null : extra.toString();
|
||||
if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) {
|
||||
throw NotLoginException.newInstance(StpUtil.getLoginType(),
|
||||
"-100", "客户端ID与Token不匹配",
|
||||
StpUtil.getTokenValue());
|
||||
}
|
||||
}))
|
||||
.setError(e -> {
|
||||
HttpServletResponse response = ServletUtils.getResponse();
|
||||
if (response != null) {
|
||||
response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON);
|
||||
response.setContentType(SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON);
|
||||
if (e instanceof NotLoginException) {
|
||||
return SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
StpUtil.checkLogin();
|
||||
|
||||
String headerCid = request.getHeader(LoginHelper.CLIENT_KEY);
|
||||
String paramCid = ServletUtils.getParameter(LoginHelper.CLIENT_KEY);
|
||||
Object extra = StpUtil.getExtra(LoginHelper.CLIENT_KEY);
|
||||
String clientId = extra == null ? null : extra.toString();
|
||||
if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) {
|
||||
throw NotLoginException.newInstance(StpUtil.getLoginType(),
|
||||
"-100", "客户端ID与Token不匹配",
|
||||
StpUtil.getTokenValue());
|
||||
}
|
||||
})))
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns("/favicon.ico", "/actuator", "/actuator/**", "/resource/sse");
|
||||
return SaResult.error("认证失败,无法访问系统资源").setCode(HttpStatus.UNAUTHORIZED);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,8 +63,6 @@ public class AuthFilter {
|
||||
// }
|
||||
});
|
||||
}).setError(e -> {
|
||||
ServerHttpResponse response = SaReactorSyncHolder.getExchange().getResponse();
|
||||
response.getHeaders().set(SaTokenConsts.CONTENT_TYPE_KEY, SaTokenConsts.CONTENT_TYPE_APPLICATION_JSON);
|
||||
if (e instanceof NotLoginException) {
|
||||
return SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -157,19 +157,6 @@ public class GenController extends BaseController {
|
||||
genCode(response, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代码(自定义路径)
|
||||
*
|
||||
* @param tableId 表ID
|
||||
*/
|
||||
@SaCheckPermission("tool:gen:code")
|
||||
@Log(title = "代码生成", businessType = BusinessType.GENCODE)
|
||||
@GetMapping("/genCode/{tableId}")
|
||||
public R<Void> genCode(@PathVariable("tableId") Long tableId) {
|
||||
genTableService.generatorCode(tableId);
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步数据库
|
||||
*
|
||||
|
||||
@@ -101,12 +101,12 @@ public class GenTable extends BaseEntity {
|
||||
private String functionAuthor;
|
||||
|
||||
/**
|
||||
* 生成代码方式(0zip压缩包 1自定义路径)
|
||||
* 生成代码方式(固定为0zip压缩包)
|
||||
*/
|
||||
private String genType;
|
||||
|
||||
/**
|
||||
* 生成路径(不填默认项目路径)
|
||||
* 生成路径(兼容历史字段)
|
||||
*/
|
||||
@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
|
||||
private String genPath;
|
||||
|
||||
+2
-50
@@ -23,7 +23,6 @@ import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.SpringUtils;
|
||||
import org.dromara.common.core.utils.StreamUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.core.utils.file.FileUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
@@ -40,7 +39,6 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -222,6 +220,8 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateGenTable(GenTable genTable) {
|
||||
genTable.setGenType("0");
|
||||
genTable.setGenPath("/");
|
||||
String options = JsonUtils.toJsonString(genTable.getParams());
|
||||
genTable.setOptions(options);
|
||||
int row = baseMapper.updateById(genTable);
|
||||
@@ -357,40 +357,6 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代码(自定义路径)
|
||||
*
|
||||
* @param tableId 表名称
|
||||
*/
|
||||
@Override
|
||||
public void generatorCode(Long tableId) {
|
||||
// 查询表信息
|
||||
GenTable table = baseMapper.selectGenTableById(tableId);
|
||||
// 设置主键列信息
|
||||
setPkColumn(table);
|
||||
|
||||
VelocityInitializer.initVelocity();
|
||||
|
||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||
|
||||
// 获取模板列表
|
||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getDataName());
|
||||
for (String template : templates) {
|
||||
if (!StringUtils.containsAny(template, "sql.vm", "api.ts.vm", "types.ts.vm", "index.vue.vm", "index-tree.vue.vm")) {
|
||||
// 渲染模板
|
||||
StringWriter sw = new StringWriter();
|
||||
Template tpl = Velocity.getTemplate(template, Constants.UTF8);
|
||||
tpl.merge(context, sw);
|
||||
try {
|
||||
String path = getGenPath(table, template);
|
||||
FileUtils.writeUtf8String(sw.toString(), path);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("渲染模板失败,表名:" + table.getTableName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步数据库
|
||||
*
|
||||
@@ -560,19 +526,5 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取代码生成地址
|
||||
*
|
||||
* @param table 业务表信息
|
||||
* @param template 模板文件路径
|
||||
* @return 生成地址
|
||||
*/
|
||||
public static String getGenPath(GenTable table, String template) {
|
||||
String genPath = table.getGenPath();
|
||||
if (StringUtils.equals(genPath, "/")) {
|
||||
return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table);
|
||||
}
|
||||
return genPath + File.separator + VelocityUtils.getFileName(template, table);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,13 +110,6 @@ public interface IGenTableService {
|
||||
*/
|
||||
byte[] downloadCode(Long tableId);
|
||||
|
||||
/**
|
||||
* 生成代码(自定义路径)
|
||||
*
|
||||
* @param tableId 表名称
|
||||
*/
|
||||
void generatorCode(Long tableId);
|
||||
|
||||
/**
|
||||
* 同步数据库
|
||||
*
|
||||
|
||||
+5
-3
@@ -162,9 +162,11 @@ public class WorkflowGlobalListener implements GlobalListener {
|
||||
String[] userIdArray = userIds.split(StringUtils.SEPARATOR);
|
||||
if (userIdArray.length > 0) {
|
||||
flowTask.setPermissionList(List.of(userIdArray));
|
||||
// 移除已处理的状态变量
|
||||
variable.remove(nodeKey);
|
||||
FlowEngine.insService().removeVariables(flowTask.getInstanceId(), nodeKey);
|
||||
if (TaskStatusEnum.PASS.getStatus().equals(taskStatus)) {
|
||||
// 办理指定人变量只消费一次;驳回指定人变量需要保留给后续重复驳回。
|
||||
variable.remove(nodeKey);
|
||||
FlowEngine.insService().removeVariables(flowTask.getInstanceId(), nodeKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -230,6 +230,7 @@ xss:
|
||||
enabled: true
|
||||
excludeUrls:
|
||||
- /system/notice
|
||||
- /warm-flow/save-json
|
||||
|
||||
# 接口文档配置
|
||||
springdoc:
|
||||
|
||||
@@ -27,7 +27,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
nacos:
|
||||
image: ruoyi/ruoyi-nacos:2.6.1
|
||||
image: ruoyi/ruoyi-nacos:2.6.2
|
||||
container_name: nacos
|
||||
ports:
|
||||
- "8848:8848"
|
||||
@@ -95,7 +95,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
seata-server:
|
||||
image: ruoyi/ruoyi-seata-server:2.6.1
|
||||
image: ruoyi/ruoyi-seata-server:2.6.2
|
||||
container_name: seata-server
|
||||
ports:
|
||||
- "7091:7091"
|
||||
@@ -134,7 +134,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-monitor:
|
||||
image: ruoyi/ruoyi-monitor:2.6.1
|
||||
image: ruoyi/ruoyi-monitor:2.6.2
|
||||
container_name: ruoyi-monitor
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -150,7 +150,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-snailjob-server:
|
||||
image: ruoyi/ruoyi-snailjob-server:2.6.1
|
||||
image: ruoyi/ruoyi-snailjob-server:2.6.2
|
||||
container_name: ruoyi-snailjob-server
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -164,7 +164,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-gateway:
|
||||
image: ruoyi/ruoyi-gateway:2.6.1
|
||||
image: ruoyi/ruoyi-gateway:2.6.2
|
||||
container_name: ruoyi-gateway
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -180,7 +180,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-auth:
|
||||
image: ruoyi/ruoyi-auth:2.6.1
|
||||
image: ruoyi/ruoyi-auth:2.6.2
|
||||
container_name: ruoyi-auth
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -196,7 +196,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-system:
|
||||
image: ruoyi/ruoyi-system:2.6.1
|
||||
image: ruoyi/ruoyi-system:2.6.2
|
||||
container_name: ruoyi-system
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -212,7 +212,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-gen:
|
||||
image: ruoyi/ruoyi-gen:2.6.1
|
||||
image: ruoyi/ruoyi-gen:2.6.2
|
||||
container_name: ruoyi-gen
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -228,7 +228,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-job:
|
||||
image: ruoyi/ruoyi-job:2.6.1
|
||||
image: ruoyi/ruoyi-job:2.6.2
|
||||
container_name: ruoyi-job
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -246,7 +246,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-resource:
|
||||
image: ruoyi/ruoyi-resource:2.6.1
|
||||
image: ruoyi/ruoyi-resource:2.6.2
|
||||
container_name: ruoyi-resource
|
||||
environment:
|
||||
# 时区上海
|
||||
@@ -262,7 +262,7 @@ services:
|
||||
network_mode: "host"
|
||||
|
||||
ruoyi-workflow:
|
||||
image: ruoyi/ruoyi-workflow:2.6.1
|
||||
image: ruoyi/ruoyi-workflow:2.6.2
|
||||
container_name: ruoyi-workflow
|
||||
environment:
|
||||
# 时区上海
|
||||
|
||||
Reference in New Issue
Block a user