From 08d4493994a649b725d94e917b31d42c930284ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 15 Jul 2024 15:18:29 +0800 Subject: [PATCH 1/9] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20bug=20?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 49 ---------------------------------- .gitee/ISSUE_TEMPLATE/bug.yml | 5 ++-- 2 files changed, 3 insertions(+), 51 deletions(-) delete mode 100644 .gitee/ISSUE_TEMPLATE.zh-CN.md diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md deleted file mode 100644 index cf82237f3..000000000 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,49 +0,0 @@ -### 使用版本(未按照模板填写直接删除) - -- jdk版本(带上尾号): 例如 1.8.0_202 -- 框架版本(项目启动时输出的版本号): 例如 4.4.0 -- 其他依赖版本(你觉得有必要的): - -### 问题前提 - -> 功能不好用 不会用 是否已经看过项目文档 -> 项目运行报错 是否已经拿着报错信息去百度 常见报错百度百度足以 -> 是否搜索过其他issue 一些已经解决的问题 会在issue内留下解决方法 -> 无法线上解决或者与框架无关的问题的欢迎加VIP群跟作者一对一谈 - -### 异常模块 - -> 此报错都涉及到那些系统模块 - -例如 ruoyi-system ruoyi-auth 等等 - -### 问题描述 - -> 越详细越容易直击问题所在 - -已知: XXX功能不好用 或 XXX数据不正常 等等 - -### 希望结果 - -> 想知道你觉得怎么样是正常或者合理的 - -希望功能可以有XXX结果 或者 XXX现象 - -### 重现步骤 - -> 作者并不知道这个问题是如何出现的 - -- 1 -- 2 -- 3 - -### 相关代码与报错信息(请勿发混乱格式) - -> 代码可按照如下形式提供或者截图均可 越详细越好 -> 大多数问题都是 代码编写错误问题 逻辑问题 或者用法错误等问题 - -```java -public class XXX { - -} -``` \ No newline at end of file diff --git a/.gitee/ISSUE_TEMPLATE/bug.yml b/.gitee/ISSUE_TEMPLATE/bug.yml index 8a5d06500..045001336 100644 --- a/.gitee/ISSUE_TEMPLATE/bug.yml +++ b/.gitee/ISSUE_TEMPLATE/bug.yml @@ -9,8 +9,9 @@ body: label: 版本 description: 你当前正在使用我们软件的哪个版本(pom文件内的版本号)? value: | - jdk版本(带上尾号): 例如 17.0.8 - 框架版本(项目启动时输出的版本号): 例如 5.1.1 + 注意: 未填写版本号不予处理直接关闭或删除 + jdk版本(带上尾号): + 框架版本(项目启动时输出的版本号): 其他依赖版本(你觉得有必要的): validations: required: true From 7e14b9867623e4ae8ae0eb1c35598562afb90552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Mon, 28 Oct 2024 09:46:28 +0000 Subject: [PATCH 2/9] =?UTF-8?q?reset=20=E5=9B=9E=E6=BB=9A=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 疯狂的狮子Li <15040126243@163.com> --- .../main/java/org/dromara/common/oss/core/OssClient.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java index 900536b56..ba924c0bb 100644 --- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java +++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/core/OssClient.java @@ -83,10 +83,10 @@ public class OssClient { StaticCredentialsProvider credentialsProvider = StaticCredentialsProvider.create( AwsBasicCredentials.create(properties.getAccessKey(), properties.getSecretKey())); - //使用对象存储服务时要求明确配置访问样式(路径样式或虚拟托管样式)。需要启用路径样式访问 - boolean isStyle = true; + // MinIO 使用 HTTPS 限制使用域名访问,站点填域名。需要启用路径样式访问 + boolean isStyle = !StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE); - //创建AWS基于 CRT 的 S3 客户端 + // 创建AWS基于 CRT 的 S3 客户端 this.client = S3AsyncClient.crtBuilder() .credentialsProvider(credentialsProvider) .endpointOverride(URI.create(getEndpoint())) From ea50a57602f6de4ecee9daf224f3177a6848c335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Tue, 12 Nov 2024 18:17:47 +0800 Subject: [PATCH 3/9] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20xss=E5=8C=85?= =?UTF-8?q?=E8=A3=85=E5=99=A8=20Parameter=20=E5=A4=84=E7=90=86=20=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=9F=90=E4=BA=9B=E5=AE=B9=E5=99=A8=E4=B8=8D=E5=85=81?= =?UTF-8?q?=E8=AE=B8=E6=94=B9=E5=8F=82=E6=95=B0=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter/XssHttpServletRequestWrapper.java | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java index 190f94eab..914e54995 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/filter/XssHttpServletRequestWrapper.java @@ -1,19 +1,22 @@ package org.dromara.common.web.filter; import cn.hutool.core.io.IoUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HtmlUtil; -import org.dromara.common.core.utils.StringUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; - import jakarta.servlet.ReadListener; import jakarta.servlet.ServletInputStream; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequestWrapper; +import org.dromara.common.core.utils.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.Map; /** @@ -32,16 +35,22 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { @Override public String getParameter(String name) { String value = super.getParameter(name); - if (value != null) { - return HtmlUtil.cleanHtmlTag(value).trim(); + if (value == null) { + return null; } - return value; + return HtmlUtil.cleanHtmlTag(value).trim(); } @Override public Map getParameterMap() { Map valueMap = super.getParameterMap(); - for (Map.Entry entry : valueMap.entrySet()) { + if (MapUtil.isEmpty(valueMap)) { + return valueMap; + } + // 避免某些容器不允许改参数的情况 copy一份重新改 + Map map = new HashMap<>(valueMap.size()); + map.putAll(valueMap); + for (Map.Entry entry : map.entrySet()) { String[] values = entry.getValue(); if (values != null) { int length = values.length; @@ -50,25 +59,25 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { // 防xss攻击和过滤前后空格 escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim(); } - valueMap.put(entry.getKey(), escapseValues); + map.put(entry.getKey(), escapseValues); } } - return valueMap; + return map; } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); - if (values != null) { - int length = values.length; - String[] escapseValues = new String[length]; - for (int i = 0; i < length; i++) { - // 防xss攻击和过滤前后空格 - escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim(); - } - return escapseValues; + if (ArrayUtil.isEmpty(values)) { + return values; } - return values; + int length = values.length; + String[] escapseValues = new String[length]; + for (int i = 0; i < length; i++) { + // 防xss攻击和过滤前后空格 + escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim(); + } + return escapseValues; } @Override From 7a9f51fc7a356ea9f7b693328117660fe59cbf81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Thu, 27 Mar 2025 02:51:57 +0000 Subject: [PATCH 4/9] =?UTF-8?q?!662=20=E5=8F=91=E5=B8=83=205.3.1=20?= =?UTF-8?q?=E6=AD=A3=E5=BC=8F=E7=89=88=20*=20=F0=9F=90=B3=E5=8F=91?= =?UTF-8?q?=E5=B8=83=205.3.1=20=E6=AD=A3=E5=BC=8F=E7=89=88=20*=20update=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20*=20fix=20=E4=BF=AE=E5=A4=8D=20excel?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=AF=BC=E5=87=BA=E6=95=B0=E6=8D=AE=E8=A2=AB?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E7=9A=84=E9=97=AE=E9=A2=98=20*=20update=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E7=BB=9F=E4=B8=80=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E6=A0=A1=E9=AA=8C=E9=95=BF=E5=BA=A6=20*=20up?= =?UTF-8?q?date=20mybatis-plus=203.5.10.1=20=3D>=203.5.11=20*=20fix=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E8=B7=A8=E5=9F=9F=E6=9C=AA=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E8=AF=B7=E6=B1=82=E5=A4=B4=E9=97=AE=E9=A2=98(cloud?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E4=B8=8D=E9=9C=80=E8=A6=81=20vue=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E9=9C=80=E8=A6=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .run/ruoyi-monitor-admin.run.xml | 2 +- .run/ruoyi-server.run.xml | 2 +- .run/ruoyi-snailjob-server.run.xml | 2 +- README.md | 2 +- pom.xml | 6 +++--- ruoyi-common/ruoyi-common-bom/pom.xml | 2 +- .../common/core/domain/model/PasswordLoginBody.java | 4 ++-- .../common/encrypt/filter/EncryptResponseBodyWrapper.java | 5 +++++ .../java/org/dromara/common/excel/utils/ExcelUtil.java | 5 +++-- ruoyi-extend/ruoyi-monitor-admin/pom.xml | 3 --- .../src/main/resources/application-dev.yml | 4 +--- .../src/main/resources/application-prod.yml | 4 +--- script/docker/docker-compose.yml | 8 ++++---- 13 files changed, 24 insertions(+), 25 deletions(-) diff --git a/.run/ruoyi-monitor-admin.run.xml b/.run/ruoyi-monitor-admin.run.xml index 3b5b97b4d..065ff01a7 100644 --- a/.run/ruoyi-monitor-admin.run.xml +++ b/.run/ruoyi-monitor-admin.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-server.run.xml b/.run/ruoyi-server.run.xml index dddc04057..6c5031edb 100644 --- a/.run/ruoyi-server.run.xml +++ b/.run/ruoyi-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-snailjob-server.run.xml b/.run/ruoyi-snailjob-server.run.xml index e48c539d2..859902ac1 100644 --- a/.run/ruoyi-snailjob-server.run.xml +++ b/.run/ruoyi-snailjob-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/README.md b/README.md index ca67c874a..fc3131a24 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
-[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.3.0--BETA2-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) +[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.3.0-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4-blue.svg)]() [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]() [![JDK-21](https://img.shields.io/badge/JDK-21-green.svg)]() diff --git a/pom.xml b/pom.xml index c99cbb252..f1362f2e3 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ Dromara RuoYi-Vue-Plus多租户管理系统 - 5.3.1-BETA2 + 5.3.1 3.4.4 UTF-8 UTF-8 @@ -24,14 +24,14 @@ 4.0.3 2.3 1.40.0 - 3.5.10.1 + 3.5.11 3.9.1 5.8.35 3.4.5 3.45.1 2.2.7 4.3.1 - 1.4.0-beta2 + 1.4.0 1.4.6 0.2.0 1.18.36 diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index c8ea1ffa4..62967c30d 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -14,7 +14,7 @@ - 5.3.1-BETA2 + 5.3.1 diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java index 87d0e8e73..36e33b24b 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java @@ -18,14 +18,14 @@ public class PasswordLoginBody extends LoginBody { * 用户名 */ @NotBlank(message = "{user.username.not.blank}") - @Length(min = 2, max = 20, message = "{user.username.length.valid}") + @Length(min = 2, max = 30, message = "{user.username.length.valid}") private String username; /** * 用户密码 */ @NotBlank(message = "{user.password.not.blank}") - @Length(min = 5, max = 20, message = "{user.password.length.valid}") + @Length(min = 5, max = 30, message = "{user.password.length.valid}") private String password; } diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java index 7bbca49d0..78e06ff73 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java @@ -76,9 +76,14 @@ public class EncryptResponseBodyWrapper extends HttpServletResponseWrapper { String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey); // 设置响应头 + // vue版本需要设置 + servletResponse.addHeader("Access-Control-Expose-Headers", headerFlag); + servletResponse.setHeader("Access-Control-Allow-Origin", "*"); + servletResponse.setHeader("Access-Control-Allow-Methods", "*"); servletResponse.setHeader(headerFlag, encryptPassword); servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString()); + // 获取原始内容 String originalBody = this.getContent(); // 对内容进行加密 diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java index b22e6f987..0e9569677 100644 --- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java +++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java @@ -245,9 +245,10 @@ public class ExcelUtil { .registerWriteHandler(new DataWriteHandler(data.get(0).getClass())) .build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); + FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); // 单表多数据导出 模板格式为 {.属性} for (T d : data) { - excelWriter.fill(d, writeSheet); + excelWriter.fill(d, fillConfig, writeSheet); } excelWriter.finish(); } @@ -320,7 +321,7 @@ public class ExcelUtil { // 多表导出必须使用 FillWrapper excelWriter.fill(new FillWrapper(map.getKey(), (Collection) map.getValue()), fillConfig, writeSheet); } else { - excelWriter.fill(map.getValue(), writeSheet); + excelWriter.fill(map.getValue(), fillConfig, writeSheet); } } excelWriter.finish(); diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml index 77c9eb71a..538ffbd9f 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml +++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml @@ -59,9 +59,6 @@ org.springframework.boot spring-boot-maven-plugin ${spring-boot.version} - - - diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml index caf5dba55..aaf474895 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml @@ -22,10 +22,8 @@ snail-job: job-pull-page-size: 1000 # 服务器端口 server-port: 17888 - # 号段模式下步长配置 - step: 100 # 日志保存时间(单位: day) - log-storage: 90 + log-storage: 7 rpc-type: grpc --- # 监控中心配置 diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml index caf5dba55..aaf474895 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml @@ -22,10 +22,8 @@ snail-job: job-pull-page-size: 1000 # 服务器端口 server-port: 17888 - # 号段模式下步长配置 - step: 100 # 日志保存时间(单位: day) - log-storage: 90 + log-storage: 7 rpc-type: grpc --- # 监控中心配置 diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml index cd5b567a3..fb35cae6f 100644 --- a/script/docker/docker-compose.yml +++ b/script/docker/docker-compose.yml @@ -98,7 +98,7 @@ services: network_mode: "host" ruoyi-server1: - image: ruoyi/ruoyi-server:5.3.1-BETA2 + image: ruoyi/ruoyi-server:5.3.1 container_name: ruoyi-server1 environment: # 时区上海 @@ -113,7 +113,7 @@ services: network_mode: "host" ruoyi-server2: - image: ruoyi/ruoyi-server:5.3.1-BETA2 + image: ruoyi/ruoyi-server:5.3.1 container_name: ruoyi-server2 environment: # 时区上海 @@ -128,7 +128,7 @@ services: network_mode: "host" ruoyi-monitor-admin: - image: ruoyi/ruoyi-monitor-admin:5.3.1-BETA2 + image: ruoyi/ruoyi-monitor-admin:5.3.1 container_name: ruoyi-monitor-admin environment: # 时区上海 @@ -140,7 +140,7 @@ services: network_mode: "host" ruoyi-snailjob-server: - image: ruoyi/ruoyi-snailjob-server:5.3.1-BETA2 + image: ruoyi/ruoyi-snailjob-server:5.3.1 container_name: ruoyi-snailjob-server environment: # 时区上海 From 8aa60abb1fa3a00714a65e79360b47a6622a502b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Thu, 27 Mar 2025 02:53:23 +0000 Subject: [PATCH 5/9] =?UTF-8?q?!663=20=E5=9B=9E=E9=80=80=20'Pull=20Request?= =?UTF-8?q?=20!662=20:=20=E5=8F=91=E5=B8=83=205.3.1=20=E6=AD=A3=E5=BC=8F?= =?UTF-8?q?=E7=89=88'=20*=20=E5=9B=9E=E9=80=80=20'Pull=20Request=20!662=20?= =?UTF-8?q?:=20=E5=8F=91=E5=B8=83=205.3.1=20=E6=AD=A3=E5=BC=8F=E7=89=88'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .run/ruoyi-monitor-admin.run.xml | 2 +- .run/ruoyi-server.run.xml | 2 +- .run/ruoyi-snailjob-server.run.xml | 2 +- README.md | 2 +- pom.xml | 6 +++--- ruoyi-common/ruoyi-common-bom/pom.xml | 2 +- .../common/core/domain/model/PasswordLoginBody.java | 4 ++-- .../common/encrypt/filter/EncryptResponseBodyWrapper.java | 5 ----- .../java/org/dromara/common/excel/utils/ExcelUtil.java | 5 ++--- ruoyi-extend/ruoyi-monitor-admin/pom.xml | 3 +++ .../src/main/resources/application-dev.yml | 4 +++- .../src/main/resources/application-prod.yml | 4 +++- script/docker/docker-compose.yml | 8 ++++---- 13 files changed, 25 insertions(+), 24 deletions(-) diff --git a/.run/ruoyi-monitor-admin.run.xml b/.run/ruoyi-monitor-admin.run.xml index 065ff01a7..3b5b97b4d 100644 --- a/.run/ruoyi-monitor-admin.run.xml +++ b/.run/ruoyi-monitor-admin.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-server.run.xml b/.run/ruoyi-server.run.xml index 6c5031edb..dddc04057 100644 --- a/.run/ruoyi-server.run.xml +++ b/.run/ruoyi-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/.run/ruoyi-snailjob-server.run.xml b/.run/ruoyi-snailjob-server.run.xml index 859902ac1..e48c539d2 100644 --- a/.run/ruoyi-snailjob-server.run.xml +++ b/.run/ruoyi-snailjob-server.run.xml @@ -2,7 +2,7 @@ - diff --git a/README.md b/README.md index fc3131a24..ca67c874a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
-[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.3.0-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) +[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.3.0--BETA2-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus) [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.4-blue.svg)]() [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]() [![JDK-21](https://img.shields.io/badge/JDK-21-green.svg)]() diff --git a/pom.xml b/pom.xml index f1362f2e3..c99cbb252 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ Dromara RuoYi-Vue-Plus多租户管理系统 - 5.3.1 + 5.3.1-BETA2 3.4.4 UTF-8 UTF-8 @@ -24,14 +24,14 @@ 4.0.3 2.3 1.40.0 - 3.5.11 + 3.5.10.1 3.9.1 5.8.35 3.4.5 3.45.1 2.2.7 4.3.1 - 1.4.0 + 1.4.0-beta2 1.4.6 0.2.0 1.18.36 diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index 62967c30d..c8ea1ffa4 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -14,7 +14,7 @@ - 5.3.1 + 5.3.1-BETA2 diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java index 36e33b24b..87d0e8e73 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/PasswordLoginBody.java @@ -18,14 +18,14 @@ public class PasswordLoginBody extends LoginBody { * 用户名 */ @NotBlank(message = "{user.username.not.blank}") - @Length(min = 2, max = 30, message = "{user.username.length.valid}") + @Length(min = 2, max = 20, message = "{user.username.length.valid}") private String username; /** * 用户密码 */ @NotBlank(message = "{user.password.not.blank}") - @Length(min = 5, max = 30, message = "{user.password.length.valid}") + @Length(min = 5, max = 20, message = "{user.password.length.valid}") private String password; } diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java index 78e06ff73..7bbca49d0 100644 --- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java +++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java @@ -76,14 +76,9 @@ public class EncryptResponseBodyWrapper extends HttpServletResponseWrapper { String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey); // 设置响应头 - // vue版本需要设置 - servletResponse.addHeader("Access-Control-Expose-Headers", headerFlag); - servletResponse.setHeader("Access-Control-Allow-Origin", "*"); - servletResponse.setHeader("Access-Control-Allow-Methods", "*"); servletResponse.setHeader(headerFlag, encryptPassword); servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString()); - // 获取原始内容 String originalBody = this.getContent(); // 对内容进行加密 diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java index 0e9569677..b22e6f987 100644 --- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java +++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java @@ -245,10 +245,9 @@ public class ExcelUtil { .registerWriteHandler(new DataWriteHandler(data.get(0).getClass())) .build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); - FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build(); // 单表多数据导出 模板格式为 {.属性} for (T d : data) { - excelWriter.fill(d, fillConfig, writeSheet); + excelWriter.fill(d, writeSheet); } excelWriter.finish(); } @@ -321,7 +320,7 @@ public class ExcelUtil { // 多表导出必须使用 FillWrapper excelWriter.fill(new FillWrapper(map.getKey(), (Collection) map.getValue()), fillConfig, writeSheet); } else { - excelWriter.fill(map.getValue(), fillConfig, writeSheet); + excelWriter.fill(map.getValue(), writeSheet); } } excelWriter.finish(); diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml index 538ffbd9f..77c9eb71a 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml +++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml @@ -59,6 +59,9 @@ org.springframework.boot spring-boot-maven-plugin ${spring-boot.version} + + + diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml index aaf474895..caf5dba55 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml @@ -22,8 +22,10 @@ snail-job: job-pull-page-size: 1000 # 服务器端口 server-port: 17888 + # 号段模式下步长配置 + step: 100 # 日志保存时间(单位: day) - log-storage: 7 + log-storage: 90 rpc-type: grpc --- # 监控中心配置 diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml index aaf474895..caf5dba55 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml @@ -22,8 +22,10 @@ snail-job: job-pull-page-size: 1000 # 服务器端口 server-port: 17888 + # 号段模式下步长配置 + step: 100 # 日志保存时间(单位: day) - log-storage: 7 + log-storage: 90 rpc-type: grpc --- # 监控中心配置 diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml index fb35cae6f..cd5b567a3 100644 --- a/script/docker/docker-compose.yml +++ b/script/docker/docker-compose.yml @@ -98,7 +98,7 @@ services: network_mode: "host" ruoyi-server1: - image: ruoyi/ruoyi-server:5.3.1 + image: ruoyi/ruoyi-server:5.3.1-BETA2 container_name: ruoyi-server1 environment: # 时区上海 @@ -113,7 +113,7 @@ services: network_mode: "host" ruoyi-server2: - image: ruoyi/ruoyi-server:5.3.1 + image: ruoyi/ruoyi-server:5.3.1-BETA2 container_name: ruoyi-server2 environment: # 时区上海 @@ -128,7 +128,7 @@ services: network_mode: "host" ruoyi-monitor-admin: - image: ruoyi/ruoyi-monitor-admin:5.3.1 + image: ruoyi/ruoyi-monitor-admin:5.3.1-BETA2 container_name: ruoyi-monitor-admin environment: # 时区上海 @@ -140,7 +140,7 @@ services: network_mode: "host" ruoyi-snailjob-server: - image: ruoyi/ruoyi-snailjob-server:5.3.1 + image: ruoyi/ruoyi-snailjob-server:5.3.1-BETA2 container_name: ruoyi-snailjob-server environment: # 时区上海 From 957a4d1fcd254882d6ff8ad537b9ceec5afe3be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Thu, 29 May 2025 15:38:29 +0800 Subject: [PATCH 6/9] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E7=9B=91?= =?UTF-8?q?=E5=90=AC=E5=99=A8=20flowParams=20=E4=B8=BAnull=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/workflow/listener/WorkflowGlobalListener.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java index 027865bc8..01a9194c4 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java @@ -106,6 +106,7 @@ public class WorkflowGlobalListener implements GlobalListener { Task task = listenerVariable.getTask(); Map params = new HashMap<>(); FlowParams flowParams = listenerVariable.getFlowParams(); + Map variable = new HashMap<>(); if (ObjectUtil.isNotNull(flowParams)) { // 历史任务扩展(通常为附件) params.put("hisTaskExt", flowParams.getHisTaskExt()); @@ -113,8 +114,8 @@ public class WorkflowGlobalListener implements GlobalListener { params.put("handler", flowParams.getHandler()); // 办理意见 params.put("message", flowParams.getMessage()); + variable = flowParams.getVariable(); } - Map variable = flowParams.getVariable(); //申请人提交事件 Boolean submit = MapUtil.getBool(variable, FlowConstant.SUBMIT); if (submit != null && submit) { From d22b2a10dff0e6552bc648adaeca62f01d9b590f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Thu, 29 May 2025 16:28:09 +0800 Subject: [PATCH 7/9] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20PermissionSer?= =?UTF-8?q?vice=20=E6=97=A0=E5=AE=9E=E7=8E=B0=E7=B1=BB=E4=B9=9F=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E5=90=AF=E5=8A=A8=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/service/SaPermissionImpl.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java index 35d16cd6e..e57d1fbde 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/service/SaPermissionImpl.java @@ -4,10 +4,11 @@ import cn.dev33.satoken.stp.StpInterface; import cn.hutool.core.util.ObjectUtil; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.enums.UserType; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.service.PermissionService; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.satoken.utils.LoginHelper; -import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; import java.util.List; @@ -19,9 +20,6 @@ import java.util.List; */ public class SaPermissionImpl implements StpInterface { - @Autowired - private PermissionService permissionService; - /** * 获取菜单权限列表 */ @@ -29,8 +27,13 @@ public class SaPermissionImpl implements StpInterface { public List getPermissionList(Object loginId, String loginType) { LoginUser loginUser = LoginHelper.getLoginUser(); if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(loginId)) { - List list = StringUtils.splitList(loginId.toString(), ":"); - return new ArrayList<>(permissionService.getMenuPermission(Long.parseLong(list.get(1)))); + PermissionService permissionService = getPermissionService(); + if (ObjectUtil.isNotNull(permissionService)) { + List list = StringUtils.splitList(loginId.toString(), ":"); + return new ArrayList<>(permissionService.getMenuPermission(Long.parseLong(list.get(1)))); + } else { + throw new ServiceException("PermissionService 实现类不存在"); + } } UserType userType = UserType.getUserType(loginUser.getUserType()); if (userType == UserType.APP_USER) { @@ -47,8 +50,13 @@ public class SaPermissionImpl implements StpInterface { public List getRoleList(Object loginId, String loginType) { LoginUser loginUser = LoginHelper.getLoginUser(); if (ObjectUtil.isNull(loginUser) || !loginUser.getLoginId().equals(loginId)) { - List list = StringUtils.splitList(loginId.toString(), ":"); - return new ArrayList<>(permissionService.getRolePermission(Long.parseLong(list.get(1)))); + PermissionService permissionService = getPermissionService(); + if (ObjectUtil.isNotNull(permissionService)) { + List list = StringUtils.splitList(loginId.toString(), ":"); + return new ArrayList<>(permissionService.getRolePermission(Long.parseLong(list.get(1)))); + } else { + throw new ServiceException("PermissionService 实现类不存在"); + } } UserType userType = UserType.getUserType(loginUser.getUserType()); if (userType == UserType.APP_USER) { @@ -57,4 +65,13 @@ public class SaPermissionImpl implements StpInterface { // SYS_USER 默认返回权限 return new ArrayList<>(loginUser.getRolePermission()); } + + private PermissionService getPermissionService() { + try { + return SpringUtils.getBean(PermissionService.class); + } catch (Exception e) { + return null; + } + } + } From fd5d028e9506974152853cb7765a4cea2159b567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90Li?= <15040126243@163.com> Date: Fri, 4 Jul 2025 01:10:49 +0000 Subject: [PATCH 8/9] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E6=9C=89?= =?UTF-8?q?=E6=9F=90=E4=BA=9B=E6=97=A0=E8=81=8A=E4=BA=BA=E5=A3=AB=20?= =?UTF-8?q?=E5=AF=B9=E4=B8=80=E4=B8=AAdemo=E6=A1=88=E4=BE=8B=E6=8F=90?= =?UTF-8?q?=E6=BC=8F=E6=B4=9E=20CVE-2025-6925?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 疯狂的狮子Li <15040126243@163.com> --- .../org/dromara/demo/controller/MailController.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java index 01f50449f..6fc5a17ba 100644 --- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java +++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/MailController.java @@ -1,6 +1,5 @@ package org.dromara.demo.controller; -import cn.dev33.satoken.annotation.SaIgnore; import lombok.RequiredArgsConstructor; import org.dromara.common.core.domain.R; import org.dromara.common.mail.utils.MailUtils; @@ -18,7 +17,6 @@ import java.util.Arrays; * * @author Michelle.Chung */ -@SaIgnore @Validated @RequiredArgsConstructor @RestController @@ -44,11 +42,11 @@ public class MailController { * @param to 接收人 * @param subject 标题 * @param text 内容 - * @param filePath 附件路径 */ @GetMapping("/sendMessageWithAttachment") - public R sendMessageWithAttachment(String to, String subject, String text, String filePath) { - MailUtils.sendText(to, subject, text, new File(filePath)); + public R sendMessageWithAttachment(String to, String subject, String text) { + // 附件路径 禁止前端传递 有任意读取系统文件风险 + MailUtils.sendText(to, subject, text, new File("/xxx/xxx")); return R.ok(); } @@ -58,10 +56,11 @@ public class MailController { * @param to 接收人 * @param subject 标题 * @param text 内容 - * @param paths 附件路径 */ @GetMapping("/sendMessageWithAttachments") - public R sendMessageWithAttachments(String to, String subject, String text, String[] paths) { + public R sendMessageWithAttachments(String to, String subject, String text) { + // 附件路径 禁止前端传递 有任意读取系统文件风险 + String[] paths = new String[]{"/xxx/xxx", "/xxx/xxx"}; File[] array = Arrays.stream(paths).map(File::new).toArray(File[]::new); MailUtils.sendText(to, subject, text, array); return R.ok(); From b2762e336d430ad15670dd7c459a6b987df461e1 Mon Sep 17 00:00:00 2001 From: shichenyang Date: Thu, 29 Jan 2026 16:05:54 +0800 Subject: [PATCH 9/9] =?UTF-8?q?docs:=20=E8=87=AA=E7=94=A8skill?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-feature-developer.skill | Bin 0 -> 31298 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ruoyi-feature-developer.skill diff --git a/ruoyi-feature-developer.skill b/ruoyi-feature-developer.skill new file mode 100644 index 0000000000000000000000000000000000000000..8d9cbe6f9ca33c0977ed7c4833bb766bedab27b3 GIT binary patch literal 31298 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 literal 0 HcmV?d00001