From 8b97e7bc53e039f3985bbdfdce4c84e0ea114933 Mon Sep 17 00:00:00 2001
From: ColorDreams <545073804@qq.com>
Date: Wed, 24 Dec 2025 19:09:36 +0800
Subject: [PATCH 01/20] update ip2region version to 3.3.2
---
pom.xml | 2 +-
.../common/core/utils/ip/RegionUtils.java | 32 ++++++++-----------
2 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/pom.xml b/pom.xml
index 0c175fda9..16e05d583 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,7 @@
1.80
1.16.7
- 3.3.1
+ 3.3.2
2.28.22
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
index 191b1e599..5c74a8351 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/ip/RegionUtils.java
@@ -1,6 +1,5 @@
package org.dromara.common.core.utils.ip;
-import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
@@ -9,7 +8,6 @@ import org.lionsoul.ip2region.service.Config;
import org.lionsoul.ip2region.service.Ip2Region;
import org.lionsoul.ip2region.xdb.Util;
-import java.io.File;
import java.io.InputStream;
import java.time.Duration;
@@ -31,6 +29,11 @@ public class RegionUtils {
// 下载地址:https://gitee.com/lionsoul/ip2region/blob/master/data/ip2region_v6.xdb
public static final String DEFAULT_IPV6_XDB_PATH = "ip2region_v6.xdb";
+ // 默认缓存切片大小为15MB(仅针对BufferCache全量读取有效,如果你的xdb数据库很大,合理设置该值可以有效提升BufferCache模式下的查询效率,具体可以查看Ip2Region的README)
+ // 注意:设置过大的值可能会申请内存时,因内存不足而导致OOM,请合理设置该值。
+ // README:https://gitee.com/lionsoul/ip2region/tree/master/binding/java
+ public static final int DEFAULT_CACHE_SLICE_BYTES = 1024 * 1024 * 15;
+
// 未知地址
public static final String UNKNOWN_ADDRESS = "未知";
@@ -43,20 +46,18 @@ public class RegionUtils {
// 注意:Ip2Region 的xdb文件加载策略 CachePolicy 有三种,分别是:BufferCache(全量读取xdb到内存中)、VIndexCache(默认策略,按需读取并缓存)、NoCache(实时读取)
// 本项目工具使用的 CachePolicy 为 BufferCache,BufferCache会加载整个xdb文件到内存中,setXdbInputStream 仅支持 BufferCache 策略。
// 因为加载整个xdb文件会耗费非常大的内存,如果你不希望加载整个xdb到内存中,更推荐使用 VIndexCache 或 NoCache(即实时读取文件)策略和 setXdbPath/setXdbFile 加载方法(需要注意的一点,setXdbPath 和 setXdbFile 不支持读取ClassPath(即源码和resource目录)中的文件)。
- // 一般而言,更建议把xdb数据库放到一个指定的文件目录中(即不打包进jar包中),然后使用 NoCache + 配合SearcherPool的并发池读取数据,更方便随时更新xdb数据库
+ // 一般而言,更建议把xdb数据库放到一个指定的文件目录中(即不打包进jar包中),然后使用 VIndexCache + 配合SearcherPool的并发池读取数据,更方便随时更新xdb数据库
- // TODO 2025年12月23日 Ip2Region封装的 InputStream 读取函数 Searcher.loadContentFromInputStream 在Linux环境下会申请过大的byte[]空间而导致OOM,这里先用临时文件的方案解决,等后续 Ip2Region 更新解决方案
- // 创建临时文件
- File v4TempXdb = FileUtil.writeFromStream(ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH), FileUtil.createTempFile());
+ InputStream v4InputStream = ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH);
// IPv4配置
Config v4Config = Config.custom()
.setCachePolicy(Config.BufferCache)
- .setXdbFile(v4TempXdb)
-// .setXdbInputStream(ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH))
+ //.setXdbFile(v4TempXdb)
+ .setXdbInputStream(v4InputStream)
+ //
+ .setCacheSliceBytes(DEFAULT_CACHE_SLICE_BYTES)
.asV4();
- // 删除临时文件
- v4TempXdb.delete();
// IPv6配置
Config v6Config = null;
@@ -64,17 +65,12 @@ public class RegionUtils {
if (v6XdbInputStream == null) {
log.warn("未加载 IPv6 地址库:未在类路径下找到文件 {}。当前仅启用 IPv4 查询。如需启用 IPv6,请将 ip2region_v6.xdb 放置到 resources 目录", DEFAULT_IPV6_XDB_PATH);
} else {
- // 创建临时文件
- File v6TempXdb = FileUtil.writeFromStream(ResourceUtil.getStream(DEFAULT_IPV4_XDB_PATH), FileUtil.createTempFile());
-
v6Config = Config.custom()
.setCachePolicy(Config.BufferCache)
- .setXdbFile(v6TempXdb)
-// .setXdbInputStream(v6XdbInputStream)
+ //.setXdbFile(v6TempXdb)
+ .setXdbInputStream(v6XdbInputStream)
+ .setCacheSliceBytes(DEFAULT_CACHE_SLICE_BYTES)
.asV6();
-
- // 删除临时文件
- v6TempXdb.delete();
}
// 初始化Ip2Region实例
From d634c2a292250c422997e1c1055e7a6b3870d207 Mon Sep 17 00:00:00 2001
From: AprilWind <2100166581@qq.com>
Date: Mon, 5 Jan 2026 14:39:40 +0800
Subject: [PATCH 02/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96oss=E6=97=A5?=
=?UTF-8?q?=E5=BF=97=E4=BE=A6=E5=90=AC=E5=99=A8=E6=89=93=E5=8D=B0=E7=BA=A7?=
=?UTF-8?q?=E5=88=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../dromara/common/oss/core/OssClient.java | 67 +++++++++++--------
1 file changed, 39 insertions(+), 28 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 089d1926b..14fc4dcfe 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
@@ -141,7 +141,8 @@ public class OssClient {
try {
// 构建上传请求对象
FileUpload fileUpload = transferManager.uploadFile(
- x -> x.putObjectRequest(
+ x -> {
+ x.source(filePath).putObjectRequest(
y -> y.bucket(properties.getBucketName())
.key(key)
.contentMD5(StringUtils.isNotEmpty(md5Digest) ? md5Digest : null)
@@ -149,10 +150,13 @@ public class OssClient {
// 用于设置对象的访问控制列表(ACL)。不同云厂商对ACL的支持和实现方式有所不同,
// 因此根据具体的云服务提供商,你可能需要进行不同的配置(自行开启,阿里云有acl权限配置,腾讯云没有acl权限配置)
//.acl(getAccessPolicy().getObjectCannedACL())
- .build())
- .addTransferListener(LoggingTransferListener.create())
- .source(filePath).build());
-
+ .build()
+ );
+ if (log.isDebugEnabled()) {
+ x.addTransferListener(LoggingTransferListener.create());
+ }
+ }
+ );
// 等待上传完成并获取上传结果
CompletedFileUpload uploadResult = fileUpload.completionFuture().join();
String eTag = uploadResult.response().eTag();
@@ -192,16 +196,21 @@ public class OssClient {
// 使用 transferManager 进行上传
Upload upload = transferManager.upload(
- x -> x.requestBody(body).addTransferListener(LoggingTransferListener.create())
- .putObjectRequest(
+ x -> {
+ x.requestBody(body).putObjectRequest(
y -> y.bucket(properties.getBucketName())
.key(key)
.contentType(contentType)
// 用于设置对象的访问控制列表(ACL)。不同云厂商对ACL的支持和实现方式有所不同,
// 因此根据具体的云服务提供商,你可能需要进行不同的配置(自行开启,阿里云有acl权限配置,腾讯云没有acl权限配置)
//.acl(getAccessPolicy().getObjectCannedACL())
- .build())
- .build());
+ .build()
+ );
+ if (log.isDebugEnabled()) {
+ x.addTransferListener(LoggingTransferListener.create());
+ }
+ }
+ );
// 将输入流写入请求体
body.writeInputStream(inputStream);
@@ -229,13 +238,17 @@ public class OssClient {
Path tempFilePath = FileUtils.createTempFile().toPath();
// 使用 S3TransferManager 下载文件
FileDownload downloadFile = transferManager.downloadFile(
- x -> x.getObjectRequest(
+ x -> {
+ x.destination(tempFilePath).getObjectRequest(
y -> y.bucket(properties.getBucketName())
.key(removeBaseUrl(path))
- .build())
- .addTransferListener(LoggingTransferListener.create())
- .destination(tempFilePath)
- .build());
+ .build()
+ );
+ if (log.isDebugEnabled()) {
+ x.addTransferListener(LoggingTransferListener.create());
+ }
+ }
+ );
// 等待文件下载操作完成
downloadFile.completionFuture().join();
return tempFilePath;
@@ -244,8 +257,8 @@ public class OssClient {
/**
* 下载文件从 Amazon S3 到 输出流
*
- * @param key 文件在 Amazon S3 中的对象键
- * @param out 输出流
+ * @param key 文件在 Amazon S3 中的对象键
+ * @param out 输出流
* @param consumer 自定义处理逻辑
* @throws OssException 如果下载失败,抛出自定义异常
*/
@@ -260,26 +273,24 @@ public class OssClient {
/**
* 下载文件从 Amazon S3 到 输出流
*
- * @param key 文件在 Amazon S3 中的对象键
+ * @param key 文件在 Amazon S3 中的对象键
* @param contentLengthConsumer 文件大小消费者函数
* @return 写出订阅器
* @throws OssException 如果下载失败,抛出自定义异常
*/
public WriteOutSubscriber download(String key, Consumer contentLengthConsumer) {
try {
- // 构建下载请求
- DownloadRequest> publisherDownloadRequest = DownloadRequest.builder()
- // 文件对象
- .getObjectRequest(y -> y.bucket(properties.getBucketName())
- .key(key)
- .build())
- .addTransferListener(LoggingTransferListener.create())
+ DownloadRequest.TypedBuilder> typedBuilder = DownloadRequest.builder()
// 使用发布订阅转换器
.responseTransformer(AsyncResponseTransformer.toPublisher())
- .build();
+ // 文件对象
+ .getObjectRequest(y -> y.bucket(properties.getBucketName()).key(key).build());
+ if (log.isDebugEnabled()) {
+ typedBuilder.addTransferListener(LoggingTransferListener.create());
+ }
// 使用 S3TransferManager 下载文件
- Download> publisherDownload = transferManager.download(publisherDownloadRequest);
+ Download> publisherDownload = transferManager.download(typedBuilder.build());
// 获取下载发布订阅转换器
ResponsePublisher publisher = publisherDownload.completionFuture().join().result();
// 执行文件大小消费者函数
@@ -289,7 +300,7 @@ public class OssClient {
// 构建写出订阅器对象
return out -> {
// 创建可写入的字节通道
- try(WritableByteChannel channel = Channels.newChannel(out)){
+ try (WritableByteChannel channel = Channels.newChannel(out)) {
// 订阅数据
publisher.subscribe(byteBuffer -> {
while (byteBuffer.hasRemaining()) {
@@ -347,7 +358,7 @@ public class OssClient {
*
* @param objectKey 对象KEY
* @param expiredTime 链接授权到期时间
- * @param metadata 元数据
+ * @param metadata 元数据
*/
public String createPresignedPutUrl(String objectKey, Duration expiredTime, Map metadata) {
// 使用 AWS S3 预签名 URL 的生成器 获取上传文件对象的预签名 URL
From 2b8f4e1d2c9ed6d14aad84d3d05c4ffd369509b7 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, 6 Jan 2026 17:22:44 +0800
Subject: [PATCH 03/20] =?UTF-8?q?update=20=E4=B8=8B=E6=9E=B6=E8=BF=87?=
=?UTF-8?q?=E6=9C=9F=E7=9A=84=E8=B5=9E=E5=8A=A9=E5=95=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/README.md b/README.md
index 457f0a0b5..8786e423e 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,6 @@ MaxKey 业界领先单点登录产品 - https://gitee.com/dromara/MaxKey
CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow
数舵科技 软件定制开发APP小程序等 - http://www.shuduokeji.com/
引迈信息 软件开发平台 - https://www.jnpfsoft.com/index.html?from=plus-doc
-**启山商城系统 多租户商城源码可免费商用可二次开发 - https://www.73app.cn/**
Mall4J 高质量Java商城系统 - https://www.mall4j.com/cn/?statId=11
aizuda flowlong 工作流 - https://gitee.com/aizuda/flowlong
Ruoyi-Plus-Uniapp - https://ruoyi.plus
From bbc684b33518945472b09796554b0a896967e8b1 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, 6 Jan 2026 17:26:45 +0800
Subject: [PATCH 04/20] =?UTF-8?q?update=20=E5=88=A0=E9=99=A4=E5=B7=B2?=
=?UTF-8?q?=E7=BB=8F=E8=BF=87=E6=9C=9F=E7=9A=84=E9=85=8D=E7=BD=AE=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../common/register/ServerRegister.java | 146 ------------------
1 file changed, 146 deletions(-)
delete mode 100644 ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/common/register/ServerRegister.java
diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/common/register/ServerRegister.java b/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/common/register/ServerRegister.java
deleted file mode 100644
index 2a8a47aa4..000000000
--- a/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/common/register/ServerRegister.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package com.aizuda.snailjob.server.common.register;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.IdUtil;
-import cn.hutool.core.util.StrUtil;
-import com.aizuda.snailjob.common.core.enums.NodeTypeEnum;
-import com.aizuda.snailjob.common.core.util.JsonUtil;
-import com.aizuda.snailjob.common.core.util.NetUtil;
-import com.aizuda.snailjob.common.core.util.SnailJobVersion;
-import com.aizuda.snailjob.common.core.util.StreamUtils;
-import com.aizuda.snailjob.common.log.SnailJobLog;
-import com.aizuda.snailjob.server.common.cache.CacheConsumerGroup;
-import com.aizuda.snailjob.server.common.config.SystemProperties;
-import com.aizuda.snailjob.server.common.convert.RegisterNodeInfoConverter;
-import com.aizuda.snailjob.server.common.dto.ServerNodeExtAttrs;
-import com.aizuda.snailjob.server.common.handler.InstanceManager;
-import com.aizuda.snailjob.template.datasource.persistence.po.ServerNode;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.google.common.collect.Lists;
-import lombok.RequiredArgsConstructor;
-import org.springframework.boot.autoconfigure.web.ServerProperties;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDateTime;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 服务端注册
- *
- * @author opensnail
- * @date 2023-06-07
- * @since 1.6.0
- */
-@Component(ServerRegister.BEAN_NAME)
-@RequiredArgsConstructor
-public class ServerRegister extends AbstractRegister {
- public static final String BEAN_NAME = "serverRegister";
- private final ScheduledExecutorService serverRegisterNode = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "server-register-node"));
- public static final int DELAY_TIME = 30;
- public static final String CURRENT_CID;
- public static final String GROUP_NAME = "DEFAULT_SERVER";
- public static final String NAMESPACE_ID = "DEFAULT_SERVER_NAMESPACE_ID";
- private final InstanceManager instanceManager;
- private final SystemProperties systemProperties;
- private final ServerProperties serverProperties;
-
- static {
- CURRENT_CID = IdUtil.getSnowflakeNextIdStr();
- }
-
- @Override
- public boolean supports(int type) {
- return getNodeType().equals(type);
- }
-
- @Override
- protected void beforeProcessor(RegisterContext context) {
- // 新增扩展参数
- ServerNodeExtAttrs serverNodeExtAttrs = new ServerNodeExtAttrs();
- serverNodeExtAttrs.setWebPort(serverProperties.getPort());
- serverNodeExtAttrs.setSystemVersion(SnailJobVersion.getVersion());
-
- context.setGroupName(GROUP_NAME);
- context.setHostId(CURRENT_CID);
- String serverHost = systemProperties.getServerHost();
- if (StrUtil.isEmptyIfStr(serverHost)) {
- serverHost = NetUtil.getLocalIpStr();
- }
- context.setHostIp(serverHost);
- context.setHostPort(systemProperties.getServerPort());
- context.setContextPath(Optional.ofNullable(serverProperties.getServlet().getContextPath()).orElse(StrUtil.EMPTY));
- context.setNamespaceId(NAMESPACE_ID);
- context.setExtAttrs(JsonUtil.toJsonString(serverNodeExtAttrs));
- }
-
- @Override
- protected LocalDateTime getExpireAt() {
- return LocalDateTime.now().plusSeconds(DELAY_TIME);
- }
-
- @Override
- protected boolean doRegister(RegisterContext context, ServerNode serverNode) {
- refreshExpireAt(Lists.newArrayList(serverNode));
- return Boolean.TRUE;
- }
-
-
- @Override
- protected void afterProcessor(final ServerNode serverNode) {
- try {
- // 同步当前POD消费的组的节点信息
- // netty的client只会注册到一个服务端,若组分配的和client连接的不是一个POD则会导致当前POD没有其他客户端的注册信息
- ConcurrentMap/*namespaceId*/> allConsumerGroupName = CacheConsumerGroup.getAllConsumerGroupName();
- if (CollUtil.isNotEmpty(allConsumerGroupName)) {
- Set namespaceIdSets = StreamUtils.toSetByFlatMap(allConsumerGroupName.values(), Set::stream);
- if (CollUtil.isEmpty(namespaceIdSets)) {
- return;
- }
-
- List serverNodes = serverNodeMapper.selectList(
- new LambdaQueryWrapper()
- .eq(ServerNode::getNodeType, NodeTypeEnum.CLIENT.getType())
- .in(ServerNode::getNamespaceId, namespaceIdSets)
- .in(ServerNode::getGroupName, allConsumerGroupName.keySet()));
- for (final ServerNode node : serverNodes) {
- // 刷新全量本地缓存
- instanceManager.registerOrUpdate(RegisterNodeInfoConverter.INSTANCE.toRegisterNodeInfo(node));
- // 刷新过期时间
- CacheConsumerGroup.addOrUpdate(node.getGroupName(), node.getNamespaceId());
- }
- }
- } catch (Exception e) {
- SnailJobLog.LOCAL.error("Client refresh failed", e);
- }
- }
-
- @Override
- protected Integer getNodeType() {
- return NodeTypeEnum.SERVER.getType();
- }
-
- @Override
- public void start() {
- SnailJobLog.LOCAL.info("ServerRegister start");
-
- serverRegisterNode.scheduleAtFixedRate(() -> {
- try {
- this.register(new RegisterContext());
- } catch (Exception e) {
- SnailJobLog.LOCAL.error("Server-side registration failed", e);
- }
- }, 0, DELAY_TIME * 2 / 3, TimeUnit.SECONDS);
-
- }
-
- @Override
- public void close() {
- SnailJobLog.LOCAL.info("ServerRegister close");
- }
-}
From 1a14bdf256bfe4323946452741997bff1309b9f1 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, 9 Jan 2026 11:50:28 +0800
Subject: [PATCH 05/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E7=BB=9F?=
=?UTF-8?q?=E4=B8=80=E7=94=A8=E8=AF=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/resources/i18n/messages.properties | 2 +-
.../resources/i18n/messages_zh_CN.properties | 2 +-
.../common/core/constant/CacheConstants.java | 2 +-
.../common/core/constant/CacheNames.java | 2 +-
.../common/core/service/UserService.java | 8 ++---
.../dromara/common/mail/utils/MailUtils.java | 30 +++++++++----------
.../common/satoken/utils/LoginHelper.java | 2 +-
.../monitor/SysLogininforController.java | 2 +-
.../service/impl/SysUserServiceImpl.java | 12 ++++----
script/sql/oracle/oracle_ry_vue_5.X.sql | 2 +-
script/sql/postgres/postgres_ry_vue_5.X.sql | 2 +-
script/sql/ry_vue_5.X.sql | 2 +-
script/sql/sqlserver/sqlserver_ry_vue_5.X.sql | 2 +-
13 files changed, 35 insertions(+), 35 deletions(-)
diff --git a/ruoyi-admin/src/main/resources/i18n/messages.properties b/ruoyi-admin/src/main/resources/i18n/messages.properties
index f2777f77b..cc02929ef 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages.properties
@@ -13,7 +13,7 @@ user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=用户名不能为空
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
-user.username.length.valid=账户长度必须在{min}到{max}个字符之间
+user.username.length.valid=帐户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符
diff --git a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
index f2777f77b..cc02929ef 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
@@ -13,7 +13,7 @@ user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=用户名不能为空
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
-user.username.length.valid=账户长度必须在{min}到{max}个字符之间
+user.username.length.valid=帐户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
index ceb837044..ff590cf22 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
@@ -23,7 +23,7 @@ public interface CacheConstants {
String SYS_DICT_KEY = "sys_dict:";
/**
- * 登录账户密码错误次数 redis key
+ * 登录帐户密码错误次数 redis key
*/
String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
index c38f39b47..dd9c750ca 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
@@ -47,7 +47,7 @@ public interface CacheNames {
String SYS_CLIENT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_client#30d";
/**
- * 用户账户
+ * 用户帐户
*/
String SYS_USER_NAME = "sys_user_name#30d";
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
index eefeef011..10108d011 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
@@ -13,15 +13,15 @@ import java.util.Map;
public interface UserService {
/**
- * 通过用户ID查询用户账户
+ * 通过用户ID查询用户帐户
*
* @param userId 用户ID
- * @return 用户账户
+ * @return 用户帐户
*/
String selectUserNameById(Long userId);
/**
- * 通过用户ID查询用户账户
+ * 通过用户ID查询用户帐户
*
* @param userId 用户ID
* @return 用户名称
@@ -29,7 +29,7 @@ public interface UserService {
String selectNicknameById(Long userId);
/**
- * 通过用户ID查询用户账户
+ * 通过用户ID查询用户帐户
*
* @param userIds 用户ID 多个用逗号隔开
* @return 用户名称
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
index a28701fbc..918b42b57 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
@@ -51,7 +51,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送文本邮件,发送给单个或多个收件人
+ * 使用配置文件中设置的帐户发送文本邮件,发送给单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -66,7 +66,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 使用配置文件中设置的帐户发送HTML邮件,发送给单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -81,7 +81,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -96,7 +96,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
* 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
@@ -114,7 +114,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送文本邮件,发送给多人
+ * 使用配置文件中设置的帐户发送文本邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -127,7 +127,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送HTML邮件,发送给多人
+ * 使用配置文件中设置的帐户发送HTML邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -141,7 +141,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送给多人
+ * 使用配置文件中设置的帐户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -155,7 +155,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送给多人
+ * 使用配置文件中设置的帐户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param ccs 抄送人列表,可以为null或空
@@ -223,7 +223,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
+ * 使用配置文件中设置的帐户发送HTML邮件,发送给单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -239,7 +239,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -255,7 +255,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
* 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
@@ -274,7 +274,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送HTML邮件,发送给多人
+ * 使用配置文件中设置的帐户发送HTML邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -289,7 +289,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送给多人
+ * 使用配置文件中设置的帐户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -304,7 +304,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的账户发送邮件,发送给多人
+ * 使用配置文件中设置的帐户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param ccs 抄送人列表,可以为null或空
@@ -380,7 +380,7 @@ public class MailUtils {
/**
* 根据配置文件,获取邮件客户端会话
*
- * @param mailAccount 邮件账户配置
+ * @param mailAccount 邮件帐户配置
* @param isSingleton 是否单例(全局共享会话)
* @return {@link Session}
* @since 5.5.7
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
index 730bae29d..ad3915ddc 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
@@ -99,7 +99,7 @@ public class LoginHelper {
}
/**
- * 获取用户账户
+ * 获取用户帐户
*/
public static String getUsername() {
return Convert.toStr(getExtra(USER_NAME_KEY));
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
index 378717003..ef871c90f 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
@@ -79,7 +79,7 @@ public class SysLogininforController extends BaseController {
}
@SaCheckPermission("monitor:logininfor:unlock")
- @Log(title = "账户解锁", businessType = BusinessType.OTHER)
+ @Log(title = "帐户解锁", businessType = BusinessType.OTHER)
@RepeatSubmit()
@GetMapping("/unlock/{userName}")
public R unlock(@PathVariable("userName") String userName) {
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
index aafc73e29..c16cd9add 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
@@ -580,10 +580,10 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
}
/**
- * 通过用户ID查询用户账户
+ * 通过用户ID查询用户帐户
*
* @param userId 用户ID
- * @return 用户账户
+ * @return 用户帐户
*/
@Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
@Override
@@ -594,10 +594,10 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
}
/**
- * 通过用户ID查询用户账户
+ * 通过用户ID查询用户帐户
*
* @param userId 用户ID
- * @return 用户账户
+ * @return 用户帐户
*/
@Override
@Cacheable(cacheNames = CacheNames.SYS_NICKNAME, key = "#userId")
@@ -608,10 +608,10 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
}
/**
- * 通过用户ID查询用户账户
+ * 通过用户ID查询用户帐户
*
* @param userIds 用户ID 多个用逗号隔开
- * @return 用户账户
+ * @return 用户帐户
*/
@Override
public String selectNicknameByIds(String userIds) {
diff --git a/script/sql/oracle/oracle_ry_vue_5.X.sql b/script/sql/oracle/oracle_ry_vue_5.X.sql
index 041e99a57..627f4d666 100644
--- a/script/sql/oracle/oracle_ry_vue_5.X.sql
+++ b/script/sql/oracle/oracle_ry_vue_5.X.sql
@@ -518,7 +518,7 @@ insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1,
insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1050', '帐户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate, null, null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 103, 1, sysdate, null, null, '');
diff --git a/script/sql/postgres/postgres_ry_vue_5.X.sql b/script/sql/postgres/postgres_ry_vue_5.X.sql
index b5da8e096..78c51d9e0 100644
--- a/script/sql/postgres/postgres_ry_vue_5.X.sql
+++ b/script/sql/postgres/postgres_ry_vue_5.X.sql
@@ -519,7 +519,7 @@ insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', '1'
insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:query', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:remove', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:export', '#', 103, 1, now(), null, null, '');
-insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1050', '帐户解锁', '501', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, now(), null, null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:query', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:batchLogout', '#', 103, 1, now(), null, null, '');
diff --git a/script/sql/ry_vue_5.X.sql b/script/sql/ry_vue_5.X.sql
index dae47920d..4b172e91f 100644
--- a/script/sql/ry_vue_5.X.sql
+++ b/script/sql/ry_vue_5.X.sql
@@ -353,7 +353,7 @@ insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1,
insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1050', '帐户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate(), null, null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 103, 1, sysdate(), null, null, '');
diff --git a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
index 5db798848..a602122f5 100644
--- a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
+++ b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
@@ -1801,7 +1801,7 @@ INSERT sys_menu VALUES (1044, N'登录删除', 501, 2, N'#', N'', N'', 1, 0, N'F
GO
INSERT sys_menu VALUES (1045, N'日志导出', 501, 3, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:logininfor:export', N'#', 103, 1, getdate(), NULL, NULL, N'')
GO
-INSERT sys_menu VALUES (1050, N'账户解锁', 501, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:logininfor:unlock', N'#', 103, 1, getdate(), NULL, NULL, N'')
+INSERT sys_menu VALUES (1050, N'帐户解锁', 501, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:logininfor:unlock', N'#', 103, 1, getdate(), NULL, NULL, N'')
GO
INSERT sys_menu VALUES (1046, N'在线查询', 109, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:online:query', N'#', 103, 1, getdate(), NULL, NULL, N'')
GO
From 948eba656608eec0d1a9ddbb836612d5281f5142 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, 9 Jan 2026 13:19:21 +0800
Subject: [PATCH 06/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E8=8F=9C=E5=8D=95=E8=B7=AF=E7=94=B1=E5=9C=B0=E5=9D=80?=
=?UTF-8?q?=E5=92=8C=E5=90=8D=E7=A7=B0=E7=9A=84=E6=A0=A1=E9=AA=8C=E8=A7=84?=
=?UTF-8?q?=E5=88=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../controller/system/SysMenuController.java | 4 ++
.../org/dromara/system/domain/SysMenu.java | 10 ++--
.../system/service/ISysMenuService.java | 9 ++++
.../service/impl/SysMenuServiceImpl.java | 47 ++++++++++++++++++-
4 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
index d1b5b9bd5..9d95880e8 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
@@ -137,6 +137,8 @@ public class SysMenuController extends BaseController {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
} else if (SystemConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
return R.fail("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
+ } else if (!menuService.checkRouteConfigUnique(menu)) {
+ return R.fail("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
}
return toAjax(menuService.insertMenu(menu));
}
@@ -156,6 +158,8 @@ public class SysMenuController extends BaseController {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
} else if (menu.getMenuId().equals(menu.getParentId())) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
+ } else if (!menuService.checkRouteConfigUnique(menu)) {
+ return R.fail("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
}
return toAjax(menuService.updateMenu(menu));
}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java
index 2df55962b..5fe0de585 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysMenu.java
@@ -130,11 +130,11 @@ public class SysMenu extends BaseEntity {
public String getRouterPath() {
String routerPath = this.path;
// 内链打开外网方式
- if (getParentId() != 0L && isInnerLink()) {
+ if (!Constants.TOP_PARENT_ID.equals(getParentId()) && isInnerLink()) {
routerPath = innerLinkReplaceEach(routerPath);
}
// 非外链并且是一级目录(类型为目录)
- if (0L == getParentId() && SystemConstants.TYPE_DIR.equals(getMenuType())
+ if (Constants.TOP_PARENT_ID.equals(getParentId()) && SystemConstants.TYPE_DIR.equals(getMenuType())
&& SystemConstants.NO_FRAME.equals(getIsFrame())) {
routerPath = "/" + this.path;
}
@@ -152,7 +152,7 @@ public class SysMenu extends BaseEntity {
String component = SystemConstants.LAYOUT;
if (StringUtils.isNotEmpty(this.component) && !isMenuFrame()) {
component = this.component;
- } else if (StringUtils.isEmpty(this.component) && getParentId() != 0L && isInnerLink()) {
+ } else if (StringUtils.isEmpty(this.component) && !Constants.TOP_PARENT_ID.equals(getParentId()) && isInnerLink()) {
component = SystemConstants.INNER_LINK;
} else if (StringUtils.isEmpty(this.component) && isParentView()) {
component = SystemConstants.PARENT_VIEW;
@@ -164,7 +164,7 @@ public class SysMenu extends BaseEntity {
* 是否为菜单内部跳转
*/
public boolean isMenuFrame() {
- return getParentId() == 0L && SystemConstants.TYPE_MENU.equals(menuType) && isFrame.equals(SystemConstants.NO_FRAME);
+ return Constants.TOP_PARENT_ID.equals(getParentId()) && SystemConstants.TYPE_MENU.equals(menuType) && isFrame.equals(SystemConstants.NO_FRAME);
}
/**
@@ -178,7 +178,7 @@ public class SysMenu extends BaseEntity {
* 是否为parent_view组件
*/
public boolean isParentView() {
- return getParentId() != 0L && SystemConstants.TYPE_DIR.equals(menuType);
+ return !Constants.TOP_PARENT_ID.equals(getParentId()) && SystemConstants.TYPE_DIR.equals(menuType);
}
/**
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java
index f972691be..8888c3c39 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysMenuService.java
@@ -160,4 +160,13 @@ public interface ISysMenuService {
* @return 结果
*/
boolean checkMenuNameUnique(SysMenuBo menu);
+
+ /**
+ * 校验路由组合是否唯一
+ *
+ * @param menu 菜单信息
+ * @return 结果
+ */
+ boolean checkRouteConfigUnique(SysMenuBo menu);
+
}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
index bbba6a01e..b048d2a81 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
@@ -6,6 +6,7 @@ import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.utils.MapstructUtils;
@@ -29,13 +30,17 @@ import org.dromara.system.service.ISysMenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
/**
* 菜单 业务层处理
*
* @author Lion Li
*/
+@Slf4j
@RequiredArgsConstructor
@Service
public class SysMenuServiceImpl implements ISysMenuService {
@@ -353,6 +358,46 @@ public class SysMenuServiceImpl implements ISysMenuService {
return !exist;
}
+ /**
+ * 校验路由名称是否唯一
+ *
+ * @param menuBo 菜单信息
+ * @return 结果
+ */
+ @Override
+ public boolean checkRouteConfigUnique(SysMenuBo menuBo) {
+ SysMenu menu = MapstructUtils.convert(menuBo, SysMenu.class);
+ long menuId = ObjectUtil.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
+ Long parentId = menu.getParentId();
+ String path = menu.getPath();
+ String routeName = StringUtils.isEmpty(menu.getRouteName()) ? path : menu.getRouteName();
+ List sysMenuList = baseMapper.selectList(
+ new LambdaQueryWrapper()
+ .in(SysMenu::getMenuType, SystemConstants.TYPE_DIR, SystemConstants.TYPE_MENU)
+ .and(w ->
+ w.eq(SysMenu::getPath, path)
+ .or().eq(SysMenu::getRouteName, path)
+ .or().eq(SysMenu::getRouteName, routeName)));
+ for (SysMenu sysMenu : sysMenuList) {
+ if (sysMenu.getMenuId() != menuId) {
+ Long dbParentId = sysMenu.getParentId();
+ String dbPath = sysMenu.getPath();
+ String dbRouteName = StringUtils.isEmpty(sysMenu.getRouteName()) ? dbPath : sysMenu.getRouteName();
+ if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == dbParentId.longValue()) {
+ log.warn("[同级路由冲突] 同级下已存在相同路由路径 '{}',冲突菜单:{}", dbPath, sysMenu.getMenuName());
+ return false;
+ } else if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == Constants.TOP_PARENT_ID) {
+ log.warn("[根目录路由冲突] 根目录下路由 '{}' 必须唯一,已被菜单 '{}' 占用", path, sysMenu.getMenuName());
+ return false;
+ } else if (StringUtils.equalsAnyIgnoreCase(routeName, dbRouteName)) {
+ log.warn("[路由名称冲突] 路由名称 '{}' 需全局唯一,已被菜单 '{}' 使用", routeName, sysMenu.getMenuName());
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
/**
* 根据父节点的ID获取所有子节点
*
From d8ed23f2270c22a191864a82641657784f91293f 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, 9 Jan 2026 17:10:51 +0800
Subject: [PATCH 07/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E8=8F=9C=E5=8D=95=E8=B7=AF=E7=94=B1=E5=9C=B0=E5=9D=80?=
=?UTF-8?q?=E5=92=8C=E5=90=8D=E7=A7=B0=E7=9A=84=E6=A0=A1=E9=AA=8C=E8=A7=84?=
=?UTF-8?q?=E5=88=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../org/dromara/system/service/impl/SysMenuServiceImpl.java | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
index b048d2a81..7a844812c 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
@@ -374,10 +374,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
List sysMenuList = baseMapper.selectList(
new LambdaQueryWrapper()
.in(SysMenu::getMenuType, SystemConstants.TYPE_DIR, SystemConstants.TYPE_MENU)
- .and(w ->
- w.eq(SysMenu::getPath, path)
- .or().eq(SysMenu::getRouteName, path)
- .or().eq(SysMenu::getRouteName, routeName)));
+ .eq(SysMenu::getPath, path));
for (SysMenu sysMenu : sysMenuList) {
if (sysMenu.getMenuId() != menuId) {
Long dbParentId = sysMenu.getParentId();
From 0940ba67621496a66c94564cb13e4cf026865daa 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, 12 Jan 2026 09:17:39 +0800
Subject: [PATCH 08/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E5=A4=A7?=
=?UTF-8?q?=E5=AE=B6=E9=83=BD=E8=AE=A4=E5=8F=AF=E7=94=A8"=E8=B4=A6"?=
=?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=94=B9=E4=B8=BA=E8=B4=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../main/resources/i18n/messages.properties | 8 ++--
.../resources/i18n/messages_zh_CN.properties | 8 ++--
.../common/core/constant/CacheConstants.java | 2 +-
.../common/core/constant/CacheNames.java | 2 +-
.../common/core/domain/dto/UserDTO.java | 2 +-
.../common/core/service/UserService.java | 8 ++--
.../dromara/common/mail/utils/MailUtils.java | 40 +++++++++----------
.../common/satoken/utils/LoginHelper.java | 2 +-
.../monitor/SysLogininforController.java | 2 +-
.../org/dromara/system/domain/SysUser.java | 2 +-
.../dromara/system/domain/bo/SysUserBo.java | 2 +-
.../system/domain/vo/SysUserExportVo.java | 4 +-
.../system/domain/vo/SysUserImportVo.java | 4 +-
.../dromara/system/domain/vo/SysUserVo.java | 2 +-
.../system/service/ISysUserService.java | 2 +-
.../service/impl/SysUserServiceImpl.java | 14 +++----
script/sql/oracle/oracle_ry_vue_5.X.sql | 4 +-
script/sql/postgres/postgres_ry_vue_5.X.sql | 4 +-
script/sql/ry_vue_5.X.sql | 4 +-
script/sql/sqlserver/sqlserver_ry_vue_5.X.sql | 4 +-
20 files changed, 60 insertions(+), 60 deletions(-)
diff --git a/ruoyi-admin/src/main/resources/i18n/messages.properties b/ruoyi-admin/src/main/resources/i18n/messages.properties
index cc02929ef..e1e5263b8 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages.properties
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
-user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
+user.password.retry.limit.exceed=密码输入错误{0}次,账户锁定{1}分钟
user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=角色已封禁,请联系管理员
@@ -13,7 +13,7 @@ user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=用户名不能为空
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
-user.username.length.valid=帐户长度必须在{min}到{max}个字符之间
+user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符
@@ -47,10 +47,10 @@ repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=短信验证码输入错误{0}次
-sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟
+sms.code.retry.limit.exceed=短信验证码输入错误{0}次,账户锁定{1}分钟
email.code.not.blank=邮箱验证码不能为空
email.code.retry.limit.count=邮箱验证码输入错误{0}次
-email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
+email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,账户锁定{1}分钟
xcx.code.not.blank=小程序[code]不能为空
social.source.not.blank=第三方登录平台[source]不能为空
social.code.not.blank=第三方登录平台[code]不能为空
diff --git a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
index cc02929ef..e1e5263b8 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
@@ -5,7 +5,7 @@ user.jcaptcha.expire=验证码已失效
user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次
-user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
+user.password.retry.limit.exceed=密码输入错误{0}次,账户锁定{1}分钟
user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=角色已封禁,请联系管理员
@@ -13,7 +13,7 @@ user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=用户名不能为空
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
-user.username.length.valid=帐户长度必须在{min}到{max}个字符之间
+user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=用户密码不能为空
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50个字符
@@ -47,10 +47,10 @@ repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=短信验证码输入错误{0}次
-sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}分钟
+sms.code.retry.limit.exceed=短信验证码输入错误{0}次,账户锁定{1}分钟
email.code.not.blank=邮箱验证码不能为空
email.code.retry.limit.count=邮箱验证码输入错误{0}次
-email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
+email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,账户锁定{1}分钟
xcx.code.not.blank=小程序[code]不能为空
social.source.not.blank=第三方登录平台[source]不能为空
social.code.not.blank=第三方登录平台[code]不能为空
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
index ff590cf22..ceb837044 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java
@@ -23,7 +23,7 @@ public interface CacheConstants {
String SYS_DICT_KEY = "sys_dict:";
/**
- * 登录帐户密码错误次数 redis key
+ * 登录账户密码错误次数 redis key
*/
String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
index dd9c750ca..c38f39b47 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java
@@ -47,7 +47,7 @@ public interface CacheNames {
String SYS_CLIENT = GlobalConstants.GLOBAL_REDIS_KEY + "sys_client#30d";
/**
- * 用户帐户
+ * 用户账户
*/
String SYS_USER_NAME = "sys_user_name#30d";
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserDTO.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserDTO.java
index cb5def9a9..393a0f0de 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserDTO.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/dto/UserDTO.java
@@ -61,7 +61,7 @@ public class UserDTO implements Serializable {
private String sex;
/**
- * 帐号状态(0正常 1停用)
+ * 账号状态(0正常 1停用)
*/
private String status;
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
index 10108d011..eefeef011 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java
@@ -13,15 +13,15 @@ import java.util.Map;
public interface UserService {
/**
- * 通过用户ID查询用户帐户
+ * 通过用户ID查询用户账户
*
* @param userId 用户ID
- * @return 用户帐户
+ * @return 用户账户
*/
String selectUserNameById(Long userId);
/**
- * 通过用户ID查询用户帐户
+ * 通过用户ID查询用户账户
*
* @param userId 用户ID
* @return 用户名称
@@ -29,7 +29,7 @@ public interface UserService {
String selectNicknameById(Long userId);
/**
- * 通过用户ID查询用户帐户
+ * 通过用户ID查询用户账户
*
* @param userIds 用户ID 多个用逗号隔开
* @return 用户名称
diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
index 918b42b57..793c0241c 100644
--- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
+++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java
@@ -51,7 +51,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送文本邮件,发送给单个或多个收件人
+ * 使用配置文件中设置的账户发送文本邮件,发送给单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -66,7 +66,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送HTML邮件,发送给单个或多个收件人
+ * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -81,7 +81,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -96,7 +96,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
* 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
@@ -114,7 +114,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送文本邮件,发送给多人
+ * 使用配置文件中设置的账户发送文本邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -127,7 +127,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送HTML邮件,发送给多人
+ * 使用配置文件中设置的账户发送HTML邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -141,7 +141,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送给多人
+ * 使用配置文件中设置的账户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -155,7 +155,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送给多人
+ * 使用配置文件中设置的账户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param ccs 抄送人列表,可以为null或空
@@ -192,7 +192,7 @@ public class MailUtils {
/**
* 发送邮件给多人
*
- * @param mailAccount 邮件帐户信息
+ * @param mailAccount 邮件账户信息
* @param tos 收件人列表
* @param subject 标题
* @param content 正文
@@ -207,7 +207,7 @@ public class MailUtils {
/**
* 发送邮件给多人
*
- * @param mailAccount 邮件帐户信息
+ * @param mailAccount 邮件账户信息
* @param tos 收件人列表
* @param ccs 抄送人列表,可以为null或空
* @param bccs 密送人列表,可以为null或空
@@ -223,7 +223,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送HTML邮件,发送给单个或多个收件人
+ * 使用配置文件中设置的账户发送HTML邮件,发送给单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -239,7 +239,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
* 多个收件人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人
@@ -255,7 +255,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送单个或多个收件人
+ * 使用配置文件中设置的账户发送邮件,发送单个或多个收件人
* 多个收件人、抄送人、密送人可以使用逗号“,”分隔,也可以通过分号“;”分隔
*
* @param to 收件人,可以使用逗号“,”分隔,也可以通过分号“;”分隔
@@ -274,7 +274,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送HTML邮件,发送给多人
+ * 使用配置文件中设置的账户发送HTML邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -289,7 +289,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送给多人
+ * 使用配置文件中设置的账户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param subject 标题
@@ -304,7 +304,7 @@ public class MailUtils {
}
/**
- * 使用配置文件中设置的帐户发送邮件,发送给多人
+ * 使用配置文件中设置的账户发送邮件,发送给多人
*
* @param tos 收件人列表
* @param ccs 抄送人列表,可以为null或空
@@ -343,7 +343,7 @@ public class MailUtils {
/**
* 发送邮件给多人
*
- * @param mailAccount 邮件帐户信息
+ * @param mailAccount 邮件账户信息
* @param tos 收件人列表
* @param subject 标题
* @param content 正文
@@ -360,7 +360,7 @@ public class MailUtils {
/**
* 发送邮件给多人
*
- * @param mailAccount 邮件帐户信息
+ * @param mailAccount 邮件账户信息
* @param tos 收件人列表
* @param ccs 抄送人列表,可以为null或空
* @param bccs 密送人列表,可以为null或空
@@ -380,7 +380,7 @@ public class MailUtils {
/**
* 根据配置文件,获取邮件客户端会话
*
- * @param mailAccount 邮件帐户配置
+ * @param mailAccount 邮件账户配置
* @param isSingleton 是否单例(全局共享会话)
* @return {@link Session}
* @since 5.5.7
@@ -400,7 +400,7 @@ public class MailUtils {
/**
* 发送邮件给多人
*
- * @param mailAccount 邮件帐户信息
+ * @param mailAccount 邮件账户信息
* @param useGlobalSession 是否全局共享Session
* @param tos 收件人列表
* @param ccs 抄送人列表,可以为null或空
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
index ad3915ddc..730bae29d 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java
@@ -99,7 +99,7 @@ public class LoginHelper {
}
/**
- * 获取用户帐户
+ * 获取用户账户
*/
public static String getUsername() {
return Convert.toStr(getExtra(USER_NAME_KEY));
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
index ef871c90f..378717003 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java
@@ -79,7 +79,7 @@ public class SysLogininforController extends BaseController {
}
@SaCheckPermission("monitor:logininfor:unlock")
- @Log(title = "帐户解锁", businessType = BusinessType.OTHER)
+ @Log(title = "账户解锁", businessType = BusinessType.OTHER)
@RepeatSubmit()
@GetMapping("/unlock/{userName}")
public R unlock(@PathVariable("userName") String userName) {
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java
index 3712f805f..a06172f66 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java
@@ -78,7 +78,7 @@ public class SysUser extends TenantEntity {
private String password;
/**
- * 帐号状态(0正常 1停用)
+ * 账号状态(0正常 1停用)
*/
private String status;
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
index 1472d2428..11c01666d 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
@@ -78,7 +78,7 @@ public class SysUserBo extends BaseEntity {
private String password;
/**
- * 帐号状态(0正常 1停用)
+ * 账号状态(0正常 1停用)
*/
private String status;
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java
index 913ab2001..c60087202 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserExportVo.java
@@ -63,9 +63,9 @@ public class SysUserExportVo implements Serializable {
private String sex;
/**
- * 帐号状态(0正常 1停用)
+ * 账号状态(0正常 1停用)
*/
- @ExcelProperty(value = "帐号状态", converter = ExcelDictConvert.class)
+ @ExcelProperty(value = "账号状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_normal_disable")
private String status;
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java
index d4e575c14..4507f631e 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserImportVo.java
@@ -67,9 +67,9 @@ public class SysUserImportVo implements Serializable {
private String sex;
/**
- * 帐号状态(0正常 1停用)
+ * 账号状态(0正常 1停用)
*/
- @ExcelProperty(value = "帐号状态", converter = ExcelDictConvert.class)
+ @ExcelProperty(value = "账号状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_normal_disable")
private String status;
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java
index 86249d20e..755dcf81d 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java
@@ -89,7 +89,7 @@ public class SysUserVo implements Serializable {
private String password;
/**
- * 帐号状态(0正常 1停用)
+ * 账号状态(0正常 1停用)
*/
private String status;
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
index 1fe554547..9e255f992 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
@@ -174,7 +174,7 @@ public interface ISysUserService {
* 修改用户状态
*
* @param userId 用户ID
- * @param status 帐号状态
+ * @param status 账号状态
* @return 结果
*/
int updateUserStatus(Long userId, String status);
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
index c16cd9add..39ad4cb91 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java
@@ -375,7 +375,7 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
* 修改用户状态
*
* @param userId 用户ID
- * @param status 帐号状态
+ * @param status 账号状态
* @return 结果
*/
@Override
@@ -580,10 +580,10 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
}
/**
- * 通过用户ID查询用户帐户
+ * 通过用户ID查询用户账户
*
* @param userId 用户ID
- * @return 用户帐户
+ * @return 用户账户
*/
@Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
@Override
@@ -594,10 +594,10 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
}
/**
- * 通过用户ID查询用户帐户
+ * 通过用户ID查询用户账户
*
* @param userId 用户ID
- * @return 用户帐户
+ * @return 用户账户
*/
@Override
@Cacheable(cacheNames = CacheNames.SYS_NICKNAME, key = "#userId")
@@ -608,10 +608,10 @@ public class SysUserServiceImpl implements ISysUserService, UserService {
}
/**
- * 通过用户ID查询用户帐户
+ * 通过用户ID查询用户账户
*
* @param userIds 用户ID 多个用逗号隔开
- * @return 用户帐户
+ * @return 用户账户
*/
@Override
public String selectNicknameByIds(String userIds) {
diff --git a/script/sql/oracle/oracle_ry_vue_5.X.sql b/script/sql/oracle/oracle_ry_vue_5.X.sql
index 627f4d666..3a9cef456 100644
--- a/script/sql/oracle/oracle_ry_vue_5.X.sql
+++ b/script/sql/oracle/oracle_ry_vue_5.X.sql
@@ -257,7 +257,7 @@ comment on column sys_user.phonenumber is '手机号码';
comment on column sys_user.sex is '用户性别(0男 1女 2未知)';
comment on column sys_user.avatar is '头像路径';
comment on column sys_user.password is '密码';
-comment on column sys_user.status is '帐号状态(0正常 1停用)';
+comment on column sys_user.status is '账号状态(0正常 1停用)';
comment on column sys_user.del_flag is '删除标志(0代表存在 1代表删除)';
comment on column sys_user.login_ip is '最后登录IP';
comment on column sys_user.login_date is '最后登录时间';
@@ -518,7 +518,7 @@ insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1,
insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values('1050', '帐户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate, null, null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 103, 1, sysdate, null, null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 103, 1, sysdate, null, null, '');
diff --git a/script/sql/postgres/postgres_ry_vue_5.X.sql b/script/sql/postgres/postgres_ry_vue_5.X.sql
index 78c51d9e0..bb127f9e2 100644
--- a/script/sql/postgres/postgres_ry_vue_5.X.sql
+++ b/script/sql/postgres/postgres_ry_vue_5.X.sql
@@ -258,7 +258,7 @@ comment on column sys_user.phonenumber is '手机号码';
comment on column sys_user.sex is '用户性别(0男 1女 2未知)';
comment on column sys_user.avatar is '头像地址';
comment on column sys_user.password is '密码';
-comment on column sys_user.status is '帐号状态(0正常 1停用)';
+comment on column sys_user.status is '账号状态(0正常 1停用)';
comment on column sys_user.del_flag is '删除标志(0代表存在 1代表删除)';
comment on column sys_user.login_ip is '最后登陆IP';
comment on column sys_user.login_date is '最后登陆时间';
@@ -519,7 +519,7 @@ insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', '1'
insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:query', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:remove', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:export', '#', 103, 1, now(), null, null, '');
-insert into sys_menu values('1050', '帐户解锁', '501', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, now(), null, null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:query', '#', 103, 1, now(), null, null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:online:batchLogout', '#', 103, 1, now(), null, null, '');
diff --git a/script/sql/ry_vue_5.X.sql b/script/sql/ry_vue_5.X.sql
index 4b172e91f..3cd642b0b 100644
--- a/script/sql/ry_vue_5.X.sql
+++ b/script/sql/ry_vue_5.X.sql
@@ -148,7 +148,7 @@ create table sys_user (
sex char(1) default '0' comment '用户性别(0男 1女 2未知)',
avatar bigint(20) comment '头像地址',
password varchar(100) default '' comment '密码',
- status char(1) default '0' comment '帐号状态(0正常 1停用)',
+ status char(1) default '0' comment '账号状态(0正常 1停用)',
del_flag char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
login_ip varchar(128) default '' comment '最后登录IP',
login_date datetime comment '最后登录时间',
@@ -353,7 +353,7 @@ insert into sys_menu values('1042', '日志导出', '500', '4', '#', '', '', 1,
insert into sys_menu values('1043', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1044', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1045', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values('1050', '帐户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 103, 1, sysdate(), null, null, '');
-- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 103, 1, sysdate(), null, null, '');
diff --git a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
index a602122f5..295cc8e36 100644
--- a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
+++ b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
@@ -1801,7 +1801,7 @@ INSERT sys_menu VALUES (1044, N'登录删除', 501, 2, N'#', N'', N'', 1, 0, N'F
GO
INSERT sys_menu VALUES (1045, N'日志导出', 501, 3, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:logininfor:export', N'#', 103, 1, getdate(), NULL, NULL, N'')
GO
-INSERT sys_menu VALUES (1050, N'帐户解锁', 501, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:logininfor:unlock', N'#', 103, 1, getdate(), NULL, NULL, N'')
+INSERT sys_menu VALUES (1050, N'账户解锁', 501, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:logininfor:unlock', N'#', 103, 1, getdate(), NULL, NULL, N'')
GO
INSERT sys_menu VALUES (1046, N'在线查询', 109, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'monitor:online:query', N'#', 103, 1, getdate(), NULL, NULL, N'')
GO
@@ -2802,7 +2802,7 @@ EXEC sys.sp_addextendedproperty
'COLUMN', N'password'
GO
EXEC sys.sp_addextendedproperty
- 'MS_Description', N'帐号状态(0正常 1停用)' ,
+ 'MS_Description', N'账号状态(0正常 1停用)' ,
'SCHEMA', N'dbo',
'TABLE', N'sys_user',
'COLUMN', N'status'
From 459e9caf14a3ca681d2282413908063a1b1870fc 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, 12 Jan 2026 09:21:01 +0800
Subject: [PATCH 09/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E5=85=BC?=
=?UTF-8?q?=E5=AE=B9path=E5=A4=A7=E5=86=99=E5=BC=80=E5=A4=B4=E6=90=9C?=
=?UTF-8?q?=E7=B4=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../org/dromara/system/service/impl/SysMenuServiceImpl.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
index 7a844812c..854c836d2 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
@@ -374,7 +374,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
List sysMenuList = baseMapper.selectList(
new LambdaQueryWrapper()
.in(SysMenu::getMenuType, SystemConstants.TYPE_DIR, SystemConstants.TYPE_MENU)
- .eq(SysMenu::getPath, path));
+ .eq(SysMenu::getPath, path).or().eq(SysMenu::getPath, routeName));
for (SysMenu sysMenu : sysMenuList) {
if (sysMenu.getMenuId() != menuId) {
Long dbParentId = sysMenu.getParentId();
From c5777c01c1ac9b5829918dd1ec56a9db71f10bec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BE=A1=E6=B0=91Coding?=
Date: Mon, 12 Jan 2026 06:01:54 +0000
Subject: [PATCH 10/20] =?UTF-8?q?!822=20fix:=20=E6=96=87=E6=A1=88=E9=94=99?=
=?UTF-8?q?=E8=AF=AF=20*=20fix:=20=E6=96=87=E6=A1=88=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../org/dromara/system/controller/system/SysMenuController.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
index 9d95880e8..7d0ca0068 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysMenuController.java
@@ -159,7 +159,7 @@ public class SysMenuController extends BaseController {
} else if (menu.getMenuId().equals(menu.getParentId())) {
return R.fail("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
} else if (!menuService.checkRouteConfigUnique(menu)) {
- return R.fail("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
+ return R.fail("修改菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
}
return toAjax(menuService.updateMenu(menu));
}
From 7f9e4e14f0013e85dc8a48d908e902986292ee2c 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: Wed, 14 Jan 2026 09:11:31 +0800
Subject: [PATCH 11/20] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E9=A1=B6?=
=?UTF-8?q?=E8=8A=82=E7=82=B9=E5=88=A4=E6=96=AD=E6=9D=A1=E4=BB=B6=E7=BC=BA?=
=?UTF-8?q?=E5=A4=B1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../org/dromara/system/service/impl/SysMenuServiceImpl.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
index 854c836d2..921f7e4b4 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
@@ -383,7 +383,9 @@ public class SysMenuServiceImpl implements ISysMenuService {
if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == dbParentId.longValue()) {
log.warn("[同级路由冲突] 同级下已存在相同路由路径 '{}',冲突菜单:{}", dbPath, sysMenu.getMenuName());
return false;
- } else if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == Constants.TOP_PARENT_ID) {
+ } else if (StringUtils.equalsAnyIgnoreCase(path, dbPath)
+ && parentId.longValue() == Constants.TOP_PARENT_ID
+ && dbParentId.longValue() == Constants.TOP_PARENT_ID) {
log.warn("[根目录路由冲突] 根目录下路由 '{}' 必须唯一,已被菜单 '{}' 占用", path, sysMenu.getMenuName());
return false;
} else if (StringUtils.equalsAnyIgnoreCase(routeName, dbRouteName)) {
From 2d4685ac5fe7f10cc4a067dbcee130e401a53f0e 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: Wed, 14 Jan 2026 16:38:17 +0800
Subject: [PATCH 12/20] =?UTF-8?q?update=20=E4=BF=AE=E6=94=B9=E9=AA=8C?=
=?UTF-8?q?=E8=AF=81=E7=A0=81=E9=BB=98=E8=AE=A4=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-admin/src/main/resources/application.yml | 2 +-
.../main/java/org/dromara/common/web/config/CaptchaConfig.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 866b8f1a2..3fc344e0b 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -26,7 +26,7 @@ captcha:
# 验证码类型 math 数组计算 char 字符验证
type: MATH
# line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
- category: CIRCLE
+ category: SHEAR
# 数字验证码位数
numberLength: 1
# 字符验证码长度
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
index 650517ed1..b7172e9b6 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
@@ -23,7 +23,7 @@ public class CaptchaConfig {
private static final int WIDTH = 160;
private static final int HEIGHT = 60;
- private static final Color BACKGROUND = Color.LIGHT_GRAY;
+ private static final Color BACKGROUND = Color.WHITE;
private static final Font FONT = new Font("Arial", Font.BOLD, 48);
/**
From 6f94095bb0d0cbd64066d5ea1b15a5072e1eaa6c 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: Wed, 14 Jan 2026 18:28:37 +0800
Subject: [PATCH 13/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20=E8=87=AA?=
=?UTF-8?q?=E8=A1=8C=E5=AE=9E=E7=8E=B0=E6=9B=B4=E6=BC=82=E4=BA=AE=E7=9A=84?=
=?UTF-8?q?=E9=AA=8C=E8=AF=81=E7=A0=81=E5=9B=BE=E6=A1=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../web/controller/CaptchaController.java | 21 +-
.../src/main/resources/application.yml | 4 +-
.../common/web/config/CaptchaConfig.java | 49 -----
.../config/properties/CaptchaProperties.java | 9 +-
.../common/web/core/WaveAndCircleCaptcha.java | 197 ++++++++++++++++++
.../common/web/enums/CaptchaCategory.java | 35 ----
.../dromara/common/web/enums/CaptchaType.java | 29 ---
7 files changed, 211 insertions(+), 133 deletions(-)
create mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/WaveAndCircleCaptcha.java
delete mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java
delete mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
index dcd04c5e1..2586addab 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java
@@ -1,8 +1,9 @@
package org.dromara.web.controller;
import cn.dev33.satoken.annotation.SaIgnore;
-import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.captcha.generator.MathGenerator;
+import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import jakarta.validation.constraints.NotBlank;
@@ -14,14 +15,13 @@ import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
-import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.mail.config.properties.MailProperties;
import org.dromara.common.mail.utils.MailUtils;
import org.dromara.common.ratelimiter.annotation.RateLimiter;
import org.dromara.common.ratelimiter.enums.LimitType;
import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.web.core.WaveAndCircleCaptcha;
import org.dromara.common.web.config.properties.CaptchaProperties;
-import org.dromara.common.web.enums.CaptchaType;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.api.entity.SmsResponse;
import org.dromara.sms4j.core.factory.SmsFactory;
@@ -33,6 +33,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.awt.*;
import java.time.Duration;
import java.util.LinkedHashMap;
@@ -130,19 +131,21 @@ public class CaptchaController {
String uuid = IdUtil.simpleUUID();
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + uuid;
// 生成验证码
- CaptchaType captchaType = captchaProperties.getType();
+ String captchaType = captchaProperties.getType();
CodeGenerator codeGenerator;
- if (CaptchaType.MATH == captchaType) {
- codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), captchaProperties.getNumberLength(), false);
+ if ("math".equals(captchaType)) {
+ codeGenerator = new MathGenerator(captchaProperties.getNumberLength(), false);
} else {
- codeGenerator = ReflectUtils.newInstance(captchaType.getClazz(), captchaProperties.getCharLength());
+ codeGenerator = new RandomGenerator(captchaProperties.getCharLength());
}
- AbstractCaptcha captcha = SpringUtils.getBean(captchaProperties.getCategory().getClazz());
+ WaveAndCircleCaptcha captcha = new WaveAndCircleCaptcha(160, 60);
+ // captcha.setBackground(Color.WHITE); // 不设置就是透明底
+ captcha.setFont(new Font("Arial", Font.BOLD, 45));
captcha.setGenerator(codeGenerator);
captcha.createCode();
// 如果是数学验证码,使用SpEL表达式处理验证码结果
String code = captcha.getCode();
- if (CaptchaType.MATH == captchaType) {
+ if ("math".equals(captchaType)) {
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression(StringUtils.remove(code, "="));
code = exp.getValue(String.class);
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index 3fc344e0b..d11d9f0ea 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -24,9 +24,7 @@ captcha:
# 是否启用验证码校验
enable: true
# 验证码类型 math 数组计算 char 字符验证
- type: MATH
- # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰
- category: SHEAR
+ type: math
# 数字验证码位数
numberLength: 1
# 字符验证码长度
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
index b7172e9b6..7140db947 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/CaptchaConfig.java
@@ -1,16 +1,8 @@
package org.dromara.common.web.config;
-import cn.hutool.captcha.CaptchaUtil;
-import cn.hutool.captcha.CircleCaptcha;
-import cn.hutool.captcha.LineCaptcha;
-import cn.hutool.captcha.ShearCaptcha;
import org.dromara.common.web.config.properties.CaptchaProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Lazy;
-
-import java.awt.*;
/**
* 验证码配置
@@ -21,45 +13,4 @@ import java.awt.*;
@EnableConfigurationProperties(CaptchaProperties.class)
public class CaptchaConfig {
- private static final int WIDTH = 160;
- private static final int HEIGHT = 60;
- private static final Color BACKGROUND = Color.WHITE;
- private static final Font FONT = new Font("Arial", Font.BOLD, 48);
-
- /**
- * 圆圈干扰验证码
- */
- @Lazy
- @Bean
- public CircleCaptcha circleCaptcha() {
- CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(WIDTH, HEIGHT);
- captcha.setBackground(BACKGROUND);
- captcha.setFont(FONT);
- return captcha;
- }
-
- /**
- * 线段干扰的验证码
- */
- @Lazy
- @Bean
- public LineCaptcha lineCaptcha() {
- LineCaptcha captcha = CaptchaUtil.createLineCaptcha(WIDTH, HEIGHT);
- captcha.setBackground(BACKGROUND);
- captcha.setFont(FONT);
- return captcha;
- }
-
- /**
- * 扭曲干扰验证码
- */
- @Lazy
- @Bean
- public ShearCaptcha shearCaptcha() {
- ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(WIDTH, HEIGHT);
- captcha.setBackground(BACKGROUND);
- captcha.setFont(FONT);
- return captcha;
- }
-
}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java
index bfc52f450..6dcfe64bb 100644
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/properties/CaptchaProperties.java
@@ -1,7 +1,5 @@
package org.dromara.common.web.config.properties;
-import org.dromara.common.web.enums.CaptchaCategory;
-import org.dromara.common.web.enums.CaptchaType;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -19,12 +17,7 @@ public class CaptchaProperties {
/**
* 验证码类型
*/
- private CaptchaType type;
-
- /**
- * 验证码类别
- */
- private CaptchaCategory category;
+ private String type;
/**
* 数字验证码位数
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/WaveAndCircleCaptcha.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/WaveAndCircleCaptcha.java
new file mode 100644
index 000000000..8b37be471
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/core/WaveAndCircleCaptcha.java
@@ -0,0 +1,197 @@
+package org.dromara.common.web.core;
+
+import cn.hutool.captcha.AbstractCaptcha;
+import cn.hutool.captcha.generator.CodeGenerator;
+import cn.hutool.captcha.generator.RandomGenerator;
+import cn.hutool.core.img.GraphicsUtil;
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.Serial;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * 带干扰线、波浪、圆的验证码
+ *
+ * @author Lion Li
+ */
+public class WaveAndCircleCaptcha extends AbstractCaptcha {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ // 构造方法(略,与之前一致)
+ public WaveAndCircleCaptcha(int width, int height) {
+ this(width, height, 4);
+ }
+
+ public WaveAndCircleCaptcha(int width, int height, int codeCount) {
+ this(width, height, codeCount, 6);
+ }
+
+ public WaveAndCircleCaptcha(int width, int height, int codeCount, int interfereCount) {
+ this(width, height, new RandomGenerator(codeCount), interfereCount);
+ }
+
+ public WaveAndCircleCaptcha(int width, int height, CodeGenerator generator, int interfereCount) {
+ super(width, height, generator, interfereCount);
+ }
+
+ public WaveAndCircleCaptcha(int width, int height, int codeCount, int interfereCount, float size) {
+ super(width, height, new RandomGenerator(codeCount), interfereCount, size);
+ }
+
+ @Override
+ public Image createImage(String code) {
+ final BufferedImage image = new BufferedImage(
+ width,
+ height,
+ (null == this.background) ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_INT_RGB
+ );
+ final Graphics2D g = ImgUtil.createGraphics(image, this.background);
+
+ try {
+ drawString(g, code);
+ // 扭曲
+ shear(g, this.width, this.height, ObjectUtil.defaultIfNull(this.background, Color.WHITE));
+ drawInterfere(g);
+ } finally {
+ g.dispose();
+ }
+
+ return image;
+ }
+
+ private void drawString(Graphics2D g, String code) {
+ // 设置抗锯齿(让字体渲染更清晰)
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+ if (this.textAlpha != null) {
+ g.setComposite(this.textAlpha);
+ }
+
+ GraphicsUtil.drawStringColourful(g, code, this.font, this.width, this.height);
+ }
+
+ protected void drawInterfere(Graphics2D g) {
+ ThreadLocalRandom random = RandomUtil.getRandom();
+ int circleCount = Math.max(0, this.interfereCount - 1);
+
+ // 圈圈
+ for (int i = 0; i < circleCount; i++) {
+ g.setColor(ImgUtil.randomColor(random));
+ int x = random.nextInt(width);
+ int y = random.nextInt(height);
+ int w = random.nextInt(height >> 1);
+ int h = random.nextInt(height >> 1);
+ g.drawOval(x, y, w, h);
+ }
+
+ // 仅 1 条平滑波浪线
+ if (this.interfereCount >= 1) {
+ g.setColor(getRandomColor(120, 230, random));
+ drawSmoothWave(g, random);
+ }
+ }
+
+ private void drawSmoothWave(Graphics2D g, ThreadLocalRandom random) {
+ int amplitude = random.nextInt(8) + 5; // 波动幅度
+ int wavelength = random.nextInt(40) + 30; // 波长
+ double phase = random.nextDouble() * Math.PI * 2;
+
+ // ✅ 关键:限制 baseY 在中间区域
+ int centerY = height / 2;
+ int verticalJitter = Math.max(5, height / 6); // 至少偏移5像素
+ int baseY = centerY - verticalJitter + random.nextInt(verticalJitter * 2);
+
+ g.setStroke(new BasicStroke(2.5f)); // 线宽
+
+ int[] xPoints = new int[width];
+ int[] yPoints = new int[width];
+ for (int x = 0; x < width; x++) {
+ int y = baseY + (int) (amplitude * Math.sin((double) x / wavelength * 2 * Math.PI + phase));
+ // 限制 y 不要超出图像边界(可选)
+ y = Math.max(amplitude, Math.min(y, height - amplitude));
+ xPoints[x] = x;
+ yPoints[x] = y;
+ }
+ g.drawPolyline(xPoints, yPoints, width);
+ }
+
+ private Color getRandomColor(int min, int max, ThreadLocalRandom random) {
+ int range = max - min;
+ return new Color(
+ min + random.nextInt(range),
+ min + random.nextInt(range),
+ min + random.nextInt(range)
+ );
+ }
+
+ /**
+ * 扭曲
+ *
+ * @param g {@link Graphics}
+ * @param w1 w1
+ * @param h1 h1
+ * @param color 颜色
+ */
+ private void shear(Graphics g, int w1, int h1, Color color) {
+ shearX(g, w1, h1, color);
+ shearY(g, w1, h1, color);
+ }
+
+ /**
+ * X坐标扭曲
+ *
+ * @param g {@link Graphics}
+ * @param w1 宽
+ * @param h1 高
+ * @param color 颜色
+ */
+ private void shearX(Graphics g, int w1, int h1, Color color) {
+
+ int period = RandomUtil.randomInt(this.width);
+
+ int frames = 1;
+ int phase = RandomUtil.randomInt(2);
+
+ for (int i = 0; i < h1; i++) {
+ double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
+ g.copyArea(0, i, w1, 1, (int) d, 0);
+ g.setColor(color);
+ g.drawLine((int) d, i, 0, i);
+ g.drawLine((int) d + w1, i, w1, i);
+ }
+
+ }
+
+ /**
+ * Y坐标扭曲
+ *
+ * @param g {@link Graphics}
+ * @param w1 宽
+ * @param h1 高
+ * @param color 颜色
+ */
+ private void shearY(Graphics g, int w1, int h1, Color color) {
+
+ int period = RandomUtil.randomInt(this.height >> 1);
+
+ int frames = 20;
+ int phase = 7;
+ for (int i = 0; i < w1; i++) {
+ double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
+ g.copyArea(i, 0, 1, h1, 0, (int) d);
+ g.setColor(color);
+ // 擦除原位置的痕迹
+ g.drawLine(i, (int) d, i, 0);
+ g.drawLine(i, (int) d + h1, i, h1);
+ }
+
+ }
+
+}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java
deleted file mode 100644
index ecf26583c..000000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaCategory.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.dromara.common.web.enums;
-
-import cn.hutool.captcha.AbstractCaptcha;
-import cn.hutool.captcha.CircleCaptcha;
-import cn.hutool.captcha.LineCaptcha;
-import cn.hutool.captcha.ShearCaptcha;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 验证码类别
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum CaptchaCategory {
-
- /**
- * 线段干扰
- */
- LINE(LineCaptcha.class),
-
- /**
- * 圆圈干扰
- */
- CIRCLE(CircleCaptcha.class),
-
- /**
- * 扭曲干扰
- */
- SHEAR(ShearCaptcha.class);
-
- private final Class extends AbstractCaptcha> clazz;
-}
diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java
deleted file mode 100644
index d0b6ca3eb..000000000
--- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/enums/CaptchaType.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.dromara.common.web.enums;
-
-import cn.hutool.captcha.generator.CodeGenerator;
-import cn.hutool.captcha.generator.MathGenerator;
-import cn.hutool.captcha.generator.RandomGenerator;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 验证码类型
- *
- * @author Lion Li
- */
-@Getter
-@AllArgsConstructor
-public enum CaptchaType {
-
- /**
- * 数字
- */
- MATH(MathGenerator.class),
-
- /**
- * 字符
- */
- CHAR(RandomGenerator.class);
-
- private final Class extends CodeGenerator> clazz;
-}
From f984f08a14e495cf2f0138cc175c37f5bb7f33b8 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, 16 Jan 2026 16:47:12 +0800
Subject: [PATCH 14/20] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E6=8C=89?=
=?UTF-8?q?=E9=92=AE=E8=8F=9C=E5=8D=95=20=E4=B8=8D=E5=BA=94=E8=AF=A5?=
=?UTF-8?q?=E6=A0=A1=E9=AA=8C=E8=B7=AF=E7=94=B1=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../org/dromara/system/service/impl/SysMenuServiceImpl.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
index 921f7e4b4..fd824e9af 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
@@ -367,6 +367,9 @@ public class SysMenuServiceImpl implements ISysMenuService {
@Override
public boolean checkRouteConfigUnique(SysMenuBo menuBo) {
SysMenu menu = MapstructUtils.convert(menuBo, SysMenu.class);
+ if (SystemConstants.TYPE_BUTTON.equals(menu.getMenuType())) {
+ return true;
+ }
long menuId = ObjectUtil.isNull(menu.getMenuId()) ? -1L : menu.getMenuId();
Long parentId = menu.getParentId();
String path = menu.getPath();
From 79d9f47053b0b42b54d068861583cb044fa647dc 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, 19 Jan 2026 15:09:07 +0800
Subject: [PATCH 15/20] update README.md
---
README.md | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 8786e423e..983997a74 100644
--- a/README.md
+++ b/README.md
@@ -8,10 +8,9 @@
[](https://github.com/dromara/RuoYi-Vue-Plus)
[](https://gitcode.com/dromara/RuoYi-Vue-Plus)
[](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/5.X/LICENSE)
-[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
[](https://gitee.com/dromara/RuoYi-Vue-Plus)
-[]()
+[]()
[]()
[]()
@@ -33,7 +32,7 @@
MaxKey 业界领先单点登录产品 - https://gitee.com/dromara/MaxKey
CCFlow 驰聘低代码-流程-表单 - https://gitee.com/opencc/RuoYi-JFlow
-数舵科技 软件定制开发APP小程序等 - http://www.shuduokeji.com/
+数舵科技 软件定制开发APP小程序等 - https://www.shuduokeji.com/
引迈信息 软件开发平台 - https://www.jnpfsoft.com/index.html?from=plus-doc
Mall4J 高质量Java商城系统 - https://www.mall4j.com/cn/?statId=11
aizuda flowlong 工作流 - https://gitee.com/aizuda/flowlong
From aa277b373bb3e7b106ae40ee1feccdab36f03d70 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: Wed, 21 Jan 2026 11:46:33 +0800
Subject: [PATCH 16/20] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=20=E4=B8=8D?=
=?UTF-8?q?=E5=90=8C=E7=B1=BB=E5=88=AB=E8=8F=9C=E5=8D=95=E7=9A=84=E5=88=A4?=
=?UTF-8?q?=E6=96=AD=E9=80=BB=E8=BE=91=E6=9C=89=E8=AF=AF=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../system/service/impl/SysMenuServiceImpl.java | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
index fd824e9af..0c69b1f3f 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
@@ -377,21 +377,24 @@ public class SysMenuServiceImpl implements ISysMenuService {
List sysMenuList = baseMapper.selectList(
new LambdaQueryWrapper()
.in(SysMenu::getMenuType, SystemConstants.TYPE_DIR, SystemConstants.TYPE_MENU)
- .eq(SysMenu::getPath, path).or().eq(SysMenu::getPath, routeName));
+ .and(w ->
+ w.eq(SysMenu::getPath, path).or().eq(SysMenu::getPath, routeName)
+ ));
for (SysMenu sysMenu : sysMenuList) {
- if (sysMenu.getMenuId() != menuId) {
+ if (!sysMenu.getMenuId().equals(menuId)) {
Long dbParentId = sysMenu.getParentId();
String dbPath = sysMenu.getPath();
String dbRouteName = StringUtils.isEmpty(sysMenu.getRouteName()) ? dbPath : sysMenu.getRouteName();
- if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.longValue() == dbParentId.longValue()) {
+ if (StringUtils.equalsAnyIgnoreCase(path, dbPath) && parentId.equals(dbParentId)) {
log.warn("[同级路由冲突] 同级下已存在相同路由路径 '{}',冲突菜单:{}", dbPath, sysMenu.getMenuName());
return false;
} else if (StringUtils.equalsAnyIgnoreCase(path, dbPath)
- && parentId.longValue() == Constants.TOP_PARENT_ID
- && dbParentId.longValue() == Constants.TOP_PARENT_ID) {
+ && Constants.TOP_PARENT_ID.equals(parentId)
+ && Constants.TOP_PARENT_ID.equals(dbParentId)) {
log.warn("[根目录路由冲突] 根目录下路由 '{}' 必须唯一,已被菜单 '{}' 占用", path, sysMenu.getMenuName());
return false;
- } else if (StringUtils.equalsAnyIgnoreCase(routeName, dbRouteName)) {
+ } else if (StringUtils.equalsAnyIgnoreCase(routeName, dbRouteName)
+ && sysMenu.getMenuType().equals(menu.getMenuType())) {
log.warn("[路由名称冲突] 路由名称 '{}' 需全局唯一,已被菜单 '{}' 使用", routeName, sysMenu.getMenuName());
return false;
}
From 95c9e37797771945a9f8f0812c98cb0b69fa9ab0 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: Wed, 21 Jan 2026 11:51:43 +0800
Subject: [PATCH 17/20] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20oss=20?=
=?UTF-8?q?=E4=BE=9D=E8=B5=96=E6=B3=A8=E9=87=8A=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ruoyi-common/ruoyi-common-oss/pom.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/ruoyi-common/ruoyi-common-oss/pom.xml b/ruoyi-common/ruoyi-common-oss/pom.xml
index 190dc5d46..bd19cc8d2 100644
--- a/ruoyi-common/ruoyi-common-oss/pom.xml
+++ b/ruoyi-common/ruoyi-common-oss/pom.xml
@@ -31,7 +31,7 @@
software.amazon.awssdk
s3
-
+
software.amazon.awssdk
aws-crt-client
@@ -49,13 +49,13 @@
-
+
software.amazon.awssdk
netty-nio-client
-
+
software.amazon.awssdk
s3-transfer-manager
From 76218091ad664a7fd3ed3b4adedd21a6f04d3e39 Mon Sep 17 00:00:00 2001
From: Coast <591616450@qq.com>
Date: Wed, 21 Jan 2026 06:41:34 +0000
Subject: [PATCH 18/20] =?UTF-8?q?!824=20update=20=E4=BC=98=E5=8C=96=20oss?=
=?UTF-8?q?=20=E4=BE=9D=E8=B5=96=E6=B3=A8=E9=87=8A=E8=AF=B4=E6=98=8E=20*?=
=?UTF-8?q?=20update=20=E4=BC=98=E5=8C=96=20oss=20=E4=BE=9D=E8=B5=96?=
=?UTF-8?q?=E6=B3=A8=E9=87=8A=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 16e05d583..0bb01ff2e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -226,13 +226,13 @@
s3
${aws.sdk.version}
-
+
software.amazon.awssdk
s3-transfer-manager
${aws.sdk.version}
-
+
software.amazon.awssdk
netty-nio-client
From 348d7fc534461d5996301384bd4edbd87c408247 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, 23 Jan 2026 13:48:07 +0800
Subject: [PATCH 19/20] update springboot 3.5.9 => 3.5.10 update springdoc
2.8.14 => 2.8.15 update mybatis-plus 3.5.14 => 3.5.16 update hutool 5.8.40 =>
5.8.43 update spring-boot-admin 3.5.5 => 3.5.6
---
pom.xml | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/pom.xml b/pom.xml
index 0bb01ff2e..756e8fed5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,27 +14,27 @@
5.5.2
- 3.5.9
+ 3.5.10
UTF-8
UTF-8
17
- 3.5.16
- 2.8.14
+ 3.5.19
+ 2.8.15
0.15.0
1.3.0
2.3
1.44.0
- 3.5.14
+ 3.5.16
3.9.1
- 5.8.40
- 3.5.5
+ 5.8.43
+ 3.5.6
3.52.0
2.2.7
4.3.1
1.9.0
1.5.0
0.2.0
- 1.18.40
+ 1.18.42
1.80
1.16.7
From 1bb597b8553db92ec495c6f000b80af79cfc83aa 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, 23 Jan 2026 14:00:24 +0800
Subject: [PATCH 20/20] =?UTF-8?q?=F0=9F=A7=A8=F0=9F=A7=A8=F0=9F=A7=A8?=
=?UTF-8?q?=E5=8F=91=E5=B8=83=205.5.3=20=E7=89=88=E6=9C=AC=20=E6=8F=90?=
=?UTF-8?q?=E5=89=8D=E7=A5=9D=E5=A4=A7=E5=AE=B6=E6=96=B0=E5=B9=B4=E5=BF=AB?=
=?UTF-8?q?=E4=B9=90?=
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 | 2 +-
ruoyi-common/ruoyi-common-bom/pom.xml | 2 +-
script/docker/docker-compose.yml | 8 ++++----
7 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/.run/ruoyi-monitor-admin.run.xml b/.run/ruoyi-monitor-admin.run.xml
index 751f46f7f..e7d616db7 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 2adc33a19..2d2c4471f 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 442c2748b..5fe048db6 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 983997a74..acd14004c 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
[](https://gitcode.com/dromara/RuoYi-Vue-Plus)
[](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/5.X/LICENSE)
-[](https://gitee.com/dromara/RuoYi-Vue-Plus)
+[](https://gitee.com/dromara/RuoYi-Vue-Plus)
[]()
[]()
[]()
diff --git a/pom.xml b/pom.xml
index 756e8fed5..5db1e6540 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,7 @@
Dromara RuoYi-Vue-Plus多租户管理系统
- 5.5.2
+ 5.5.3
3.5.10
UTF-8
UTF-8
diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml
index 3324cbe5f..dd043681c 100644
--- a/ruoyi-common/ruoyi-common-bom/pom.xml
+++ b/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -14,7 +14,7 @@
- 5.5.2
+ 5.5.3
diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml
index 462650bd5..f40a4ff01 100644
--- a/script/docker/docker-compose.yml
+++ b/script/docker/docker-compose.yml
@@ -99,7 +99,7 @@ services:
network_mode: "host"
ruoyi-server1:
- image: ruoyi/ruoyi-server:5.5.2
+ image: ruoyi/ruoyi-server:5.5.3
container_name: ruoyi-server1
environment:
# 时区上海
@@ -115,7 +115,7 @@ services:
network_mode: "host"
ruoyi-server2:
- image: ruoyi/ruoyi-server:5.5.2
+ image: ruoyi/ruoyi-server:5.5.3
container_name: ruoyi-server2
environment:
# 时区上海
@@ -131,7 +131,7 @@ services:
network_mode: "host"
ruoyi-monitor-admin:
- image: ruoyi/ruoyi-monitor-admin:5.5.2
+ image: ruoyi/ruoyi-monitor-admin:5.5.3
container_name: ruoyi-monitor-admin
environment:
# 时区上海
@@ -143,7 +143,7 @@ services:
network_mode: "host"
ruoyi-snailjob-server:
- image: ruoyi/ruoyi-snailjob-server:5.5.2
+ image: ruoyi/ruoyi-snailjob-server:5.5.3
container_name: ruoyi-snailjob-server
environment:
# 时区上海