From 203233fbaf8379623879957684de4d4b499b811a Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期五, 22 十二月 2023 13:23:30 +0800
Subject: [PATCH] !464 发布 5.1.2 版本 2023 最后一版 Merge pull request !464 from 疯狂的狮子Li/dev

---
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java                                      |    2 
 .run/ruoyi-server.run.xml                                                                                                                 |    2 
 script/bin/ry.bat                                                                                                                         |    2 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java                           |    6 
 ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java                                                               |    5 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java                                             |    7 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java                                     |   29 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java                                 |   12 
 ruoyi-admin/src/main/resources/i18n/messages_en_US.properties                                                                             |    5 
 script/sql/postgres/powerjob.sql                                                                                                          |    8 
 ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java                                                                |   76 +-
 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java                          |    8 
 ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports         |    2 
 .run/ruoyi-powerjob-server.run.xml                                                                                                        |    2 
 script/sql/oracle/oracle_ry_vue_5.X.sql                                                                                                   |    6 
 .run/ruoyi-monitor-admin.run.xml                                                                                                          |    2 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java                                     |   20 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java                                              |    6 
 ruoyi-extend/ruoyi-powerjob-server/Dockerfile                                                                                             |    5 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java                                              |    4 
 ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java                                                                  |    6 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java                 |   27 +
 ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java                                                                    |   17 
 ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java                                                             |   31 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java                                              |   49 ++
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java                                    |   14 
 ruoyi-admin/Dockerfile                                                                                                                    |   16 
 ruoyi-admin/src/main/resources/application.yml                                                                                            |    8 
 ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports |    1 
 script/docker/nginx/conf/nginx.conf                                                                                                       |    2 
 README.md                                                                                                                                 |    4 
 ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java                                         |   61 ++
 ruoyi-admin/src/main/resources/application-prod.yml                                                                                       |    6 
 ruoyi-extend/ruoyi-monitor-admin/Dockerfile                                                                                               |    5 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java                                      |    3 
 ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java                                                               |    5 
 ruoyi-admin/src/main/resources/i18n/messages.properties                                                                                   |    5 
 ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java                            |    5 
 ruoyi-common/ruoyi-common-encrypt/pom.xml                                                                                                 |    5 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java                                                     |   34 -
 script/sql/update/update_5.1.1-5.1.2.sql                                                                                                  |    6 
 ruoyi-admin/src/main/resources/application-dev.yml                                                                                        |    6 
 script/sql/oracle/powerjob.sql                                                                                                            |    8 
 ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java                                       |    5 
 ruoyi-extend/ruoyi-powerjob-server/pom.xml                                                                                                |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java                                                      |    4 
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java                                        |   27 +
 script/sql/update/postgres/update_5.1.1-5.1.2.sql                                                                                         |    6 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java                                   |   36 -
 ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java                                                            |   48 -
 ruoyi-common/ruoyi-common-bom/pom.xml                                                                                                     |    2 
 pom.xml                                                                                                                                   |   20 
 ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties                                                                             |    5 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java                                                |    2 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java                         |    7 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java                                                    |   31 -
 ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml                                                             |   15 
 script/sql/sqlserver/powerjob.sql                                                                                                         |    8 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java                         |  120 +++++
 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java                                               |   56 ++
 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java                                  |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java                                    |   12 
 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java                                           |   51 +-
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java                                        |    4 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java                                       |   74 +++
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java                                             |    8 
 ruoyi-admin/pom.xml                                                                                                                       |    4 
 ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java                          |    2 
 script/sql/update/sqlserver/update_5.1.1-5.1.2.sql                                                                                        |   10 
 script/sql/update/oracle/update_5.1.1-5.1.2.sql                                                                                           |    5 
 ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java                                         |   58 +-
 script/docker/docker-compose.yml                                                                                                          |    8 
 script/sql/ry_vue_5.X.sql                                                                                                                 |    9 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java                                          |    8 
 ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java                                                |    2 
 script/sql/sqlserver/sqlserver_ry_vue_5.X.sql                                                                                             |    8 
 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java                                               |    7 
 ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java                                                                 |   11 
 /dev/null                                                                                                                                 |   19 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java                                               |   35 +
 ruoyi-modules/ruoyi-demo/src/main/resources/excel/多sheet列表.xlsx                                                                           |    0 
 script/bin/ry.sh                                                                                                                          |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java                                   |    7 
 script/sql/postgres/postgres_ry_vue_5.X.sql                                                                                               |    6 
 ruoyi-common/ruoyi-common-mybatis/pom.xml                                                                                                 |   11 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java                                        |    7 
 ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java                                            |    2 
 ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java                                                          |   31 
 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java                           |    2 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java                                     |    2 
 ruoyi-common/ruoyi-common-core/pom.xml                                                                                                    |    6 
 ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java                                                               |   31 
 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java                                      |    4 
 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java                                      |    2 
 94 files changed, 885 insertions(+), 492 deletions(-)

diff --git a/.run/ruoyi-monitor-admin.run.xml b/.run/ruoyi-monitor-admin.run.xml
index aa1d7a5..4837d6a 100644
--- a/.run/ruoyi-monitor-admin.run.xml
+++ b/.run/ruoyi-monitor-admin.run.xml
@@ -2,7 +2,7 @@
   <configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
     <deployment type="dockerfile">
       <settings>
-        <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.1.1" />
+        <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.1.2" />
         <option name="buildOnly" value="true" />
         <option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
       </settings>
diff --git a/.run/ruoyi-powerjob-server.run.xml b/.run/ruoyi-powerjob-server.run.xml
index 61e74ea..77a4af0 100644
--- a/.run/ruoyi-powerjob-server.run.xml
+++ b/.run/ruoyi-powerjob-server.run.xml
@@ -2,7 +2,7 @@
   <configuration default="false" name="ruoyi-powerjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
     <deployment type="dockerfile">
       <settings>
-        <option name="imageTag" value="ruoyi/ruoyi-powerjob-server:5.1.1" />
+        <option name="imageTag" value="ruoyi/ruoyi-powerjob-server:5.1.2" />
         <option name="buildOnly" value="true" />
         <option name="sourceFilePath" value="ruoyi-extend/ruoyi-powerjob-server/Dockerfile" />
       </settings>
diff --git a/.run/ruoyi-server.run.xml b/.run/ruoyi-server.run.xml
index 4842e0b..a29ff2a 100644
--- a/.run/ruoyi-server.run.xml
+++ b/.run/ruoyi-server.run.xml
@@ -2,7 +2,7 @@
   <configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
     <deployment type="dockerfile">
       <settings>
-        <option name="imageTag" value="ruoyi/ruoyi-server:5.1.1" />
+        <option name="imageTag" value="ruoyi/ruoyi-server:5.1.2" />
         <option name="buildOnly" value="true" />
         <option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
       </settings>
diff --git a/README.md b/README.md
index c9a0be4..c2ddd19 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
 [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE)
 [![浣跨敤IntelliJ IDEA寮�鍙戠淮鎶(https://img.shields.io/badge/IntelliJ%20IDEA-鎻愪緵鏀寔-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
 <br>
-[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.1.1-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus)
+[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-5.1.2-success.svg)](https://gitee.com/dromara/RuoYi-Vue-Plus)
 [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.1-blue.svg)]()
 [![JDK-17](https://img.shields.io/badge/JDK-17-green.svg)]()
 [![JDK-21](https://img.shields.io/badge/JDK-21-green.svg)]()
@@ -36,7 +36,7 @@
 | 鏉冮檺璁よ瘉        | 閲囩敤 Sa-Token銆丣wt 闈欐�佷娇鐢ㄥ姛鑳介綈鍏� 浣庤�﹀悎 楂樻墿灞�                                                                                  | Spring Security 閰嶇疆绻佺悙鎵╁睍鎬ф瀬宸�                                                          |
 | 鏉冮檺娉ㄨВ        | 閲囩敤 Sa-Token 鏀寔娉ㄨВ 鐧诲綍鏍¢獙銆佽鑹叉牎楠屻�佹潈闄愭牎楠屻�佷簩绾ц璇佹牎楠屻�丠ttpBasic鏍¢獙銆佸拷鐣ユ牎楠�<br/>瑙掕壊涓庢潈闄愭牎楠屾敮鎸佸绉嶆潯浠� 濡� `AND` `OR` 鎴� `鏉冮檺 OR 瑙掕壊` 绛夊鏉傝〃杈惧紡        | 鍙敮鎸佹槸鍚﹀瓨鍦ㄥ尮閰�                                                                          |
 | 涓夋柟閴存潈        | 閲囩敤 JustAuth 绗笁鏂圭櫥褰曠粍浠� 鏀寔寰俊銆侀拤閽夌瓑鏁板崄绉嶄笁鏂硅璇�                                                                               | 鏃�                                                                                  |
-| 鍏崇郴鏁版嵁搴撴敮鎸�     | 鍘熺敓鏀寔 MySQL銆丱racle銆丳ostgreSQL銆丼QLServer<br/>鍙悓鏃朵娇鐢ㄥ紓鏋勫垏鎹�                                                              | 鏀寔 Mysql銆丱racle 涓嶆敮鎸佸悓鏃朵娇鐢ㄣ�佷笉鏀寔寮傛瀯鍒囨崲                                                    |
+| 鍏崇郴鏁版嵁搴撴敮鎸�     | 鍘熺敓鏀寔 MySQL銆丱racle銆丳ostgreSQL銆丼QLServer<br/>鍙悓鏃朵娇鐢ㄥ紓鏋勫垏鎹�(鏀寔鍏朵粬 mybatis-plus 鏀寔鐨勬墍鏈夋暟鎹簱 鍙渶瑕佸鍔爅dbc渚濊禆鍗冲彲浣跨敤 杈炬ⅵ閲戜粨绛夊潎鏈夋垚鍔熸渚�)      | 鏀寔 Mysql銆丱racle 涓嶆敮鎸佸悓鏃朵娇鐢ㄣ�佷笉鏀寔寮傛瀯鍒囨崲                                                    |
 | 缂撳瓨鏁版嵁搴�       | 鏀寔 Redis 5-7 鏀寔澶ч儴鍒嗘柊鍔熻兘鐗规�� 濡� 鍒嗗竷寮忛檺娴併�佸垎甯冨紡闃熷垪                                                                             | Redis 绠�鍗� get set 鏀寔                                                                |
 | Redis瀹㈡埛绔�    | 閲囩敤 Redisson Redis瀹樻柟鎺ㄨ崘 鍩轰簬Netty鐨勫鎴风宸ュ叿<br/>鏀寔Redis 90%浠ヤ笂鐨勫懡浠� 搴曞眰浼樺寲瑙勯伩寰堝涓嶆纭殑鐢ㄦ硶 渚嬪: keys琚浆鎹负scan<br/>鏀寔鍗曟満銆佸摠鍏点�佸崟涓婚泦缇ゃ�佸涓婚泦缇ょ瓑妯″紡 | Lettuce + RedisTemplate 鏀寔妯″紡灏� 宸ュ叿浣跨敤绻佺悙<br/>杩炴帴姹犻噰鐢� common-pool Bug澶氱粡甯告�у嚭闂              |
 | 缂撳瓨娉ㄨВ        | 閲囩敤 Spring-Cache 娉ㄨВ 瀵瑰叾鎵╁睍浜嗗疄鐜版敮鎸佷簡鏇村鍔熻兘<br/>渚嬪 杩囨湡鏃堕棿 鏈�澶х┖闂叉椂闂� 缁勬渶澶ч暱搴︾瓑 鍙渶涓�涓敞瑙e嵆鍙畬鎴愭暟鎹嚜鍔ㄧ紦瀛�                                      | 闇�鎵嬪姩缂栧啓Redis浠g爜閫昏緫                                                                     |
diff --git a/pom.xml b/pom.xml
index 4e079f3..3aafe14 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,38 +13,38 @@
     <description>RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</description>
 
     <properties>
-        <revision>5.1.1</revision>
-        <spring-boot.version>3.1.5</spring-boot.version>
+        <revision>5.1.2</revision>
+        <spring-boot.version>3.1.7</spring-boot.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <java.version>17</java.version>
-        <spring-boot.mybatis>3.0.2</spring-boot.mybatis>
+        <spring-boot.mybatis>3.0.3</spring-boot.mybatis>
         <springdoc.version>2.2.0</springdoc.version>
         <therapi-javadoc.version>0.15.0</therapi-javadoc.version>
         <poi.version>5.2.3</poi.version>
-        <easyexcel.version>3.3.2</easyexcel.version>
+        <easyexcel.version>3.3.3</easyexcel.version>
         <velocity.version>2.3</velocity.version>
         <satoken.version>1.37.0</satoken.version>
         <mybatis-plus.version>3.5.4</mybatis-plus.version>
         <p6spy.version>3.9.1</p6spy.version>
         <hutool.version>5.8.22</hutool.version>
         <okhttp.version>4.10.0</okhttp.version>
-        <spring-boot-admin.version>3.1.7</spring-boot-admin.version>
-        <redisson.version>3.24.1</redisson.version>
+        <spring-boot-admin.version>3.1.8</spring-boot-admin.version>
+        <redisson.version>3.24.3</redisson.version>
         <lock4j.version>2.2.5</lock4j.version>
         <dynamic-ds.version>4.2.0</dynamic-ds.version>
-        <alibaba-ttl.version>2.14.2</alibaba-ttl.version>
-        <powerjob.version>4.3.3</powerjob.version>
+        <alibaba-ttl.version>2.14.4</alibaba-ttl.version>
+        <powerjob.version>4.3.6</powerjob.version>
         <mapstruct-plus.version>1.3.5</mapstruct-plus.version>
         <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version>
         <lombok.version>1.18.30</lombok.version>
         <bouncycastle.version>1.76</bouncycastle.version>
-        <justauth.version>1.16.5</justauth.version>
+        <justauth.version>1.16.6</justauth.version>
         <!-- 绂荤嚎IP鍦板潃瀹氫綅搴� -->
         <ip2region.version>2.7.0</ip2region.version>
 
         <!-- OSS 閰嶇疆 -->
-        <aws-java-sdk-s3.version>1.12.540</aws-java-sdk-s3.version>
+        <aws-java-sdk-s3.version>1.12.600</aws-java-sdk-s3.version>
         <!-- SMS 閰嶇疆 -->
         <sms4j.version>2.2.0</sms4j.version>
         <!-- 闄愬埗妗嗘灦涓殑fastjson鐗堟湰 -->
diff --git a/ruoyi-admin/Dockerfile b/ruoyi-admin/Dockerfile
index 0278884..4237ef9 100644
--- a/ruoyi-admin/Dockerfile
+++ b/ruoyi-admin/Dockerfile
@@ -9,16 +9,16 @@
 
 WORKDIR /ruoyi/server
 
-ENV SERVER_PORT=8080 LANG=C.UTF-8 LC_ALL=C.UTF-8
+ENV SERVER_PORT=8080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
 
 EXPOSE ${SERVER_PORT}
 
 ADD ./target/ruoyi-admin.jar ./app.jar
 
-ENTRYPOINT ["java", \
-            "-Djava.security.egd=file:/dev/./urandom", \
-            "-Dserver.port=${SERVER_PORT}", \
-            # 搴旂敤鍚嶇О 濡傛灉鎯冲尯鍒嗛泦缇よ妭鐐圭洃鎺� 鏀规垚涓嶅悓鐨勫悕绉板嵆鍙�
-#            "-Dskywalking.agent.service_name=ruoyi-server", \
-#            "-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar", \
-            "-jar", "app.jar"]
+ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
+           # 搴旂敤鍚嶇О 濡傛灉鎯冲尯鍒嗛泦缇よ妭鐐圭洃鎺� 鏀规垚涓嶅悓鐨勫悕绉板嵆鍙�
+           #-Dskywalking.agent.service_name=ruoyi-server \
+           #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
+           -jar app.jar \
+           -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS}
+
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 8193359..26cd023 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -48,6 +48,10 @@
             <artifactId>ruoyi-common-social</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-ratelimiter</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>org.dromara</groupId>
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
index 79cd574..d0d7931 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
@@ -16,6 +16,7 @@
 import org.dromara.common.core.domain.model.RegisterBody;
 import org.dromara.common.core.domain.model.SocialLoginBody;
 import org.dromara.common.core.utils.*;
+import org.dromara.common.encrypt.annotation.ApiEncrypt;
 import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
@@ -51,7 +52,6 @@
  */
 @Slf4j
 @SaIgnore
-@Validated
 @RequiredArgsConstructor
 @RestController
 @RequestMapping("/auth")
@@ -73,8 +73,9 @@
      * @param body 鐧诲綍淇℃伅
      * @return 缁撴灉
      */
+    @ApiEncrypt
     @PostMapping("/login")
-    public R<LoginVo> login(@Validated @RequestBody String body) {
+    public R<LoginVo> login(@RequestBody String body) {
         LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class);
         ValidatorUtils.validate(loginBody);
         // 鎺堟潈绫诲瀷鍜屽鎴风id
@@ -163,6 +164,7 @@
     /**
      * 鐢ㄦ埛娉ㄥ唽
      */
+    @ApiEncrypt
     @PostMapping("/register")
     public R<Void> register(@Validated @RequestBody RegisterBody user) {
         if (!configService.selectRegisterEnabled(user.getTenantId())) {
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 656447e..ef33f5b 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
@@ -13,6 +13,8 @@
 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.config.properties.CaptchaProperties;
 import org.dromara.common.web.enums.CaptchaType;
@@ -54,6 +56,7 @@
      *
      * @param phonenumber 鐢ㄦ埛鎵嬫満鍙�
      */
+    @RateLimiter(key = "#phonenumber", time = 60, count = 1)
     @GetMapping("/resource/sms/code")
     public R<Void> smsCode(@NotBlank(message = "{user.phonenumber.not.blank}") String phonenumber) {
         String key = GlobalConstants.CAPTCHA_CODE_KEY + phonenumber;
@@ -77,6 +80,7 @@
      *
      * @param email 閭
      */
+    @RateLimiter(key = "#email", time = 60, count = 1)
     @GetMapping("/resource/email/code")
     public R<Void> emailCode(@NotBlank(message = "{user.email.not.blank}") String email) {
         if (!mailProperties.getEnabled()) {
@@ -97,6 +101,7 @@
     /**
      * 鐢熸垚楠岃瘉鐮�
      */
+    @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
     @GetMapping("/auth/code")
     public R<CaptchaVo> getCode() {
         CaptchaVo captchaVo = new CaptchaVo();
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/listener/UserActionListener.java b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java
similarity index 61%
rename from ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/listener/UserActionListener.java
rename to ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java
index 80034f1..6d67fb1 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/listener/UserActionListener.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java
@@ -1,20 +1,24 @@
-package org.dromara.common.satoken.listener;
+package org.dromara.web.listener;
 
 import cn.dev33.satoken.config.SaTokenConfig;
 import cn.dev33.satoken.listener.SaTokenListener;
 import cn.dev33.satoken.stp.SaLoginModel;
 import cn.hutool.http.useragent.UserAgent;
 import cn.hutool.http.useragent.UserAgentUtil;
-import org.dromara.common.core.constant.CacheConstants;
-import org.dromara.common.core.domain.dto.UserOnlineDTO;
-import org.dromara.common.core.domain.model.LoginUser;
-import org.dromara.common.core.enums.UserType;
-import org.dromara.common.redis.utils.RedisUtils;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.core.utils.ip.AddressUtils;
-import org.dromara.common.core.utils.ServletUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.CacheConstants;
+import org.dromara.common.core.constant.Constants;
+import org.dromara.common.core.domain.dto.UserOnlineDTO;
+import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.utils.MessageUtils;
+import org.dromara.common.core.utils.ServletUtils;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.ip.AddressUtils;
+import org.dromara.common.log.event.LogininforEvent;
+import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.web.service.SysLoginService;
 import org.springframework.stereotype.Component;
 
 import java.time.Duration;
@@ -30,37 +34,43 @@
 public class UserActionListener implements SaTokenListener {
 
     private final SaTokenConfig tokenConfig;
+    private final SysLoginService loginService;
 
     /**
      * 姣忔鐧诲綍鏃惰Е鍙�
      */
     @Override
     public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
-        UserType userType = UserType.getUserType(loginId.toString());
-        if (userType == UserType.SYS_USER) {
-            UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
-            String ip = ServletUtils.getClientIP();
-            LoginUser user = LoginHelper.getLoginUser();
-            UserOnlineDTO dto = new UserOnlineDTO();
-            dto.setIpaddr(ip);
-            dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
-            dto.setBrowser(userAgent.getBrowser().getName());
-            dto.setOs(userAgent.getOs().getName());
-            dto.setLoginTime(System.currentTimeMillis());
-            dto.setTokenId(tokenValue);
-            dto.setUserName(user.getUsername());
-            dto.setClientKey(user.getClientKey());
-            dto.setDeviceType(user.getDeviceType());
-            dto.setDeptName(user.getDeptName());
-            if(tokenConfig.getTimeout() == -1) {
-                RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto);
-            } else {
-                RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
-            }
-            log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
-        } else if (userType == UserType.APP_USER) {
-            // app绔� 鑷鏍规嵁涓氬姟缂栧啓
+        UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
+        String ip = ServletUtils.getClientIP();
+        LoginUser user = LoginHelper.getLoginUser();
+        UserOnlineDTO dto = new UserOnlineDTO();
+        dto.setIpaddr(ip);
+        dto.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
+        dto.setBrowser(userAgent.getBrowser().getName());
+        dto.setOs(userAgent.getOs().getName());
+        dto.setLoginTime(System.currentTimeMillis());
+        dto.setTokenId(tokenValue);
+        dto.setUserName(user.getUsername());
+        dto.setClientKey(user.getClientKey());
+        dto.setDeviceType(user.getDeviceType());
+        dto.setDeptName(user.getDeptName());
+        if(tokenConfig.getTimeout() == -1) {
+            RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto);
+        } else {
+            RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
         }
+        // 璁板綍鐧诲綍鏃ュ織
+        LogininforEvent logininforEvent = new LogininforEvent();
+        logininforEvent.setTenantId(user.getTenantId());
+        logininforEvent.setUsername(user.getUsername());
+        logininforEvent.setStatus(Constants.LOGIN_SUCCESS);
+        logininforEvent.setMessage(MessageUtils.message("user.login.success"));
+        logininforEvent.setRequest(ServletUtils.getRequest());
+        SpringUtils.context().publishEvent(logininforEvent);
+        // 鏇存柊鐧诲綍淇℃伅
+        loginService.recordLoginInfo(user.getUserId(), ip);
+        log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
     }
 
     /**
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
index 7e07e20..37802b7 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
@@ -3,6 +3,7 @@
 import cn.dev33.satoken.exception.NotLoginException;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -17,6 +18,7 @@
 import org.dromara.common.core.exception.user.UserException;
 import org.dromara.common.core.utils.*;
 import org.dromara.common.log.event.LogininforEvent;
+import org.dromara.common.mybatis.helper.DataPermissionHelper;
 import org.dromara.common.redis.utils.RedisUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.tenant.exception.TenantException;
@@ -77,13 +79,13 @@
         bo.setUserName(authUserData.getUsername());
         bo.setNickName(authUserData.getNickname());
         // 鏌ヨ鏄惁宸茬粡缁戝畾鐢ㄦ埛
-        SysSocialVo vo = sysSocialService.selectByAuthId(authId);
-        if (ObjectUtil.isEmpty(vo)) {
+        List<SysSocialVo> list = sysSocialService.selectByAuthId(authId);
+        if (CollUtil.isEmpty(list)) {
             // 娌℃湁缁戝畾鐢ㄦ埛, 鏂板鐢ㄦ埛淇℃伅
             sysSocialService.insertByBo(bo);
         } else {
             // 鏇存柊鐢ㄦ埛淇℃伅
-            bo.setId(vo.getId());
+            bo.setId(list.get(0).getId());
             sysSocialService.updateByBo(bo);
         }
     }
@@ -95,6 +97,9 @@
     public void logout() {
         try {
             LoginUser loginUser = LoginHelper.getLoginUser();
+            if (ObjectUtil.isNull(loginUser)) {
+                return;
+            }
             if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
                 // 瓒呯骇绠$悊鍛� 鐧诲嚭娓呴櫎鍔ㄦ�佺鎴�
                 TenantHelper.clearDynamic();
@@ -152,13 +157,13 @@
      *
      * @param userId 鐢ㄦ埛ID
      */
-    public void recordLoginInfo(Long userId) {
+    public void recordLoginInfo(Long userId, String ip) {
         SysUser sysUser = new SysUser();
         sysUser.setUserId(userId);
-        sysUser.setLoginIp(ServletUtils.getClientIP());
+        sysUser.setLoginIp(ip);
         sysUser.setLoginDate(DateUtils.getNowDate());
         sysUser.setUpdateBy(userId);
-        userMapper.updateById(sysUser);
+        DataPermissionHelper.ignore(() -> userMapper.updateById(sysUser));
     }
 
     /**
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java
index 4d4b072..f38d074 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java
@@ -3,6 +3,7 @@
 import cn.dev33.satoken.secure.BCrypt;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.constant.GlobalConstants;
 import org.dromara.common.core.domain.model.RegisterBody;
@@ -22,7 +23,6 @@
 import org.dromara.system.domain.bo.SysUserBo;
 import org.dromara.system.mapper.SysUserMapper;
 import org.dromara.system.service.ISysUserService;
-import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
 /**
@@ -59,10 +59,11 @@
         sysUser.setPassword(BCrypt.hashpw(password));
         sysUser.setUserType(userType);
 
-        boolean exist = userMapper.exists(new LambdaQueryWrapper<SysUser>()
-            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
-            .eq(SysUser::getUserName, sysUser.getUserName())
-            .ne(ObjectUtil.isNotNull(sysUser.getUserId()), SysUser::getUserId, sysUser.getUserId()));
+        boolean exist = TenantHelper.dynamic(tenantId, () -> {
+            return userMapper.exists(new LambdaQueryWrapper<SysUser>()
+                .eq(SysUser::getUserName, sysUser.getUserName())
+                .ne(ObjectUtil.isNotNull(sysUser.getUserId()), SysUser::getUserId, sysUser.getUserId()));
+        });
         if (exist) {
             throw new UserException("user.register.save.error", username);
         }
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java
index 99686eb..a2636bc 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java
@@ -69,9 +69,6 @@
         // 鐢熸垚token
         LoginHelper.login(loginUser, model);
 
-        loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        loginService.recordLoginInfo(user.getUserId());
-
         LoginVo loginVo = new LoginVo();
         loginVo.setAccessToken(StpUtil.getTokenValue());
         loginVo.setExpireIn(StpUtil.getTokenTimeout());
@@ -92,21 +89,19 @@
     }
 
     private SysUserVo loadUserByEmail(String tenantId, String email) {
-        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-            .select(SysUser::getEmail, SysUser::getStatus)
-            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
-            .eq(SysUser::getEmail, email));
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", email);
-            throw new UserException("user.not.exists", email);
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", email);
-            throw new UserException("user.blocked", email);
-        }
-        if (TenantHelper.isEnable()) {
-            return userMapper.selectTenantUserByEmail(email, tenantId);
-        }
-        return userMapper.selectUserByEmail(email);
+        return TenantHelper.dynamic(tenantId, () -> {
+            SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+                .select(SysUser::getEmail, SysUser::getStatus)
+                .eq(SysUser::getEmail, email));
+            if (ObjectUtil.isNull(user)) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", email);
+                throw new UserException("user.not.exists", email);
+            } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", email);
+                throw new UserException("user.blocked", email);
+            }
+            return userMapper.selectUserByEmail(email);
+        });
     }
 
 }
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java
index 95c7aed..bcb5916 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java
@@ -79,9 +79,6 @@
         // 鐢熸垚token
         LoginHelper.login(loginUser, model);
 
-        loginService.recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        loginService.recordLoginInfo(user.getUserId());
-
         LoginVo loginVo = new LoginVo();
         loginVo.setAccessToken(StpUtil.getTokenValue());
         loginVo.setExpireIn(StpUtil.getTokenTimeout());
@@ -111,21 +108,19 @@
     }
 
     private SysUserVo loadUserByUsername(String tenantId, String username) {
-        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-            .select(SysUser::getUserName, SysUser::getStatus)
-            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
-            .eq(SysUser::getUserName, username));
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", username);
-            throw new UserException("user.not.exists", username);
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", username);
-            throw new UserException("user.blocked", username);
-        }
-        if (TenantHelper.isEnable()) {
-            return userMapper.selectTenantUserByUserName(username, tenantId);
-        }
-        return userMapper.selectUserByUserName(username);
+        return TenantHelper.dynamic(tenantId, () -> {
+            SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+                .select(SysUser::getUserName, SysUser::getStatus)
+                .eq(SysUser::getUserName, username));
+            if (ObjectUtil.isNull(user)) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", username);
+                throw new UserException("user.not.exists", username);
+            } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", username);
+                throw new UserException("user.blocked", username);
+            }
+            return userMapper.selectUserByUserName(username);
+        });
     }
 
 }
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java
index 8f64ce1..a4fa11c 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java
@@ -69,9 +69,6 @@
         // 鐢熸垚token
         LoginHelper.login(loginUser, model);
 
-        loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        loginService.recordLoginInfo(user.getUserId());
-
         LoginVo loginVo = new LoginVo();
         loginVo.setAccessToken(StpUtil.getTokenValue());
         loginVo.setExpireIn(StpUtil.getTokenTimeout());
@@ -92,21 +89,19 @@
     }
 
     private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) {
-        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
-            .select(SysUser::getPhonenumber, SysUser::getStatus)
-            .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
-            .eq(SysUser::getPhonenumber, phonenumber));
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", phonenumber);
-            throw new UserException("user.not.exists", phonenumber);
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", phonenumber);
-            throw new UserException("user.blocked", phonenumber);
-        }
-        if (TenantHelper.isEnable()) {
-            return userMapper.selectTenantUserByPhonenumber(phonenumber, tenantId);
-        }
-        return userMapper.selectUserByPhonenumber(phonenumber);
+        return TenantHelper.dynamic(tenantId, () -> {
+            SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+                .select(SysUser::getPhonenumber, SysUser::getStatus)
+                .eq(SysUser::getPhonenumber, phonenumber));
+            if (ObjectUtil.isNull(user)) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", phonenumber);
+                throw new UserException("user.not.exists", phonenumber);
+            } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", phonenumber);
+                throw new UserException("user.blocked", phonenumber);
+            }
+            return userMapper.selectUserByPhonenumber(phonenumber);
+        });
     }
 
 }
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java
index 64a9e97..a12386e 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java
@@ -2,9 +2,9 @@
 
 import cn.dev33.satoken.stp.SaLoginModel;
 import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.http.Method;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -12,13 +12,11 @@
 import lombok.extern.slf4j.Slf4j;
 import me.zhyd.oauth.model.AuthResponse;
 import me.zhyd.oauth.model.AuthUser;
-import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.domain.model.LoginUser;
 import org.dromara.common.core.domain.model.SocialLoginBody;
 import org.dromara.common.core.enums.UserStatus;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.exception.user.UserException;
-import org.dromara.common.core.utils.MessageUtils;
 import org.dromara.common.core.utils.ValidatorUtils;
 import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
@@ -35,6 +33,9 @@
 import org.dromara.web.service.IAuthStrategy;
 import org.dromara.web.service.SysLoginService;
 import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
 
 /**
  * 绗笁鏂规巿鏉冪瓥鐣�
@@ -78,19 +79,17 @@
                     .executeAsync();
         }
 
-        SysSocialVo social = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid());
-        if (!ObjectUtil.isNotNull(social)) {
+        List<SysSocialVo> list = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid());
+        if (CollUtil.isEmpty(list)) {
             throw new ServiceException("浣犺繕娌℃湁缁戝畾绗笁鏂硅处鍙凤紝缁戝畾鍚庢墠鍙互鐧诲綍锛�");
         }
-        // 楠岃瘉鎺堟潈琛ㄩ噷闈㈢殑绉熸埛id鏄惁鍖呭惈褰撳墠绉熸埛id
-        String tenantId = social.getTenantId();
-        if (ObjectUtil.isNotNull(social) && StrUtil.isNotBlank(tenantId)
-                && !tenantId.contains(loginBody.getTenantId())) {
+        Optional<SysSocialVo> opt = list.stream().filter(x -> x.getTenantId().equals(loginBody.getTenantId())).findAny();
+        if (opt.isEmpty()) {
             throw new ServiceException("瀵逛笉璧凤紝浣犳病鏈夋潈闄愮櫥褰曞綋鍓嶇鎴凤紒");
         }
-
+        SysSocialVo social = opt.get();
         // 鏌ユ壘鐢ㄦ埛
-        SysUserVo user = loadUser(tenantId, social.getUserId());
+        SysUserVo user = loadUser(social.getTenantId(), social.getUserId());
 
         // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜�
         LoginUser loginUser = loginService.buildLoginUser(user);
@@ -106,9 +105,6 @@
         // 鐢熸垚token
         LoginHelper.login(loginUser, model);
 
-        loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        loginService.recordLoginInfo(user.getUserId());
-
         LoginVo loginVo = new LoginVo();
         loginVo.setAccessToken(StpUtil.getTokenValue());
         loginVo.setExpireIn(StpUtil.getTokenTimeout());
@@ -117,21 +113,19 @@
     }
 
     private SysUserVo loadUser(String tenantId, Long userId) {
-        SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+        return TenantHelper.dynamic(tenantId, () -> {
+            SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                 .select(SysUser::getUserName, SysUser::getStatus)
-                .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
                 .eq(SysUser::getUserId, userId));
-        if (ObjectUtil.isNull(user)) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", "");
-            throw new UserException("user.not.exists", "");
-        } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
-            log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", "");
-            throw new UserException("user.blocked", "");
-        }
-        if (TenantHelper.isEnable()) {
-            return userMapper.selectTenantUserByUserName(user.getUserName(), tenantId);
-        }
-        return userMapper.selectUserByUserName(user.getUserName());
+            if (ObjectUtil.isNull(user)) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 涓嶅瓨鍦�.", "");
+                throw new UserException("user.not.exists", "");
+            } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+                log.info("鐧诲綍鐢ㄦ埛锛歿} 宸茶鍋滅敤.", "");
+                throw new UserException("user.blocked", "");
+            }
+            return userMapper.selectUserByUserName(user.getUserName());
+        });
     }
 
 }
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java
index f227dc1..e5aef1f 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java
@@ -5,11 +5,9 @@
 import cn.hutool.core.util.ObjectUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.domain.model.XcxLoginBody;
 import org.dromara.common.core.domain.model.XcxLoginUser;
 import org.dromara.common.core.enums.UserStatus;
-import org.dromara.common.core.utils.MessageUtils;
 import org.dromara.common.core.utils.ValidatorUtils;
 import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
@@ -67,9 +65,6 @@
         model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
         // 鐢熸垚token
         LoginHelper.login(loginUser, model);
-
-        loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
-        loginService.recordLoginInfo(user.getUserId());
 
         LoginVo loginVo = new LoginVo();
         loginVo.setAccessToken(StpUtil.getTokenValue());
diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index b168542..4aaea57 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -15,7 +15,7 @@
     enabled: false
     # 闇�瑕佸厛鍦� powerjob 鐧诲綍椤垫墽琛屽簲鐢ㄦ敞鍐屽悗鎵嶈兘浣跨敤
     app-name: ruoyi-worker
-    enable-test-mode: false
+    allow-lazy-connect-server: false
     max-appended-wf-context-length: 4096
     max-result-length: 4096
     # 28080 绔彛 闅忕潃涓诲簲鐢ㄧ鍙i閫� 閬垮厤闆嗙兢鍐茬獊
@@ -60,8 +60,6 @@
 #          url: jdbc:oracle:thin:@//localhost:1521/XE
 #          username: ROOT
 #          password: root
-#          hikari:
-#            connectionTestQuery: SELECT 1 FROM DUAL
 #        postgres:
 #          type: ${spring.datasource.type}
 #          driverClassName: org.postgresql.Driver
@@ -87,8 +85,6 @@
         idleTimeout: 600000
         # 姝ゅ睘鎬ф帶鍒舵睜涓繛鎺ョ殑鏈�闀跨敓鍛藉懆鏈燂紝鍊�0琛ㄧず鏃犻檺鐢熷懡鍛ㄦ湡锛岄粯璁�30鍒嗛挓
         maxLifetime: 1800000
-        # 杩炴帴娴嬭瘯query锛堥厤缃娴嬭繛鎺ユ槸鍚︽湁鏁堬級
-        connectionTestQuery: SELECT 1
         # 澶氫箙妫�鏌ヤ竴娆¤繛鎺ョ殑娲绘��
         keepaliveTime: 30000
 
diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml
index 148b50e..782a680 100644
--- a/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-admin/src/main/resources/application-prod.yml
@@ -18,7 +18,7 @@
     enabled: false
     # 闇�瑕佸厛鍦� powerjob 鐧诲綍椤垫墽琛屽簲鐢ㄦ敞鍐屽悗鎵嶈兘浣跨敤
     app-name: ruoyi-worker
-    enable-test-mode: false
+    allow-lazy-connect-server: false
     max-appended-wf-context-length: 4096
     max-result-length: 4096
     # 28080 绔彛 闅忕潃涓诲簲鐢ㄧ鍙i閫� 閬垮厤闆嗙兢鍐茬獊
@@ -63,8 +63,6 @@
 #          url: jdbc:oracle:thin:@//localhost:1521/XE
 #          username: ROOT
 #          password: root
-#          hikari:
-#            connectionTestQuery: SELECT 1 FROM DUAL
 #        postgres:
 #          type: ${spring.datasource.type}
 #          driverClassName: org.postgresql.Driver
@@ -90,8 +88,6 @@
         idleTimeout: 600000
         # 姝ゅ睘鎬ф帶鍒舵睜涓繛鎺ョ殑鏈�闀跨敓鍛藉懆鏈燂紝鍊�0琛ㄧず鏃犻檺鐢熷懡鍛ㄦ湡锛岄粯璁�30鍒嗛挓
         maxLifetime: 1800000
-        # 杩炴帴娴嬭瘯query锛堥厤缃娴嬭繛鎺ユ槸鍚︽湁鏁堬級
-        connectionTestQuery: SELECT 1
         # 澶氫箙妫�鏌ヤ竴娆¤繛鎺ョ殑娲绘��
         keepaliveTime: 30000
 
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index ae20371..3f54f64 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -133,6 +133,7 @@
     - sys_user_post
     - sys_user_role
     - sys_client
+    - sys_oss_config
 
 # MyBatisPlus閰嶇疆
 # https://baomidou.com/config/
@@ -171,8 +172,11 @@
   enabled: true
   # AES 鍔犲瘑澶存爣璇�
   headerFlag: encrypt-key
-  # 鍏閽� 闈炲绉扮畻娉曠殑鍏閽� 濡傦細SM2锛孯SA 浣跨敤鑰呰鑷鏇存崲
-  publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==
+  # 鍝嶅簲鍔犲瘑鍏挜 闈炲绉扮畻娉曠殑鍏閽� 濡傦細SM2锛孯SA 浣跨敤鑰呰鑷鏇存崲
+  # 瀵瑰簲鍓嶇瑙e瘑绉侀挜 MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=
+  publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnNwrj4hi/y3CCJu868ghCG5dUj8wZK++RNlTLcXoMmdZWEQ/u02RgD5LyLAXGjLOjbMtC+/J9qofpSGTKSx/MCAwEAAQ==
+  # 璇锋眰瑙e瘑绉侀挜 闈炲绉扮畻娉曠殑鍏閽� 濡傦細SM2锛孯SA 浣跨敤鑰呰鑷鏇存崲
+  # 瀵瑰簲鍓嶇鍔犲瘑鍏挜 MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==
   privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y=
 
 springdoc:
diff --git a/ruoyi-admin/src/main/resources/i18n/messages.properties b/ruoyi-admin/src/main/resources/i18n/messages.properties
index c863561..cce11c8 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages.properties
@@ -50,7 +50,10 @@
 email.code.not.blank=閭楠岃瘉鐮佷笉鑳戒负绌�
 email.code.retry.limit.count=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆�
 email.code.retry.limit.exceed=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆★紝甯愭埛閿佸畾{1}鍒嗛挓
-xcx.code.not.blank=灏忕▼搴廲ode涓嶈兘涓虹┖
+xcx.code.not.blank=灏忕▼搴廩code]涓嶈兘涓虹┖
+social.source.not.blank=绗笁鏂圭櫥褰曞钩鍙癧source]涓嶈兘涓虹┖
+social.code.not.blank=绗笁鏂圭櫥褰曞钩鍙癧code]涓嶈兘涓虹┖
+social.state.not.blank=绗笁鏂圭櫥褰曞钩鍙癧state]涓嶈兘涓虹┖
 ##绉熸埛
 tenant.number.not.blank=绉熸埛缂栧彿涓嶈兘涓虹┖
 tenant.not.exists=瀵逛笉璧�, 鎮ㄧ殑绉熸埛涓嶅瓨鍦紝璇疯仈绯荤鐞嗗憳
diff --git a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
index 355da84..f948c4a 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages_en_US.properties
@@ -50,7 +50,10 @@
 email.code.not.blank=Email code cannot be blank
 email.code.retry.limit.count=Email code input error {0} times
 email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes
-xcx.code.not.blank=Mini program code cannot be blank
+xcx.code.not.blank=Mini program [code] cannot be blank
+social.source.not.blank=Social login platform [source] cannot be blank
+social.code.not.blank=Social login platform [code] cannot be blank
+social.state.not.blank=Social login platform [state] cannot be blank
 ##绉熸埛
 tenant.number.not.blank=Tenant number cannot be blank
 tenant.not.exists=Sorry, your tenant does not exist. Please contact the administrator
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 c863561..cce11c8 100644
--- a/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
+++ b/ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties
@@ -50,7 +50,10 @@
 email.code.not.blank=閭楠岃瘉鐮佷笉鑳戒负绌�
 email.code.retry.limit.count=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆�
 email.code.retry.limit.exceed=閭楠岃瘉鐮佽緭鍏ラ敊璇瘂0}娆★紝甯愭埛閿佸畾{1}鍒嗛挓
-xcx.code.not.blank=灏忕▼搴廲ode涓嶈兘涓虹┖
+xcx.code.not.blank=灏忕▼搴廩code]涓嶈兘涓虹┖
+social.source.not.blank=绗笁鏂圭櫥褰曞钩鍙癧source]涓嶈兘涓虹┖
+social.code.not.blank=绗笁鏂圭櫥褰曞钩鍙癧code]涓嶈兘涓虹┖
+social.state.not.blank=绗笁鏂圭櫥褰曞钩鍙癧state]涓嶈兘涓虹┖
 ##绉熸埛
 tenant.number.not.blank=绉熸埛缂栧彿涓嶈兘涓虹┖
 tenant.not.exists=瀵逛笉璧�, 鎮ㄧ殑绉熸埛涓嶅瓨鍦紝璇疯仈绯荤鐞嗗憳
diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml
index 66a9ec8..004b035 100644
--- a/ruoyi-common/ruoyi-common-bom/pom.xml
+++ b/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -14,7 +14,7 @@
     </description>
 
     <properties>
-        <revision>5.1.1</revision>
+        <revision>5.1.2</revision>
     </properties>
 
     <dependencyManagement>
diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml
index 33f9f7f..ad37e90 100644
--- a/ruoyi-common/ruoyi-common-core/pom.xml
+++ b/ruoyi-common/ruoyi-common-core/pom.xml
@@ -67,12 +67,6 @@
         </dependency>
 
         <dependency>
-            <groupId>cn.hutool</groupId>
-            <artifactId>hutool-json</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
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 c3425d0..e59277a 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
@@ -41,6 +41,11 @@
     String SYS_USER_NAME = "sys_user_name#30d";
 
     /**
+     * 鐢ㄦ埛鍚嶇О
+     */
+    String SYS_NICKNAME = "sys_nickname#30d";
+
+    /**
      * 閮ㄩ棬
      */
     String SYS_DEPT = "sys_dept#30d";
@@ -53,7 +58,7 @@
     /**
      * OSS閰嶇疆
      */
-    String SYS_OSS_CONFIG = "sys_oss_config";
+    String SYS_OSS_CONFIG = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss_config";
 
     /**
      * 鍦ㄧ嚎鐢ㄦ埛
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java
deleted file mode 100644
index 9916ddf..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.dromara.common.core.exception;
-
-import java.io.Serial;
-
-/**
- * 婕旂ず妯″紡寮傚父
- *
- * @author ruoyi
- */
-public class DemoModeException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public DemoModeException() {
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java
deleted file mode 100644
index 76b1265..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.dromara.common.core.exception;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-
-/**
- * 鍏ㄥ眬寮傚父
- *
- * @author ruoyi
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@NoArgsConstructor
-@AllArgsConstructor
-public class GlobalException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 閿欒鎻愮ず
-     */
-    private String message;
-
-    /**
-     * 閿欒鏄庣粏锛屽唴閮ㄨ皟璇曢敊璇�
-     */
-    private String detailMessage;
-
-    public GlobalException(String message) {
-        this.message = message;
-    }
-
-    public String getDetailMessage() {
-        return detailMessage;
-    }
-
-    public GlobalException setDetailMessage(String detailMessage) {
-        this.detailMessage = detailMessage;
-        return this;
-    }
-
-    @Override
-    public String getMessage() {
-        return message;
-    }
-
-    public GlobalException setMessage(String message) {
-        this.message = message;
-        return this;
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java
deleted file mode 100644
index a9bf2c6..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.dromara.common.core.exception;
-
-import java.io.Serial;
-
-/**
- * 宸ュ叿绫诲紓甯�
- *
- * @author ruoyi
- */
-public class UtilException extends RuntimeException {
-
-    @Serial
-    private static final long serialVersionUID = 8247610319171014183L;
-
-    public UtilException(Throwable e) {
-        super(e.getMessage(), e);
-    }
-
-    public UtilException(String message) {
-        super(message);
-    }
-
-    public UtilException(String message, Throwable throwable) {
-        super(message, throwable);
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java
deleted file mode 100644
index 289cca7..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.dromara.common.core.exception.user;
-
-import java.io.Serial;
-
-/**
- * 鐢ㄦ埛瀵嗙爜涓嶆纭垨涓嶇鍚堣鑼冨紓甯哥被
- *
- * @author ruoyi
- */
-public class UserPasswordNotMatchException extends UserException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public UserPasswordNotMatchException() {
-        super("user.password.not.match");
-    }
-}
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java
deleted file mode 100644
index 2facdeb..0000000
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.dromara.common.core.exception.user;
-
-import java.io.Serial;
-
-/**
- * 鐢ㄦ埛閿欒鏈�澶ф鏁板紓甯哥被
- *
- * @author ruoyi
- */
-public class UserPasswordRetryLimitExceedException extends UserException {
-
-    @Serial
-    private static final long serialVersionUID = 1L;
-
-    public UserPasswordRetryLimitExceedException(int retryLimitCount, int lockTime) {
-        super("user.password.retry.limit.exceed", retryLimitCount, lockTime);
-    }
-
-}
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 554e506..d6b312a 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
@@ -15,4 +15,12 @@
      */
     String selectUserNameById(Long userId);
 
+    /**
+     * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛璐︽埛
+     *
+     * @param userId 鐢ㄦ埛ID
+     * @return 鐢ㄦ埛璐︽埛
+     */
+    String selectNicknameById(Long userId);
+
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
index 1ed01a9..3e109b2 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java
@@ -1,9 +1,8 @@
 package org.dromara.common.core.utils.sql;
 
-import org.dromara.common.core.exception.UtilException;
-import org.dromara.common.core.utils.StringUtils;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import org.dromara.common.core.utils.StringUtils;
 
 /**
  * sql鎿嶄綔宸ュ叿绫�
@@ -28,7 +27,7 @@
      */
     public static String escapeOrderBySql(String value) {
         if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
-            throw new UtilException("鍙傛暟涓嶇鍚堣鑼冿紝涓嶈兘杩涜鏌ヨ");
+            throw new IllegalArgumentException("鍙傛暟涓嶇鍚堣鑼冿紝涓嶈兘杩涜鏌ヨ");
         }
         return value;
     }
@@ -50,7 +49,7 @@
         String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
         for (String sqlKeyword : sqlKeywords) {
             if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
-                throw new UtilException("鍙傛暟瀛樺湪SQL娉ㄥ叆椋庨櫓");
+                throw new IllegalArgumentException("鍙傛暟瀛樺湪SQL娉ㄥ叆椋庨櫓");
             }
         }
     }
diff --git a/ruoyi-common/ruoyi-common-encrypt/pom.xml b/ruoyi-common/ruoyi-common-encrypt/pom.xml
index 7f58063..df3222b 100644
--- a/ruoyi-common/ruoyi-common-encrypt/pom.xml
+++ b/ruoyi-common/ruoyi-common-encrypt/pom.xml
@@ -37,6 +37,11 @@
             <artifactId>hutool-crypto</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java
new file mode 100644
index 0000000..7f52de8
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java
@@ -0,0 +1,20 @@
+package org.dromara.common.encrypt.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 寮哄埗鍔犲瘑娉ㄨВ
+ *
+ * @author Michelle.Chung
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ApiEncrypt {
+
+    /**
+     * 鍝嶅簲鍔犲瘑蹇界暐锛岄粯璁や笉鍔犲瘑锛屼负 true 鏃跺姞瀵�
+     */
+    boolean response() default false;
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java
index c31e025..84b85d3 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java
@@ -3,10 +3,19 @@
 import cn.hutool.core.util.ObjectUtil;
 import jakarta.servlet.*;
 import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.dromara.common.core.constant.HttpStatus;
+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.encrypt.annotation.ApiEncrypt;
 import org.dromara.common.encrypt.properties.ApiDecryptProperties;
 import org.springframework.http.HttpMethod;
 import org.springframework.http.MediaType;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.HandlerExecutionChain;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
 
 import java.io.IOException;
 
@@ -25,8 +34,14 @@
 
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-        ServletRequest requestWrapper = null;
         HttpServletRequest servletRequest = (HttpServletRequest) request;
+        HttpServletResponse servletResponse = (HttpServletResponse) response;
+
+        boolean encryptFlag = false;
+        ServletRequest requestWrapper = null;
+        ServletResponse responseWrapper = null;
+        EncryptResponseBodyWrapper responseBodyWrapper = null;
+
         // 鏄惁涓� json 璇锋眰
         if (StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
             // 鏄惁涓� put 鎴栬�� post 璇锋眰
@@ -34,16 +49,67 @@
                 // 鏄惁瀛樺湪鍔犲瘑鏍囧ご
                 String headerValue = servletRequest.getHeader(properties.getHeaderFlag());
                 if (StringUtils.isNotBlank(headerValue)) {
-                    requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPublicKey(), properties.getPrivateKey(), properties.getHeaderFlag());
+                    // 璇锋眰瑙e瘑
+                    requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag());
+                    // 鑾峰彇鍔犲瘑娉ㄨВ
+                    ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest);
+                    if (ObjectUtil.isNotNull(apiEncrypt)) {
+                        // 鍝嶅簲鍔犲瘑鏍囧織
+                        encryptFlag = apiEncrypt.response();
+                    } else {
+                        // 鏄惁鏈夋敞瑙o紝鏈夊氨鎶ラ敊锛屾病鏈夋斁琛�
+                        HandlerExceptionResolver exceptionResolver = SpringUtils.getBean(HandlerExceptionResolver.class);
+                        exceptionResolver.resolveException(
+                            servletRequest, servletResponse, null,
+                            new ServiceException("娌℃湁璁块棶鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉�", HttpStatus.FORBIDDEN));
+                    }
+                }
+                // 鍒ゆ柇鏄惁鍝嶅簲鍔犲瘑
+                if (encryptFlag) {
+                    responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse);
+                    responseWrapper = responseBodyWrapper;
                 }
             }
         }
 
-        chain.doFilter(ObjectUtil.defaultIfNull(requestWrapper, request), response);
+        chain.doFilter(
+            ObjectUtil.defaultIfNull(requestWrapper, request),
+            ObjectUtil.defaultIfNull(responseWrapper, response));
+
+        if (encryptFlag) {
+            servletResponse.reset();
+            // 瀵瑰師濮嬪唴瀹瑰姞瀵�
+            String encryptContent = responseBodyWrapper.getEncryptContent(
+                servletResponse, properties.getPublicKey(), properties.getHeaderFlag());
+            // 瀵瑰姞瀵嗗悗鐨勫唴瀹瑰啓鍑�
+            servletResponse.getWriter().write(encryptContent);
+        }
+    }
+
+    /**
+     * 鑾峰彇 ApiEncrypt 娉ㄨВ
+     */
+    private ApiEncrypt getApiEncryptAnnotation(HttpServletRequest servletRequest) {
+        RequestMappingHandlerMapping handlerMapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class);
+        // 鑾峰彇娉ㄨВ
+        try {
+            HandlerExecutionChain mappingHandler = handlerMapping.getHandler(servletRequest);
+            if (ObjectUtil.isNotNull(mappingHandler)) {
+                Object handler = mappingHandler.getHandler();
+                if (ObjectUtil.isNotNull(handler)) {
+                    // 浠巋andler鑾峰彇娉ㄨВ
+                    if (handler instanceof HandlerMethod handlerMethod) {
+                        return handlerMethod.getMethodAnnotation(ApiEncrypt.class);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return null;
     }
 
     @Override
     public void destroy() {
-
     }
 }
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java
index fa9a310..98f4bc7 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java
@@ -24,7 +24,7 @@
 
     private final byte[] body;
 
-    public DecryptRequestBodyWrapper(HttpServletRequest request, String publicKey, String privateKey, String headerFlag) throws IOException {
+    public DecryptRequestBodyWrapper(HttpServletRequest request, String privateKey, String headerFlag) throws IOException {
         super(request);
         // 鑾峰彇 AES 瀵嗙爜 閲囩敤 RSA 鍔犲瘑
         String headerRsa = request.getHeader(headerFlag);
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java
new file mode 100644
index 0000000..05cf444
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java
@@ -0,0 +1,120 @@
+package org.dromara.common.encrypt.filter;
+
+import cn.hutool.core.util.RandomUtil;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.WriteListener;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpServletResponseWrapper;
+import org.dromara.common.encrypt.utils.EncryptUtils;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 鍔犲瘑鍝嶅簲鍙傛暟鍖呰绫�
+ *
+ * @author Michelle.Chung
+ */
+public class EncryptResponseBodyWrapper extends HttpServletResponseWrapper {
+
+    private final ByteArrayOutputStream byteArrayOutputStream;
+    private final ServletOutputStream servletOutputStream;
+    private final PrintWriter printWriter;
+
+    public EncryptResponseBodyWrapper(HttpServletResponse response) throws IOException {
+        super(response);
+        this.byteArrayOutputStream = new ByteArrayOutputStream();
+        this.servletOutputStream = this.getOutputStream();
+        this.printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream));
+    }
+
+    @Override
+    public PrintWriter getWriter() {
+        return printWriter;
+    }
+
+    @Override
+    public void flushBuffer() throws IOException {
+        if (servletOutputStream != null) {
+            servletOutputStream.flush();
+        }
+        if (printWriter != null) {
+            printWriter.flush();
+        }
+    }
+
+    @Override
+    public void reset() {
+        byteArrayOutputStream.reset();
+    }
+
+    public byte[] getResponseData() throws IOException {
+        flushBuffer();
+        return byteArrayOutputStream.toByteArray();
+    }
+
+    public String getContent() throws IOException {
+        flushBuffer();
+        return byteArrayOutputStream.toString();
+    }
+
+    /**
+     * 鑾峰彇鍔犲瘑鍐呭
+     *
+     * @param servletResponse response
+     * @param publicKey       RSA鍏挜 (鐢ㄤ簬鍔犲瘑 AES 绉橀挜)
+     * @param headerFlag      璇锋眰澶存爣蹇�
+     * @return 鍔犲瘑鍐呭
+     * @throws IOException
+     */
+    public String getEncryptContent(HttpServletResponse servletResponse, String publicKey, String headerFlag) throws IOException {
+        // 鐢熸垚绉橀挜
+        String aesPassword = RandomUtil.randomString(32);
+        // 绉橀挜浣跨敤 Base64 缂栫爜
+        String encryptAes = EncryptUtils.encryptByBase64(aesPassword);
+        // Rsa 鍏挜鍔犲瘑 Base64 缂栫爜
+        String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey);
+
+        // 璁剧疆鍝嶅簲澶�
+        servletResponse.setHeader(headerFlag, encryptPassword);
+        servletResponse.setHeader("Access-Control-Allow-Origin", "*");
+        servletResponse.setHeader("Access-Control-Allow-Methods", "*");
+        servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString());
+
+        // 鑾峰彇鍘熷鍐呭
+        String originalBody = this.getContent();
+        // 瀵瑰唴瀹硅繘琛屽姞瀵�
+        return EncryptUtils.encryptByAes(originalBody, aesPassword);
+    }
+
+    @Override
+    public ServletOutputStream getOutputStream() throws IOException {
+        return new ServletOutputStream() {
+            @Override
+            public boolean isReady() {
+                return false;
+            }
+
+            @Override
+            public void setWriteListener(WriteListener writeListener) {
+
+            }
+
+            @Override
+            public void write(int b) throws IOException {
+                byteArrayOutputStream.write(b);
+            }
+
+            @Override
+            public void write(byte[] b) throws IOException {
+                byteArrayOutputStream.write(b);
+            }
+
+            @Override
+            public void write(byte[] b, int off, int len) throws IOException {
+                byteArrayOutputStream.write(b, off, len);
+            }
+        };
+    }
+
+}
diff --git a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java
index 9e25b7b..6aadb3e 100644
--- a/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java
+++ b/ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java
@@ -21,14 +21,14 @@
      */
     private String headerFlag;
 
-
     /**
-     * 鍏挜
+     * 鍝嶅簲鍔犲瘑鍏挜
      */
     private String publicKey;
 
     /**
-     * 绉侀挜
+     * 璇锋眰瑙e瘑绉侀挜
      */
     private String privateKey;
+
 }
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java
index 08f4dda..bcb5be7 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java
@@ -98,9 +98,30 @@
                             cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
                         }
                         map.put(field, new RepeatCell(val, i));
-                    } else if (i == list.size() - 1) {
-                        if (i > repeatCell.getCurrent()) {
-                            cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+                    } else if (j == 0) {
+                        if (i == list.size() - 1) {
+                            if (i > repeatCell.getCurrent()) {
+                                cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+                            }
+                        }
+                    } else {
+                        // 鍒ゆ柇鍓嶉潰鐨勬槸鍚﹀悎骞朵簡
+                        RepeatCell firstCell = map.get(mergeFields.get(0));
+                        if (repeatCell.getCurrent() != firstCell.getCurrent()) {
+                            if (i == list.size() - 1) {
+                                if (i > repeatCell.getCurrent()) {
+                                    cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+                                }
+                            } else if (repeatCell.getCurrent() < firstCell.getCurrent()) {
+                                if (i - repeatCell.getCurrent() > 1) {
+                                    cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum));
+                                }
+                                map.put(field, new RepeatCell(val, i));
+                            }
+                        } else if (i == list.size() - 1) {
+                            if (i > repeatCell.getCurrent()) {
+                                cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum));
+                            }
                         }
                     }
                 }
diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
index 329911d..a6c14ad 100644
--- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
+++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
@@ -270,6 +270,26 @@
     }
 
     /**
+     * 澶歴heet妯℃澘瀵煎嚭 妯℃澘鏍煎紡涓� {key.灞炴�
+     *
+     * @param filename     鏂囦欢鍚�
+     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
+     *                     渚嬪: excel/temp.xlsx
+     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
+     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
+     * @param response     鍝嶅簲浣�
+     */
+    public static void exportTemplateMultiSheet(List<Map<String, Object>> data, String filename, String templatePath, HttpServletResponse response) {
+        try {
+            resetResponse(filename, response);
+            ServletOutputStream os = response.getOutputStream();
+            exportTemplateMultiSheet(data, templatePath, os);
+        } catch (IOException e) {
+            throw new RuntimeException("瀵煎嚭Excel寮傚父");
+        }
+    }
+
+    /**
      * 澶氳〃澶氭暟鎹ā鏉垮鍑� 妯℃澘鏍煎紡涓� {key.灞炴�
      *
      * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
@@ -304,6 +324,42 @@
     }
 
     /**
+     * 澶歴heet妯℃澘瀵煎嚭 妯℃澘鏍煎紡涓� {key.灞炴�
+     *
+     * @param templatePath 妯℃澘璺緞 resource 鐩綍涓嬬殑璺緞鍖呮嫭妯℃澘鏂囦欢鍚�
+     *                     渚嬪: excel/temp.xlsx
+     *                     閲嶇偣: 妯℃澘鏂囦欢蹇呴』鏀剧疆鍒板惎鍔ㄧ被瀵瑰簲鐨� resource 鐩綍涓�
+     * @param data         妯℃澘闇�瑕佺殑鏁版嵁
+     * @param os           杈撳嚭娴�
+     */
+    public static void exportTemplateMultiSheet(List<Map<String, Object>> data, String templatePath, OutputStream os) {
+        ClassPathResource templateResource = new ClassPathResource(templatePath);
+        ExcelWriter excelWriter = EasyExcel.write(os)
+            .withTemplate(templateResource.getStream())
+            .autoCloseStream(false)
+            // 澶ф暟鍊艰嚜鍔ㄨ浆鎹� 闃叉澶辩湡
+            .registerConverter(new ExcelBigNumberConvert())
+            .build();
+        if (CollUtil.isEmpty(data)) {
+            throw new IllegalArgumentException("鏁版嵁涓虹┖");
+        }
+        for (int i = 0; i < data.size(); i++) {
+            WriteSheet writeSheet = EasyExcel.writerSheet(i).build();
+            for (Map.Entry<String, Object> map : data.get(i).entrySet()) {
+                // 璁剧疆鍒楄〃鍚庣画杩樻湁鏁版嵁
+                FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
+                if (map.getValue() instanceof Collection) {
+                    // 澶氳〃瀵煎嚭蹇呴』浣跨敤 FillWrapper
+                    excelWriter.fill(new FillWrapper(map.getKey(), (Collection<?>) map.getValue()), fillConfig, writeSheet);
+                } else {
+                    excelWriter.fill(map.getValue(), writeSheet);
+                }
+            }
+        }
+        excelWriter.finish();
+    }
+
+    /**
      * 閲嶇疆鍝嶅簲浣�
      */
     private static void resetResponse(String sheetName, HttpServletResponse response) throws UnsupportedEncodingException {
diff --git a/ruoyi-common/ruoyi-common-mybatis/pom.xml b/ruoyi-common/ruoyi-common-mybatis/pom.xml
index 51199b4..2088b54 100644
--- a/ruoyi-common/ruoyi-common-mybatis/pom.xml
+++ b/ruoyi-common/ruoyi-common-mybatis/pom.xml
@@ -33,8 +33,19 @@
         </dependency>
 
         <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.mybatis</groupId>
+                    <artifactId>mybatis-spring</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
         <!-- sql鎬ц兘鍒嗘瀽鎻掍欢 -->
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java
index 64463e6..c517fa7 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java
@@ -35,7 +35,7 @@
     public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
         String requestURI = request.getRequestURI();
         String message = e.getMessage();
-        if (message.contains("CannotFindDataSourceException")) {
+        if ("CannotFindDataSourceException".contains(message)) {
             log.error("璇锋眰鍦板潃'{}', 鏈壘鍒版暟鎹簮", requestURI);
             return R.fail("鏈壘鍒版暟鎹簮锛岃鑱旂郴绠$悊鍛樼‘璁�");
         }
diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java
index aa6a4c0..6ddaa24 100644
--- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java
+++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java
@@ -149,7 +149,12 @@
         int index = sb.lastIndexOf(".");
         String clazzName = sb.substring(0, index);
         String methodName = sb.substring(index + 1, sb.length());
-        Class<?> clazz = ClassUtil.loadClass(clazzName);
+        Class<?> clazz;
+        try {
+            clazz = ClassUtil.loadClass(clazzName);
+        } catch (Exception e) {
+            return null;
+        }
         List<Method> methods = Arrays.stream(ClassUtil.getDeclaredMethods(clazz))
             .filter(method -> method.getName().equals(methodName)).toList();
         DataPermission dataPermission;
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java
index 417f17b..9d8db93 100644
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java
@@ -1,5 +1,7 @@
 package org.dromara.common.oss.constant;
 
+import org.dromara.common.core.constant.GlobalConstants;
+
 import java.util.Arrays;
 import java.util.List;
 
@@ -13,7 +15,7 @@
     /**
      * 榛樿閰嶇疆KEY
      */
-    String DEFAULT_CONFIG_KEY = "sys_oss:default_config";
+    String DEFAULT_CONFIG_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss:default_config";
 
     /**
      * 棰勮鍒楄〃璧勬簮寮�鍏矺ey
diff --git a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
index 6503eb1..763b090 100644
--- a/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
+++ b/ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java
@@ -39,7 +39,7 @@
     /**
      * 鏍规嵁绫诲瀷鑾峰彇瀹炰緥
      */
-    public static OssClient instance(String configKey) {
+    public static synchronized OssClient instance(String configKey) {
         String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);
         if (json == null) {
             throw new OssException("绯荤粺寮傚父, '" + configKey + "'閰嶇疆淇℃伅涓嶅瓨鍦�!");
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
index dcba573..7999f2b 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
@@ -49,6 +49,8 @@
             CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec);
             config.setThreads(redissonProperties.getThreads())
                 .setNettyThreads(redissonProperties.getNettyThreads())
+                // 缂撳瓨 Lua 鑴氭湰 鍑忓皯缃戠粶浼犺緭(redisson 澶ч儴鍒嗙殑鍔熻兘閮芥槸鍩轰簬 Lua 鑴氭湰瀹炵幇)
+                .setUseScriptCache(true)
                 .setCodec(codec);
             RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
             if (ObjectUtil.isNotNull(singleServerConfig)) {
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java
index 67ce552..4587e64 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java
@@ -224,8 +224,12 @@
     /**
      * 璁㈤槄闃诲闃熷垪(鍙闃呮墍鏈夊疄鐜扮被 渚嬪: 寤惰繜 浼樺厛 鏈夌晫 绛�)
      */
-    public static <T> void subscribeBlockingQueue(String queueName, Consumer<T> consumer) {
+    public static <T> void subscribeBlockingQueue(String queueName, Consumer<T> consumer, boolean isDelayed) {
         RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
+        if (isDelayed) {
+            // 璁㈤槄寤惰繜闃熷垪
+            CLIENT.getDelayedQueue(queue);
+        }
         queue.subscribeOnElements(consumer);
     }
 
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java
index 9f59f69..ce32055 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java
@@ -142,6 +142,18 @@
     }
 
     /**
+     * 濡傛灉瀛樺湪鍒欒缃� 骞惰繑鍥� true 濡傛灉瀛樺湪鍒欒繑鍥� false
+     *
+     * @param key   缂撳瓨鐨勯敭鍊�
+     * @param value 缂撳瓨鐨勫��
+     * @return set鎴愬姛鎴栧け璐�
+     */
+    public static <T> boolean setObjectIfExists(final String key, final T value, final Duration duration) {
+        RBucket<T> bucket = CLIENT.getBucket(key);
+        return bucket.setIfExists(value, duration);
+    }
+
+    /**
      * 娉ㄥ唽瀵硅薄鐩戝惉鍣�
      * <p>
      * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
@@ -243,6 +255,18 @@
     }
 
     /**
+     * 杩藉姞缂撳瓨List鏁版嵁
+     *
+     * @param key  缂撳瓨鐨勯敭鍊�
+     * @param data 寰呯紦瀛樼殑鏁版嵁
+     * @return 缂撳瓨鐨勫璞�
+     */
+    public static <T> boolean addCacheList(final String key, final T data) {
+        RList<T> rList = CLIENT.getList(key);
+        return rList.add(data);
+    }
+
+    /**
      * 娉ㄥ唽List鐩戝惉鍣�
      * <p>
      * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
@@ -267,6 +291,19 @@
     }
 
     /**
+     * 鑾峰緱缂撳瓨鐨刲ist瀵硅薄(鑼冨洿)
+     *
+     * @param key  缂撳瓨鐨勯敭鍊�
+     * @param form 璧峰涓嬫爣
+     * @param to   鎴涓嬫爣
+     * @return 缂撳瓨閿�煎搴旂殑鏁版嵁
+     */
+    public static <T> List<T> getCacheListRange(final String key, int form, int to) {
+        RList<T> rList = CLIENT.getList(key);
+        return rList.range(form, to);
+    }
+
+    /**
      * 缂撳瓨Set
      *
      * @param key     缂撳瓨閿��
@@ -279,6 +316,18 @@
     }
 
     /**
+     * 杩藉姞缂撳瓨Set鏁版嵁
+     *
+     * @param key  缂撳瓨鐨勯敭鍊�
+     * @param data 寰呯紦瀛樼殑鏁版嵁
+     * @return 缂撳瓨鐨勫璞�
+     */
+    public static <T> boolean addCacheSet(final String key, final T data) {
+        RSet<T> rSet = CLIENT.getSet(key);
+        return rSet.add(data);
+    }
+
+    /**
      * 娉ㄥ唽Set鐩戝惉鍣�
      * <p>
      * key 鐩戝惉鍣ㄩ渶寮�鍚� `notify-keyspace-events` 绛� redis 鐩稿叧閰嶇疆
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java
index aef8a66..ce8d85c 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java
@@ -10,7 +10,6 @@
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.PropertySource;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 /**
  * sa-token 閰嶇疆
@@ -19,7 +18,7 @@
  */
 @AutoConfiguration
 @PropertySource(value = "classpath:common-satoken.yml", factory = YmlPropertySourceFactory.class)
-public class SaTokenConfig implements WebMvcConfigurer {
+public class SaTokenConfig {
 
     @Bean
     public StpLogic getStpLogicJwt() {
diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
index 8d2aac9..d885962 100644
--- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
+++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java
@@ -45,12 +45,9 @@
      */
     @Override
     public void update(String key, String value) {
-        long expire = getTimeout(key);
-        // -2 = 鏃犳閿�
-        if (expire == NOT_VALUE_EXPIRE) {
-            return;
+        if (RedisUtils.hasKey(key)) {
+            RedisUtils.setCacheObject(key, value, true);
         }
-        this.set(key, value, expire);
     }
 
     /**
@@ -75,17 +72,6 @@
      */
     @Override
     public void updateTimeout(String key, long timeout) {
-        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
-        if (timeout == NEVER_EXPIRE) {
-            long expire = getTimeout(key);
-            if (expire == NEVER_EXPIRE) {
-                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
-            } else {
-                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
-                this.set(key, this.get(key), timeout);
-            }
-            return;
-        }
         RedisUtils.expire(key, Duration.ofSeconds(timeout));
     }
 
@@ -119,12 +105,9 @@
      */
     @Override
     public void updateObject(String key, Object object) {
-        long expire = getObjectTimeout(key);
-        // -2 = 鏃犳閿�
-        if (expire == NOT_VALUE_EXPIRE) {
-            return;
+        if (RedisUtils.hasKey(key)) {
+            RedisUtils.setCacheObject(key, object, true);
         }
-        this.setObject(key, object, expire);
     }
 
     /**
@@ -149,17 +132,6 @@
      */
     @Override
     public void updateObjectTimeout(String key, long timeout) {
-        // 鍒ゆ柇鏄惁鎯宠璁剧疆涓烘案涔�
-        if (timeout == NEVER_EXPIRE) {
-            long expire = getObjectTimeout(key);
-            if (expire == NEVER_EXPIRE) {
-                // 濡傛灉鍏跺凡缁忚璁剧疆涓烘案涔咃紝鍒欎笉浣滀换浣曞鐞�
-            } else {
-                // 濡傛灉灏氭湭琚缃负姘镐箙锛岄偅涔堝啀娆et涓�娆�
-                this.setObject(key, this.getObject(key), timeout);
-            }
-            return;
-        }
         RedisUtils.expire(key, Duration.ofSeconds(timeout));
     }
 
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 97b7041..2406ba9 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
@@ -15,6 +15,7 @@
 import org.dromara.common.core.enums.UserType;
 
 import java.util.Set;
+import java.util.function.Supplier;
 
 /**
  * 鐧诲綍閴存潈鍔╂墜
@@ -36,6 +37,7 @@
     public static final String USER_KEY = "userId";
     public static final String DEPT_KEY = "deptId";
     public static final String CLIENT_KEY = "clientid";
+    public static final String TENANT_ADMIN_KEY = "isTenantAdmin";
 
     /**
      * 鐧诲綍绯荤粺 鍩轰簬 璁惧绫诲瀷
@@ -55,32 +57,27 @@
             model.setExtra(TENANT_KEY, loginUser.getTenantId())
                 .setExtra(USER_KEY, loginUser.getUserId())
                 .setExtra(DEPT_KEY, loginUser.getDeptId()));
-        StpUtil.getSession().set(LOGIN_USER_KEY, loginUser);
+        StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
     }
 
     /**
      * 鑾峰彇鐢ㄦ埛(澶氱骇缂撳瓨)
      */
     public static LoginUser getLoginUser() {
-        LoginUser loginUser = (LoginUser) SaHolder.getStorage().get(LOGIN_USER_KEY);
-        if (loginUser != null) {
-            return loginUser;
-        }
-        SaSession session = StpUtil.getSession();
-        if (ObjectUtil.isNull(session)) {
-            return null;
-        }
-        loginUser = (LoginUser) session.get(LOGIN_USER_KEY);
-        SaHolder.getStorage().set(LOGIN_USER_KEY, loginUser);
-        return loginUser;
+        return (LoginUser) getStorageIfAbsentSet(LOGIN_USER_KEY, () -> {
+            SaSession session = StpUtil.getTokenSession();
+            if (ObjectUtil.isNull(session)) {
+                return null;
+            }
+            return session.get(LOGIN_USER_KEY);
+        });
     }
 
     /**
      * 鑾峰彇鐢ㄦ埛鍩轰簬token
      */
     public static LoginUser getLoginUser(String token) {
-        Object loginId = StpUtil.getLoginIdByToken(token);
-        SaSession session = StpUtil.getSessionByLoginId(loginId);
+        SaSession session = StpUtil.getTokenSessionByToken(token);
         if (ObjectUtil.isNull(session)) {
             return null;
         }
@@ -109,17 +106,7 @@
     }
 
     private static Object getExtra(String key) {
-        Object obj;
-        try {
-            obj = SaHolder.getStorage().get(key);
-            if (ObjectUtil.isNull(obj)) {
-                obj = StpUtil.getExtra(key);
-                SaHolder.getStorage().set(key, obj);
-            }
-        } catch (Exception e) {
-            return null;
-        }
-        return obj;
+        return getStorageIfAbsentSet(key, () -> StpUtil.getExtra(key));
     }
 
     /**
@@ -162,7 +149,26 @@
     }
 
     public static boolean isTenantAdmin() {
-        return isTenantAdmin(getLoginUser().getRolePermission());
+        Object value = getStorageIfAbsentSet(TENANT_ADMIN_KEY, () -> {
+            return isTenantAdmin(getLoginUser().getRolePermission());
+        });
+        return Convert.toBool(value);
     }
 
+    public static boolean isLogin() {
+        return getLoginUser() != null;
+    }
+
+    public static Object getStorageIfAbsentSet(String key, Supplier<Object> handle) {
+        try {
+            Object obj = SaHolder.getStorage().get(key);
+            if (ObjectUtil.isNull(obj)) {
+                obj = handle.get();
+                SaHolder.getStorage().set(key, obj);
+            }
+            return obj;
+        } catch (Exception e) {
+            return null;
+        }
+    }
 }
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java
index 1809c61..a4dcfe3 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java
@@ -10,7 +10,6 @@
 import jakarta.validation.ConstraintViolationException;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.domain.R;
-import org.dromara.common.core.exception.DemoModeException;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.exception.base.BaseException;
 import org.dromara.common.core.utils.StreamUtils;
@@ -162,11 +161,4 @@
         return R.fail(message);
     }
 
-    /**
-     * 婕旂ず妯″紡寮傚父
-     */
-    @ExceptionHandler(DemoModeException.class)
-    public R<Void> handleDemoModeException(DemoModeException e) {
-        return R.fail("婕旂ず妯″紡锛屼笉鍏佽鎿嶄綔");
-    }
 }
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
similarity index 64%
rename from ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java
rename to ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
index 6b5a844..29f60fc 100644
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.java
+++ b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
@@ -3,13 +3,12 @@
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 
 /**
- * 鐭俊閰嶇疆绫�
+ * 鐭俊閰嶇疆绫�(鏆傛椂娌$敤 棰勭暀鎵╁睍)
  *
  * @author Lion Li
  * @version 4.2.0
  */
 @AutoConfiguration
-//@EnableConfigurationProperties(SmsProperties.class)
-public class SmsConfig {
+public class SmsAutoConfiguration {
 
 }
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java b/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java
deleted file mode 100644
index c7b3ef1..0000000
--- a/ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java
+++ /dev/null
@@ -1,19 +0,0 @@
-//package org.dromara.common.sms.config.properties;
-//
-//import lombok.Data;
-//import org.springframework.boot.context.properties.ConfigurationProperties;
-//
-///**
-// * SMS鐭俊 閰嶇疆灞炴��
-// *
-// * @author Lion Li
-// * @version 4.2.0
-// */
-//@Data
-//@ConfigurationProperties(prefix = "sms")
-//public class SmsProperties {
-//
-//    private Boolean enabled;
-//
-//
-//}
diff --git a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 6988c7e..5919ce3 100644
--- a/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
-org.dromara.common.sms.config.SmsConfig
+org.dromara.common.sms.config.SmsAutoConfiguration
diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java
index 572a5d0..51b7e13 100644
--- a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java
+++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java
@@ -35,33 +35,34 @@
          if (ObjectUtil.isNull(obj)) {
             throw new AuthException("涓嶆敮鎸佺殑绗笁鏂圭櫥褰曠被鍨�");
         }
-        String clientId = obj.getClientId();
-        String clientSecret = obj.getClientSecret();
-        String redirectUri = obj.getRedirectUri();
+        AuthConfig.AuthConfigBuilder builder = AuthConfig.builder()
+            .clientId(obj.getClientId())
+            .clientSecret(obj.getClientSecret())
+            .redirectUri(obj.getRedirectUri());
         return switch (source.toLowerCase()) {
-            case "dingtalk" -> new AuthDingTalkRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "baidu" -> new AuthBaiduRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "github" -> new AuthGithubRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "gitee" -> new AuthGiteeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "weibo" -> new AuthWeiboRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "coding" -> new AuthCodingRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "oschina" -> new AuthOschinaRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
+            case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE);
+            case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE);
+            case "github" -> new AuthGithubRequest(builder.build(), STATE_CACHE);
+            case "gitee" -> new AuthGiteeRequest(builder.build(), STATE_CACHE);
+            case "weibo" -> new AuthWeiboRequest(builder.build(), STATE_CACHE);
+            case "coding" -> new AuthCodingRequest(builder.build(), STATE_CACHE);
+            case "oschina" -> new AuthOschinaRequest(builder.build(), STATE_CACHE);
             // 鏀粯瀹濆湪鍒涘缓鍥炶皟鍦板潃鏃讹紝涓嶅厑璁镐娇鐢╨ocalhost鎴栬��127.0.0.1锛屾墍浠ヨ繖鍎跨殑鍥炶皟鍦板潃浣跨敤鐨勫眬鍩熺綉鍐呯殑ip
-            case "alipay_wallet" -> new AuthAlipayRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), socialProperties.getType().get("alipay_wallet").getAlipayPublicKey(), STATE_CACHE);
-            case "qq" -> new AuthQqRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "wechat_open" -> new AuthWeChatOpenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "taobao" -> new AuthTaobaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "douyin" -> new AuthDouyinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "linkedin" -> new AuthLinkedinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "microsoft" -> new AuthMicrosoftRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "renren" -> new AuthRenrenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "stack_overflow" -> new AuthStackOverflowRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).stackOverflowKey("").build(), STATE_CACHE);
-            case "huawei" -> new AuthHuaweiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).agentId("").build(), STATE_CACHE);
-            case "gitlab" -> new AuthGitlabRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "wechat_mp" -> new AuthWeChatMpRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "aliyun" -> new AuthAliyunRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
-            case "maxkey" -> new AuthMaxKeyRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret).redirectUri(redirectUri).build(), STATE_CACHE);
+            case "alipay_wallet" -> new AuthAlipayRequest(builder.build(), socialProperties.getType().get("alipay_wallet").getAlipayPublicKey(), STATE_CACHE);
+            case "qq" -> new AuthQqRequest(builder.build(), STATE_CACHE);
+            case "wechat_open" -> new AuthWeChatOpenRequest(builder.build(), STATE_CACHE);
+            case "taobao" -> new AuthTaobaoRequest(builder.build(), STATE_CACHE);
+            case "douyin" -> new AuthDouyinRequest(builder.build(), STATE_CACHE);
+            case "linkedin" -> new AuthLinkedinRequest(builder.build(), STATE_CACHE);
+            case "microsoft" -> new AuthMicrosoftRequest(builder.build(), STATE_CACHE);
+            case "renren" -> new AuthRenrenRequest(builder.build(), STATE_CACHE);
+            case "stack_overflow" -> new AuthStackOverflowRequest(builder.stackOverflowKey("").build(), STATE_CACHE);
+            case "huawei" -> new AuthHuaweiRequest(builder.build(), STATE_CACHE);
+            case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(builder.agentId("").build(), STATE_CACHE);
+            case "gitlab" -> new AuthGitlabRequest(builder.build(), STATE_CACHE);
+            case "wechat_mp" -> new AuthWeChatMpRequest(builder.build(), STATE_CACHE);
+            case "aliyun" -> new AuthAliyunRequest(builder.build(), STATE_CACHE);
+            case "maxkey" -> new AuthMaxKeyRequest(builder.build(), STATE_CACHE);
             default -> throw new AuthException("鏈幏鍙栧埌鏈夋晥鐨凙uth閰嶇疆");
         };
     }
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
index 8d435a3..e830c19 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java
@@ -1,7 +1,7 @@
 package org.dromara.common.tenant.helper;
 
 import cn.dev33.satoken.context.SaHolder;
-import cn.dev33.satoken.spring.SpringMVCUtil;
+import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.convert.Convert;
 import com.alibaba.ttl.TransmittableThreadLocal;
 import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
@@ -82,10 +82,13 @@
     /**
      * 璁剧疆鍔ㄦ�佺鎴�(涓�鐩存湁鏁� 闇�瑕佹墜鍔ㄦ竻鐞�)
      * <p>
-     * 濡傛灉涓洪潪web鐜 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
+     * 濡傛灉涓烘湭鐧诲綍鐘舵�佷笅 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
      */
     public static void setDynamic(String tenantId) {
-        if (!SpringMVCUtil.isWeb()) {
+        if (!isEnable()) {
+            return;
+        }
+        if (!isLogin()) {
             TEMP_DYNAMIC_TENANT.set(tenantId);
             return;
         }
@@ -97,10 +100,13 @@
     /**
      * 鑾峰彇鍔ㄦ�佺鎴�(涓�鐩存湁鏁� 闇�瑕佹墜鍔ㄦ竻鐞�)
      * <p>
-     * 濡傛灉涓洪潪web鐜 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
+     * 濡傛灉涓烘湭鐧诲綍鐘舵�佷笅 閭d箞鍙湪褰撳墠绾跨▼鍐呯敓鏁�
      */
     public static String getDynamic() {
-        if (!SpringMVCUtil.isWeb()) {
+        if (!isEnable()) {
+            return null;
+        }
+        if (!isLogin()) {
             return TEMP_DYNAMIC_TENANT.get();
         }
         String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
@@ -117,7 +123,10 @@
      * 娓呴櫎鍔ㄦ�佺鎴�
      */
     public static void clearDynamic() {
-        if (!SpringMVCUtil.isWeb()) {
+        if (!isEnable()) {
+            return;
+        }
+        if (!isLogin()) {
             TEMP_DYNAMIC_TENANT.remove();
             return;
         }
@@ -127,9 +136,40 @@
     }
 
     /**
+     * 鍦ㄥ姩鎬佺鎴蜂腑鎵ц
+     *
+     * @param handle 澶勭悊鎵ц鏂规硶
+     */
+    public static void dynamic(String tenantId, Runnable handle) {
+        setDynamic(tenantId);
+        try {
+            handle.run();
+        } finally {
+            clearDynamic();
+        }
+    }
+
+    /**
+     * 鍦ㄥ姩鎬佺鎴蜂腑鎵ц
+     *
+     * @param handle 澶勭悊鎵ц鏂规硶
+     */
+    public static <T> T dynamic(String tenantId, Supplier<T> handle) {
+        setDynamic(tenantId);
+        try {
+            return handle.get();
+        } finally {
+            clearDynamic();
+        }
+    }
+
+    /**
      * 鑾峰彇褰撳墠绉熸埛id(鍔ㄦ�佺鎴蜂紭鍏�)
      */
     public static String getTenantId() {
+        if (!isEnable()) {
+            return null;
+        }
         String tenantId = TenantHelper.getDynamic();
         if (StringUtils.isBlank(tenantId)) {
             tenantId = LoginHelper.getTenantId();
@@ -137,4 +177,13 @@
         return tenantId;
     }
 
+    private static boolean isLogin() {
+        try {
+            StpUtil.checkLogin();
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
 }
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
index 25df1c9..c084ea1 100644
--- a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java
@@ -13,6 +13,11 @@
     String USER_ID_TO_NAME = "user_id_to_name";
 
     /**
+     * 鐢ㄦ埛id杞敤鎴峰悕绉�
+     */
+    String USER_ID_TO_NICKNAME = "user_id_to_nickname";
+
+    /**
      * 閮ㄩ棬id杞悕绉�
      */
     String DEPT_ID_TO_NAME = "dept_id_to_name";
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java
new file mode 100644
index 0000000..ac65f5a
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java
@@ -0,0 +1,27 @@
+package org.dromara.common.translation.core.impl;
+
+import lombok.AllArgsConstructor;
+import org.dromara.common.core.service.UserService;
+import org.dromara.common.translation.annotation.TranslationType;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.common.translation.core.TranslationInterface;
+
+/**
+ * 鐢ㄦ埛鍚嶇О缈昏瘧瀹炵幇
+ *
+ * @author may
+ */
+@AllArgsConstructor
+@TranslationType(type = TransConstant.USER_ID_TO_NICKNAME)
+public class NicknameTranslationImpl implements TranslationInterface<String> {
+
+    private final UserService userService;
+
+    @Override
+    public String translation(Object key, String other) {
+        if (key instanceof Long id) {
+            return userService.selectNicknameById(id);
+        }
+        return null;
+    }
+}
diff --git a/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 45844e0..ad40205 100644
--- a/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -3,3 +3,4 @@
 org.dromara.common.translation.core.impl.DictTypeTranslationImpl
 org.dromara.common.translation.core.impl.OssUrlTranslationImpl
 org.dromara.common.translation.core.impl.UserNameTranslationImpl
+org.dromara.common.translation.core.impl.NicknameTranslationImpl
diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
index 99c16c6..086599c 100644
--- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
+++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java
@@ -98,7 +98,7 @@
 
     private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
         if (session == null || !session.isOpen()) {
-            log.error("[send] session浼氳瘽宸茬粡鍏抽棴");
+            log.warn("[send] session浼氳瘽宸茬粡鍏抽棴");
         } else {
             try {
                 session.sendMessage(message);
diff --git a/ruoyi-extend/ruoyi-monitor-admin/Dockerfile b/ruoyi-extend/ruoyi-monitor-admin/Dockerfile
index 2550d2d..7ae0682 100644
--- a/ruoyi-extend/ruoyi-monitor-admin/Dockerfile
+++ b/ruoyi-extend/ruoyi-monitor-admin/Dockerfile
@@ -7,10 +7,11 @@
 
 WORKDIR /ruoyi/monitor
 
-ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
+ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
 
 EXPOSE 9090
 
 ADD ./target/ruoyi-monitor-admin.jar ./app.jar
 
-ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
+ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar app.jar \
+           -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS}
diff --git a/ruoyi-extend/ruoyi-powerjob-server/Dockerfile b/ruoyi-extend/ruoyi-powerjob-server/Dockerfile
index 0da59e5..729bb22 100644
--- a/ruoyi-extend/ruoyi-powerjob-server/Dockerfile
+++ b/ruoyi-extend/ruoyi-powerjob-server/Dockerfile
@@ -7,10 +7,11 @@
 
 WORKDIR /ruoyi/powerjob
 
-ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
+ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS="-Xms512m -Xmx1024m"
 
 EXPOSE 7700
 
 ADD ./target/ruoyi-powerjob-server.jar ./app.jar
 
-ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
+ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar app.jar \
+           -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC ${JAVA_OPTS}
diff --git a/ruoyi-extend/ruoyi-powerjob-server/pom.xml b/ruoyi-extend/ruoyi-powerjob-server/pom.xml
index 72b2378..bdb92a4 100644
--- a/ruoyi-extend/ruoyi-powerjob-server/pom.xml
+++ b/ruoyi-extend/ruoyi-powerjob-server/pom.xml
@@ -10,7 +10,7 @@
     <artifactId>ruoyi-powerjob-server</artifactId>
 
     <properties>
-        <spring-boot.version>2.7.17</spring-boot.version>
+        <spring-boot.version>2.7.18</spring-boot.version>
         <spring-boot-admin.version>2.7.11</spring-boot-admin.version>
     </properties>
     <dependencyManagement>
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java
index 418f740..3fd124c 100644
--- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java
@@ -95,6 +95,41 @@
     }
 
     /**
+     * 澶氫釜sheet瀵煎嚭
+     */
+    @GetMapping("/exportTemplateMultiSheet")
+    public void exportTemplateMultiSheet(HttpServletResponse response) {
+        List<TestObj1> list1 = new ArrayList<>();
+        list1.add(new TestObj1("list1娴嬭瘯1", "list1娴嬭瘯2", "list1娴嬭瘯3"));
+        list1.add(new TestObj1("list1娴嬭瘯4", "list1娴嬭瘯5", "list1娴嬭瘯6"));
+        List<TestObj1> list2 = new ArrayList<>();
+        list2.add(new TestObj1("list2娴嬭瘯1", "list2娴嬭瘯2", "list2娴嬭瘯3"));
+        list2.add(new TestObj1("list2娴嬭瘯4", "list2娴嬭瘯5", "list2娴嬭瘯6"));
+        List<TestObj1> list3 = new ArrayList<>();
+        list3.add(new TestObj1("list3娴嬭瘯1", "list3娴嬭瘯2", "list3娴嬭瘯3"));
+        list3.add(new TestObj1("list3娴嬭瘯4", "list3娴嬭瘯5", "list3娴嬭瘯6"));
+        List<TestObj1> list4 = new ArrayList<>();
+        list4.add(new TestObj1("list4娴嬭瘯1", "list4娴嬭瘯2", "list4娴嬭瘯3"));
+        list4.add(new TestObj1("list4娴嬭瘯4", "list4娴嬭瘯5", "list4娴嬭瘯6"));
+
+        List<Map<String, Object>> list = new ArrayList<>();
+        Map<String, Object> sheetMap1 = new HashMap<>();
+        sheetMap1.put("data1", list1);
+        Map<String, Object> sheetMap2 = new HashMap<>();
+        sheetMap2.put("data2", list2);
+        Map<String, Object> sheetMap3 = new HashMap<>();
+        sheetMap3.put("data3", list3);
+        Map<String, Object> sheetMap4 = new HashMap<>();
+        sheetMap4.put("data4", list4);
+
+        list.add(sheetMap1);
+        list.add(sheetMap2);
+        list.add(sheetMap3);
+        list.add(sheetMap4);
+        ExcelUtil.exportTemplateMultiSheet(list, "澶歴heet鍒楄〃", "excel/澶歴heet鍒楄〃.xlsx", response);
+    }
+
+    /**
      * 瀵煎叆琛ㄦ牸
      */
     @PostMapping(value = "/importWithOptions", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java
index f9b81c1..fb2aade 100644
--- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java
+++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java
@@ -1,5 +1,6 @@
 package org.dromara.demo.controller.queue;
 
+import cn.dev33.satoken.annotation.SaIgnore;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.redis.utils.QueueUtils;
 import lombok.RequiredArgsConstructor;
@@ -22,6 +23,7 @@
  * @author Lion Li
  * @version 3.6.0
  */
+@SaIgnore
 @Slf4j
 @RequiredArgsConstructor
 @RestController
@@ -40,7 +42,7 @@
         QueueUtils.subscribeBlockingQueue(queueName, (String orderNum) -> {
             // 瑙傚療鎺ユ敹鏃堕棿
             log.info("閫氶亾: {}, 鏀跺埌鏁版嵁: {}", queueName, orderNum);
-        });
+        }, true);
         return R.ok("鎿嶄綔鎴愬姛");
     }
 
diff --git "a/ruoyi-modules/ruoyi-demo/src/main/resources/excel/\345\244\232sheet\345\210\227\350\241\250.xlsx" "b/ruoyi-modules/ruoyi-demo/src/main/resources/excel/\345\244\232sheet\345\210\227\350\241\250.xlsx"
new file mode 100644
index 0000000..5277f2e
--- /dev/null
+++ "b/ruoyi-modules/ruoyi-demo/src/main/resources/excel/\345\244\232sheet\345\210\227\350\241\250.xlsx"
Binary files differ
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java
index 0fe7122..24ddaff 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java
@@ -40,7 +40,7 @@
     /**
      * 鏌ヨ瀵硅薄瀛樺偍閰嶇疆鍒楄〃
      */
-    @SaCheckPermission("system:oss:list")
+    @SaCheckPermission("system:ossConfig:list")
     @GetMapping("/list")
     public TableDataInfo<SysOssConfigVo> list(@Validated(QueryGroup.class) SysOssConfigBo bo, PageQuery pageQuery) {
         return ossConfigService.queryPageList(bo, pageQuery);
@@ -51,7 +51,7 @@
      *
      * @param ossConfigId OSS閰嶇疆ID
      */
-    @SaCheckPermission("system:oss:query")
+    @SaCheckPermission("system:ossConfig:list")
     @GetMapping("/{ossConfigId}")
     public R<SysOssConfigVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
                                      @PathVariable Long ossConfigId) {
@@ -61,7 +61,7 @@
     /**
      * 鏂板瀵硅薄瀛樺偍閰嶇疆
      */
-    @SaCheckPermission("system:oss:add")
+    @SaCheckPermission("system:ossConfig:add")
     @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
@@ -72,7 +72,7 @@
     /**
      * 淇敼瀵硅薄瀛樺偍閰嶇疆
      */
-    @SaCheckPermission("system:oss:edit")
+    @SaCheckPermission("system:ossConfig:edit")
     @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
@@ -85,7 +85,7 @@
      *
      * @param ossConfigIds OSS閰嶇疆ID涓�
      */
-    @SaCheckPermission("system:oss:remove")
+    @SaCheckPermission("system:ossConfig:remove")
     @Log(title = "瀵硅薄瀛樺偍閰嶇疆", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ossConfigIds}")
     public R<Void> remove(@NotEmpty(message = "涓婚敭涓嶈兘涓虹┖")
@@ -96,7 +96,7 @@
     /**
      * 鐘舵�佷慨鏀�
      */
-    @SaCheckPermission("system:oss:edit")
+    @SaCheckPermission("system:ossConfig:edit")
     @Log(title = "瀵硅薄瀛樺偍鐘舵�佷慨鏀�", businessType = BusinessType.UPDATE)
     @PutMapping("/changeStatus")
     public R<Void> changeStatus(@RequestBody SysOssConfigBo bo) {
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
index c9be0da..f9c4b3d 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java
@@ -6,6 +6,7 @@
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.utils.file.MimeTypeUtils;
+import org.dromara.common.encrypt.annotation.ApiEncrypt;
 import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.satoken.utils.LoginHelper;
@@ -61,11 +62,12 @@
     @PutMapping
     public R<Void> updateProfile(@RequestBody SysUserProfileBo profile) {
         SysUserBo user = BeanUtil.toBean(profile, SysUserBo.class);
+        String username = LoginHelper.getUsername();
         if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
-            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
+            return R.fail("淇敼鐢ㄦ埛'" + username + "'澶辫触锛屾墜鏈哄彿鐮佸凡瀛樺湪");
         }
         if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
-            return R.fail("淇敼鐢ㄦ埛'" + user.getUserName() + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
+            return R.fail("淇敼鐢ㄦ埛'" + username + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪");
         }
         user.setUserId(LoginHelper.getUserId());
         if (userService.updateUserProfile(user) > 0) {
@@ -79,6 +81,7 @@
      *
      * @param bo 鏂版棫瀵嗙爜
      */
+    @ApiEncrypt
     @Log(title = "涓汉淇℃伅", businessType = BusinessType.UPDATE)
     @PutMapping("/updatePwd")
     public R<Void> updatePwd(@Validated @RequestBody SysUserPasswordBo bo) {
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java
index 4875508..b0281cf 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java
@@ -1,6 +1,5 @@
 package org.dromara.system.controller.system;
 
-import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.satoken.utils.LoginHelper;
@@ -9,7 +8,6 @@
 import org.dromara.system.service.ISysSocialService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -35,18 +33,6 @@
     @GetMapping("/list")
     public R<List<SysSocialVo>> list() {
         return R.ok(socialUserService.queryListByUserId(LoginHelper.getUserId()));
-    }
-
-
-    /**
-     * 鑾峰彇绀句細鍖栧叧绯昏缁嗕俊鎭�
-     *
-     * @param id 涓婚敭
-     */
-    @GetMapping("/{id}")
-    public R<SysSocialVo> getInfo(@NotNull(message = "涓婚敭涓嶈兘涓虹┖")
-                                     @PathVariable String id) {
-        return R.ok(socialUserService.queryById(id));
     }
 
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
index 865b57a..053ff17 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java
@@ -4,7 +4,6 @@
 import cn.dev33.satoken.annotation.SaCheckRole;
 import com.baomidou.lock.annotation.Lock4j;
 import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.constraints.Min;
 import jakarta.validation.constraints.NotBlank;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
@@ -13,6 +12,7 @@
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.encrypt.annotation.ApiEncrypt;
 import org.dromara.common.excel.utils.ExcelUtil;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
 import org.dromara.common.log.annotation.Log;
@@ -25,14 +25,7 @@
 import org.dromara.system.domain.vo.SysTenantVo;
 import org.dromara.system.service.ISysTenantService;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
@@ -87,6 +80,7 @@
     /**
      * 鏂板绉熸埛
      */
+    @ApiEncrypt
     @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
     @SaCheckPermission("system:tenant:add")
     @Log(title = "绉熸埛", businessType = BusinessType.INSERT)
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
index 628060a..beefe4a 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java
@@ -14,6 +14,7 @@
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.encrypt.annotation.ApiEncrypt;
 import org.dromara.common.excel.core.ExcelResult;
 import org.dromara.common.excel.utils.ExcelUtil;
 import org.dromara.common.log.annotation.Log;
@@ -209,6 +210,7 @@
     /**
      * 閲嶇疆瀵嗙爜
      */
+    @ApiEncrypt
     @SaCheckPermission("system:user:resetPwd")
     @Log(title = "鐢ㄦ埛绠$悊", businessType = BusinessType.UPDATE)
     @PutMapping("/resetPwd")
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java
index de99496..8a9e25e 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java
@@ -2,9 +2,9 @@
 
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
-import org.dromara.common.tenant.core.TenantEntity;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
 
 /**
  * 瀵硅薄瀛樺偍閰嶇疆瀵硅薄 sys_oss_config
@@ -14,7 +14,7 @@
 @Data
 @EqualsAndHashCode(callSuper = true)
 @TableName("sys_oss_config")
-public class SysOssConfig extends TenantEntity {
+public class SysOssConfig extends BaseEntity {
 
     /**
      * 涓诲缓
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java
index 8a00cc3..948dbcc 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java
@@ -1,13 +1,12 @@
 package org.dromara.system.domain.vo;
 
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
 import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import org.dromara.system.domain.SysSocial;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.util.Date;
 
 
 /**
@@ -16,7 +15,6 @@
  * @author thiszhc
  */
 @Data
-@ExcelIgnoreUnannotated
 @AutoMapper(target = SysSocial.class)
 public class SysSocialVo implements Serializable {
 
@@ -26,13 +24,11 @@
     /**
      * 涓婚敭
      */
-    @ExcelProperty(value = "涓婚敭")
     private Long id;
 
     /**
      * 鐢ㄦ埛ID
      */
-    @ExcelProperty(value = "鐢ㄦ埛ID")
     private Long userId;
 
     /**
@@ -43,123 +39,106 @@
     /**
      * 鐨勫敮涓�ID
      */
-    @ExcelProperty(value = "鎺堟潈UUID")
     private String authId;
 
     /**
      * 鐢ㄦ埛鏉ユ簮
      */
-    @ExcelProperty(value = "鐢ㄦ埛鏉ユ簮")
     private String source;
 
     /**
      * 鐢ㄦ埛鐨勬巿鏉冧护鐗�
      */
-    @ExcelProperty(value = "鐢ㄦ埛鐨勬巿鏉冧护鐗�")
     private String accessToken;
 
     /**
      * 鐢ㄦ埛鐨勬巿鏉冧护鐗岀殑鏈夋晥鏈燂紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "鐢ㄦ埛鐨勬巿鏉冧护鐗岀殑鏈夋晥鏈燂紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private int expireIn;
 
     /**
      * 鍒锋柊浠ょ墝锛岄儴鍒嗗钩鍙板彲鑳芥病鏈�
      */
-    @ExcelProperty(value = "鍒锋柊浠ょ墝锛岄儴鍒嗗钩鍙板彲鑳芥病鏈�")
     private String refreshToken;
 
     /**
      * 鐢ㄦ埛鐨� open id
      */
-    @ExcelProperty(value = "骞冲彴鐨勫敮涓�id")
     private String openId;
 
     /**
      * 鎺堟潈鐨勭涓夋柟璐﹀彿
      */
-    @ExcelProperty(value = "鎺堟潈鐨勭涓夋柟璐﹀彿")
     private String userName;
 
     /**
      * 鎺堟潈鐨勭涓夋柟鏄电О
      */
-    @ExcelProperty(value = "鎺堟潈鐨勭涓夋柟鏄电О")
     private String nickName;
 
     /**
      * 鎺堟潈鐨勭涓夋柟閭
      */
-    @ExcelProperty(value = "鎺堟潈鐨勭涓夋柟閭")
     private String email;
 
     /**
      * 鎺堟潈鐨勭涓夋柟澶村儚鍦板潃
      */
-    @ExcelProperty(value = "鎺堟潈鐨勭涓夋柟澶村儚鍦板潃")
     private String avatar;
 
 
     /**
      * 骞冲彴鐨勬巿鏉冧俊鎭紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "骞冲彴鐨勬巿鏉冧俊鎭紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private String accessCode;
 
     /**
      * 鐢ㄦ埛鐨� unionid
      */
-    @ExcelProperty(value = "鐢ㄦ埛鐨� unionid")
     private String unionId;
 
     /**
      * 鎺堜簣鐨勬潈闄愶紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "鎺堜簣鐨勬潈闄愶紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private String scope;
 
     /**
      * 涓埆骞冲彴鐨勬巿鏉冧俊鎭紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "涓埆骞冲彴鐨勬巿鏉冧俊鎭紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private String tokenType;
 
     /**
      * id token锛岄儴鍒嗗钩鍙板彲鑳芥病鏈�
      */
-    @ExcelProperty(value = "id token锛岄儴鍒嗗钩鍙板彲鑳芥病鏈�")
     private String idToken;
 
     /**
      * 灏忕背骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "灏忕背骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private String macAlgorithm;
 
     /**
      * 灏忕背骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "灏忕背骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private String macKey;
 
     /**
      * 鐢ㄦ埛鐨勬巿鏉僣ode锛岄儴鍒嗗钩鍙板彲鑳芥病鏈�
      */
-    @ExcelProperty(value = "鐢ㄦ埛鐨勬巿鏉僣ode锛岄儴鍒嗗钩鍙板彲鑳芥病鏈�")
     private String code;
 
     /**
      * Twitter骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "Twitter骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private String oauthToken;
 
     /**
      * Twitter骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁
      */
-    @ExcelProperty(value = "Twitter骞冲彴鐢ㄦ埛鐨勯檮甯﹀睘鎬э紝閮ㄥ垎骞冲彴鍙兘娌℃湁")
     private String oauthTokenSecret;
 
-
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java
index c3a8869..4322225 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java
@@ -1,15 +1,14 @@
 package org.dromara.system.mapper;
 
-import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.toolkit.Constants;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.annotation.DataColumn;
 import org.dromara.common.mybatis.annotation.DataPermission;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 import org.dromara.system.domain.SysUser;
 import org.dromara.system.domain.vo.SysUserVo;
-import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -85,37 +84,6 @@
      * @return 鐢ㄦ埛瀵硅薄淇℃伅
      */
     SysUserVo selectUserByEmail(String email);
-
-    /**
-     * 閫氳繃鐢ㄦ埛鍚嶆煡璇㈢敤鎴�(涓嶈蛋绉熸埛鎻掍欢)
-     *
-     * @param userName 鐢ㄦ埛鍚�
-     * @param tenantId 绉熸埛id
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    SysUserVo selectTenantUserByUserName(@Param("userName") String userName, @Param("tenantId") String tenantId);
-
-    /**
-     * 閫氳繃鎵嬫満鍙锋煡璇㈢敤鎴�(涓嶈蛋绉熸埛鎻掍欢)
-     *
-     * @param phonenumber 鎵嬫満鍙�
-     * @param tenantId    绉熸埛id
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    SysUserVo selectTenantUserByPhonenumber(@Param("phonenumber") String phonenumber, @Param("tenantId") String tenantId);
-
-    /**
-     * 閫氳繃閭鏌ヨ鐢ㄦ埛(涓嶈蛋绉熸埛鎻掍欢)
-     *
-     * @param email    閭
-     * @param tenantId 绉熸埛id
-     * @return 鐢ㄦ埛瀵硅薄淇℃伅
-     */
-    @InterceptorIgnore(tenantLine = "true")
-    SysUserVo selectTenantUserByEmail(@Param("email") String email, @Param("tenantId") String tenantId);
-
 
     /**
      * 閫氳繃鐢ㄦ埛ID鏌ヨ鐢ㄦ埛
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java
index 5f2014d..d5702c9 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java
@@ -49,7 +49,7 @@
      * @param authId 璁よ瘉ID
      * @return SysSocial
      */
-    SysSocialVo selectByAuthId(String authId);
+    List<SysSocialVo> selectByAuthId(String authId);
 
 
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java
index d1f8248..7738d80 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java
@@ -85,9 +85,10 @@
      */
     @Override
     public boolean selectRegisterEnabled(String tenantId) {
-        SysConfig retConfig = baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
-            .eq(SysConfig::getConfigKey, "sys.account.registerUser")
-            .eq(TenantHelper.isEnable(),SysConfig::getTenantId, tenantId));
+        SysConfig retConfig = TenantHelper.dynamic(tenantId, () -> {
+            return baseMapper.selectOne(new LambdaQueryWrapper<SysConfig>()
+                .eq(SysConfig::getConfigKey, "sys.account.registerUser"));
+        });
         if (ObjectUtil.isNull(retConfig)) {
             return false;
         }
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
index 8d3499c..346d6bc 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java
@@ -125,7 +125,7 @@
      */
     @Override
     public SysDictTypeVo selectDictTypeByType(String dictType) {
-        return baseMapper.selectVoById(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
+        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getDictType, dictType));
     }
 
     /**
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java
index be4ed03..2ecd592 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java
@@ -11,7 +11,6 @@
 import org.dromara.common.core.constant.CacheNames;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.MapstructUtils;
-import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -19,8 +18,6 @@
 import org.dromara.common.oss.constant.OssConstant;
 import org.dromara.common.redis.utils.CacheUtils;
 import org.dromara.common.redis.utils.RedisUtils;
-import org.dromara.common.tenant.core.TenantEntity;
-import org.dromara.common.tenant.helper.TenantHelper;
 import org.dromara.system.domain.SysOssConfig;
 import org.dromara.system.domain.bo.SysOssConfigBo;
 import org.dromara.system.domain.vo.SysOssConfigVo;
@@ -31,7 +28,6 @@
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 
 /**
  * 瀵硅薄瀛樺偍閰嶇疆Service涓氬姟灞傚鐞�
@@ -52,25 +48,14 @@
      */
     @Override
     public void init() {
-        List<SysOssConfig> list = TenantHelper.ignore(() ->
-            baseMapper.selectList(
-                new LambdaQueryWrapper<SysOssConfig>().orderByAsc(TenantEntity::getTenantId))
-        );
-        Map<String, List<SysOssConfig>> map = StreamUtils.groupByKey(list, SysOssConfig::getTenantId);
-        try {
-            for (String tenantId : map.keySet()) {
-                TenantHelper.setDynamic(tenantId);
-                // 鍔犺浇OSS鍒濆鍖栭厤缃�
-                for (SysOssConfig config : map.get(tenantId)) {
-                    String configKey = config.getConfigKey();
-                    if ("0".equals(config.getStatus())) {
-                        RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
-                    }
-                    CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
-                }
+        List<SysOssConfig> list = baseMapper.selectList();
+        // 鍔犺浇OSS鍒濆鍖栭厤缃�
+        for (SysOssConfig config : list) {
+            String configKey = config.getConfigKey();
+            if ("0".equals(config.getStatus())) {
+                RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);
             }
-        } finally {
-            TenantHelper.clearDynamic();
+            CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));
         }
     }
 
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java
index 05eb430..5f4d121 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java
@@ -23,7 +23,7 @@
      */
     @Override
     public boolean isSensitive(String roleKey, String perms) {
-        if (!StpUtil.isLogin()) {
+        if (!LoginHelper.isLogin()) {
             return true;
         }
         boolean roleExist = StringUtils.isNotBlank(roleKey);
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java
index bd7248f..aa86ae1 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java
@@ -99,8 +99,8 @@
      * @return 鎺堟潈淇℃伅
      */
     @Override
-    public SysSocialVo selectByAuthId(String authId) {
-        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysSocial>().eq(SysSocial::getAuthId, authId));
+    public List<SysSocialVo> selectByAuthId(String authId) {
+        return baseMapper.selectVoList(new LambdaQueryWrapper<SysSocial>().eq(SysSocial::getAuthId, authId));
     }
 
 }
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 8e097b2..7ee19e8 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
@@ -536,4 +536,12 @@
                 .select(SysUser::getUserName).eq(SysUser::getUserId, userId));
         return ObjectUtil.isNull(sysUser) ? null : sysUser.getUserName();
     }
+
+    @Override
+    @Cacheable(cacheNames = CacheNames.SYS_NICKNAME, key = "#userId")
+    public String selectNicknameById(Long userId) {
+        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
+            .select(SysUser::getNickName).eq(SysUser::getUserId, userId));
+        return ObjectUtil.isNull(sysUser) ? null : sysUser.getNickName();
+    }
 }
diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
index 52c1aa4..7af7dd0 100644
--- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -118,21 +118,6 @@
         where u.del_flag = '0' and u.email = #{email}
     </select>
 
-    <select id="selectTenantUserByUserName" parameterType="String" resultMap="SysUserResult">
-        <include refid="selectUserVo"/>
-        where u.del_flag = '0' and u.user_name = #{userName} and u.tenant_id = #{tenantId}
-    </select>
-
-    <select id="selectTenantUserByPhonenumber" parameterType="String" resultMap="SysUserResult">
-        <include refid="selectUserVo"/>
-        where u.del_flag = '0' and u.phonenumber = #{phonenumber} and u.tenant_id = #{tenantId}
-    </select>
-
-    <select id="selectTenantUserByEmail" parameterType="String" resultMap="SysUserResult">
-        <include refid="selectUserVo"/>
-        where u.del_flag = '0' and u.email = #{email} and u.tenant_id = #{tenantId}
-    </select>
-
     <select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
         <include refid="selectUserVo"/>
         where u.del_flag = '0' and u.user_id = #{userId}
diff --git a/script/bin/ry.bat b/script/bin/ry.bat
index 94434a9..d214af4 100644
--- a/script/bin/ry.bat
+++ b/script/bin/ry.bat
@@ -5,7 +5,7 @@
 set AppName=ruoyi-admin.jar
 
 rem JVM鍙傛暟
-set JVM_OPTS="-Dname=%AppName%  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
+set JVM_OPTS="-Dname=%AppName%  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC"
 
 
 ECHO.
diff --git a/script/bin/ry.sh b/script/bin/ry.sh
index 0cf5ce9..0df25e7 100644
--- a/script/bin/ry.sh
+++ b/script/bin/ry.sh
@@ -3,7 +3,7 @@
 AppName=ruoyi-admin.jar
 
 # JVM鍙傛暟
-JVM_OPTS="-Dname=$AppName  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
+JVM_OPTS="-Dname=$AppName  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Xlog:gc*,:time,tags,level -XX:+UseZGC"
 APP_HOME=`pwd`
 LOG_PATH=$APP_HOME/logs/$AppName.log
 
diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml
index 598189d..63d819e 100644
--- a/script/docker/docker-compose.yml
+++ b/script/docker/docker-compose.yml
@@ -100,7 +100,7 @@
     network_mode: "host"
 
   ruoyi-server1:
-    image: ruoyi/ruoyi-server:5.1.1
+    image: ruoyi/ruoyi-server:5.1.2
     container_name: ruoyi-server1
     environment:
       # 鏃跺尯涓婃捣
@@ -115,7 +115,7 @@
     network_mode: "host"
 
   ruoyi-server2:
-    image: ruoyi/ruoyi-server:5.1.1
+    image: ruoyi/ruoyi-server:5.1.2
     container_name: ruoyi-server2
     environment:
       # 鏃跺尯涓婃捣
@@ -130,7 +130,7 @@
     network_mode: "host"
 
   ruoyi-monitor-admin:
-    image: ruoyi/ruoyi-monitor-admin:5.1.1
+    image: ruoyi/ruoyi-monitor-admin:5.1.2
     container_name: ruoyi-monitor-admin
     environment:
       # 鏃跺尯涓婃捣
@@ -142,7 +142,7 @@
     network_mode: "host"
 
   ruoyi-powerjob-server:
-    image: ruoyi/ruoyi-powerjob-server:5.1.1
+    image: ruoyi/ruoyi-powerjob-server:5.1.2
     container_name: ruoyi-powerjob-server
     environment:
       # 鏃跺尯涓婃捣
diff --git a/script/docker/nginx/conf/nginx.conf b/script/docker/nginx/conf/nginx.conf
index 641ae67..2aa6587 100644
--- a/script/docker/nginx/conf/nginx.conf
+++ b/script/docker/nginx/conf/nginx.conf
@@ -108,7 +108,7 @@
         }
 
         # 瑙e喅 powerjob 浠g悊涔嬪悗闈欐�佹枃浠舵棤娉曡闂殑闂 璇峰嬁淇敼涔卞姩
-        location .*\.(js|css|jpg|png|svg|woff|ttf|ico)?$ {
+        location ~ ^/(js|css|jpg|png|svg|woff|ttf|ico|img)/ {
             proxy_pass http://powerjob-server;
         }
 
diff --git a/script/sql/oracle/oracle_ry_vue_5.X.sql b/script/sql/oracle/oracle_ry_vue_5.X.sql
index 1100fa9..ef45c5f 100644
--- a/script/sql/oracle/oracle_ry_vue_5.X.sql
+++ b/script/sql/oracle/oracle_ry_vue_5.X.sql
@@ -522,8 +522,10 @@
 insert into sys_menu values('1601', '鏂囦欢涓婁紶', '118', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:upload',       '#', 103, 1, sysdate, null, null, '');
 insert into sys_menu values('1602', '鏂囦欢涓嬭浇', '118', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:download',     '#', 103, 1, sysdate, null, null, '');
 insert into sys_menu values('1603', '鏂囦欢鍒犻櫎', '118', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:remove',       '#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values('1604', '閰嶇疆娣诲姞', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:add',          '#', 103, 1, sysdate, null, null, '');
-insert into sys_menu values('1605', '閰嶇疆缂栬緫', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:edit',         '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1620', '閰嶇疆鍒楄〃', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:list',   '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1621', '閰嶇疆娣诲姞', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:add',    '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1622', '閰嶇疆缂栬緫', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:edit',   '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1623', '閰嶇疆鍒犻櫎', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:remove', '#', 103, 1, sysdate, null, null, '');
 -- 绉熸埛绠$悊鐩稿叧鎸夐挳
 insert into sys_menu values('1606', '绉熸埛鏌ヨ', '121', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenant:query',   '#', 103, 1, sysdate, null, null, '');
 insert into sys_menu values('1607', '绉熸埛鏂板', '121', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenant:add',     '#', 103, 1, sysdate, null, null, '');
diff --git a/script/sql/oracle/powerjob.sql b/script/sql/oracle/powerjob.sql
index 83ebd41..7a5419d 100644
--- a/script/sql/oracle/powerjob.sql
+++ b/script/sql/oracle/powerjob.sql
@@ -159,10 +159,10 @@
 -- ----------------------------
 -- Records of "PJ_JOB_INFO"
 -- ----------------------------
-INSERT INTO "PJ_JOB_INFO" VALUES ('1', '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', '1', '5', NULL, '2', '1', NULL, NULL, NULL, '1', '0', NULL, '鍗曟満澶勭悊鍣ㄦ墽琛屾祴璇�', NULL, '{}', '{\"type\":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.StandaloneProcessorDemo', '1', '2', NULL, '1', '30000', '3');
-INSERT INTO "PJ_JOB_INFO" VALUES ('2', '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', '1', '5', NULL, '1', '2', NULL, NULL, NULL, '0', '0', NULL, '骞挎挱澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{\"type\":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.BroadcastProcessorDemo', '1', '2', NULL, '1', '30000', '3');
-INSERT INTO "PJ_JOB_INFO" VALUES ('3', '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', '1', '5', NULL, '1', '4', NULL, NULL, NULL, '0', '0', NULL, 'Map澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{\"type\":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.MapProcessorDemo', '1', '2', NULL, '1', '1000', '3');
-INSERT INTO "PJ_JOB_INFO" VALUES ('4', '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', '1', '5', NULL, '1', '3', NULL, NULL, NULL, '0', '0', NULL, 'MapReduce澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{\"type\":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.MapReduceProcessorDemo', '1', '2', NULL, '1', '1000', '3');
+INSERT INTO "PJ_JOB_INFO" VALUES ('1', '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', '1', '5', NULL, '2', '1', NULL, NULL, NULL, '1', '0', NULL, '鍗曟満澶勭悊鍣ㄦ墽琛屾祴璇�', NULL, '{}', '{"type":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.StandaloneProcessorDemo', '1', '2', NULL, '1', '30000', '3');
+INSERT INTO "PJ_JOB_INFO" VALUES ('2', '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', '1', '5', NULL, '1', '2', NULL, NULL, NULL, '0', '0', NULL, '骞挎挱澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{"type":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.BroadcastProcessorDemo', '1', '2', NULL, '1', '30000', '3');
+INSERT INTO "PJ_JOB_INFO" VALUES ('3', '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', '1', '5', NULL, '1', '4', NULL, NULL, NULL, '0', '0', NULL, 'Map澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{"type":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.MapProcessorDemo', '1', '2', NULL, '1', '1000', '3');
+INSERT INTO "PJ_JOB_INFO" VALUES ('4', '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', '1', '5', NULL, '1', '3', NULL, NULL, NULL, '0', '0', NULL, 'MapReduce澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{"type":1}', '0', '0', '0.0000000000000000', '0.0000000000000000', '0.0000000000000000', NULL, NULL, 'org.dromara.job.processors.MapReduceProcessorDemo', '1', '2', NULL, '1', '1000', '3');
 
 -- ----------------------------
 -- Table structure for PJ_OMS_LOCK
diff --git a/script/sql/postgres/postgres_ry_vue_5.X.sql b/script/sql/postgres/postgres_ry_vue_5.X.sql
index 48860dc..a6d6f1a 100644
--- a/script/sql/postgres/postgres_ry_vue_5.X.sql
+++ b/script/sql/postgres/postgres_ry_vue_5.X.sql
@@ -532,8 +532,10 @@
 insert into sys_menu values('1601', '鏂囦欢涓婁紶', '118', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:upload',       '#', 103, 1, now(), null, null, '');
 insert into sys_menu values('1602', '鏂囦欢涓嬭浇', '118', '3', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:download',     '#', 103, 1, now(), null, null, '');
 insert into sys_menu values('1603', '鏂囦欢鍒犻櫎', '118', '4', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:remove',       '#', 103, 1, now(), null, null, '');
-insert into sys_menu values('1604', '閰嶇疆娣诲姞', '118', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:add',          '#', 103, 1, now(), null, null, '');
-insert into sys_menu values('1605', '閰嶇疆缂栬緫', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:oss:edit',         '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1620', '閰嶇疆鍒楄〃', '118', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:list',   '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1621', '閰嶇疆娣诲姞', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:add',    '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1622', '閰嶇疆缂栬緫', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:edit',   '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1623', '閰嶇疆鍒犻櫎', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:remove', '#', 103, 1, now(), null, null, '');
 -- 绉熸埛绠$悊鐩稿叧鎸夐挳
 insert into sys_menu values('1606', '绉熸埛鏌ヨ', '121', '1', '#', '', '', '1', '0', 'F', '0', '0', 'system:tenant:query',   '#', 103, 1, now(), null, null, '');
 insert into sys_menu values('1607', '绉熸埛鏂板', '121', '2', '#', '', '', '1', '0', 'F', '0', '0', 'system:tenant:add',     '#', 103, 1, now(), null, null, '');
diff --git a/script/sql/postgres/powerjob.sql b/script/sql/postgres/powerjob.sql
index 0e2265d..56d3bcb 100644
--- a/script/sql/postgres/powerjob.sql
+++ b/script/sql/postgres/powerjob.sql
@@ -116,10 +116,10 @@
 CREATE INDEX idx01_job_info ON pj_job_info USING btree (app_id, status, time_expression_type, next_trigger_time);
 
 
-INSERT INTO pj_job_info VALUES(1, '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', 1, 5, '', 2, 1, NULL, '2023-06-02 15:01:27.717', '2023-07-04 17:22:12.374', 1, 0, '', '鍗曟満澶勭悊鍣ㄦ墽琛屾祴璇�', NULL, '{}', '{\"type\":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.StandaloneProcessorDemo', 1, 2, NULL, 1, '30000', 3);
-INSERT INTO pj_job_info VALUES(2, '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', 1, 5, '', 1, 2, NULL, '2023-06-02 15:04:45.342', '2023-07-04 17:22:12.816', 0, 0, NULL, '骞挎挱澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{\"type\":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.BroadcastProcessorDemo', 1, 2, NULL, 1, '30000', 3);
-INSERT INTO pj_job_info VALUES(3, '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', 1, 5, '', 1, 4, NULL, '2023-06-02 15:13:23.519', '2023-06-02 16:03:22.421', 0, 0, NULL, 'Map澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{\"type\":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.MapProcessorDemo', 1, 2, NULL, 1, '1000', 3);
-INSERT INTO pj_job_info VALUES(4, '{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', 1, 5, '', 1, 3, NULL, '2023-06-02 15:45:25.896', '2023-06-02 16:03:23.125', 0, 0, NULL, 'MapReduce澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{\"type\":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.MapReduceProcessorDemo', 1, 2, NULL, 1, '1000', 3);
+INSERT INTO pj_job_info VALUES(1, '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', 1, 5, '', 2, 1, NULL, '2023-06-02 15:01:27.717', '2023-07-04 17:22:12.374', 1, 0, '', '鍗曟満澶勭悊鍣ㄦ墽琛屾祴璇�', NULL, '{}', '{"type":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.StandaloneProcessorDemo', 1, 2, NULL, 1, '30000', 3);
+INSERT INTO pj_job_info VALUES(2, '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', 1, 5, '', 1, 2, NULL, '2023-06-02 15:04:45.342', '2023-07-04 17:22:12.816', 0, 0, NULL, '骞挎挱澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{"type":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.BroadcastProcessorDemo', 1, 2, NULL, 1, '30000', 3);
+INSERT INTO pj_job_info VALUES(3, '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', 1, 5, '', 1, 4, NULL, '2023-06-02 15:13:23.519', '2023-06-02 16:03:22.421', 0, 0, NULL, 'Map澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{"type":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.MapProcessorDemo', 1, 2, NULL, 1, '1000', 3);
+INSERT INTO pj_job_info VALUES(4, '{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', 1, 5, '', 1, 3, NULL, '2023-06-02 15:45:25.896', '2023-06-02 16:03:23.125', 0, 0, NULL, 'MapReduce澶勭悊鍣ㄦ祴璇�', NULL, '{}', '{"type":1}', 0, 0, 0.0, 0.0, 0.0, NULL, NULL, 'org.dromara.job.processors.MapReduceProcessorDemo', 1, 2, NULL, 1, '1000', 3);
 
 
 -- pj_oms_lock definition
diff --git a/script/sql/ry_vue_5.X.sql b/script/sql/ry_vue_5.X.sql
index 09f15ff..ea365bd 100644
--- a/script/sql/ry_vue_5.X.sql
+++ b/script/sql/ry_vue_5.X.sql
@@ -285,7 +285,7 @@
 insert into sys_menu values('114',  '琛ㄥ崟鏋勫缓',     '3',   '1', 'build',            'tool/build/index',             '', 1, 0, 'C', '0', '0', 'tool:build:list',             'build',         103, 1, sysdate(), null, null, '琛ㄥ崟鏋勫缓鑿滃崟');
 insert into sys_menu values('115',  '浠g爜鐢熸垚',     '3',   '2', 'gen',              'tool/gen/index',               '', 1, 0, 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, sysdate(), null, null, '浠g爜鐢熸垚鑿滃崟');
 insert into sys_menu values('121',  '绉熸埛绠$悊',     '6',   '1', 'tenant',           'system/tenant/index',          '', 1, 0, 'C', '0', '0', 'system:tenant:list',          'list',          103, 1, sysdate(), null, null, '绉熸埛绠$悊鑿滃崟');
-insert into sys_menu values('122',  '绉熸埛濂楅绠$悊', '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate(), null, null, '绉熸埛濂楅绠$悊鑿滃崟');
+insert into sys_menu values('122',  '绉熸埛濂楅绠$悊',  '6',   '2', 'tenantPackage',    'system/tenantPackage/index',   '', 1, 0, 'C', '0', '0', 'system:tenantPackage:list',   'form',          103, 1, sysdate(), null, null, '绉熸埛濂楅绠$悊鑿滃崟');
 insert into sys_menu values('123',  '瀹㈡埛绔鐞�',   '1',   '11', 'client',           'system/client/index',          '', 1, 0, 'C', '0', '0', 'system:client:list',          'international', 103, 1, sysdate(), null, null, '瀹㈡埛绔鐞嗚彍鍗�');
 
 -- springboot-admin鐩戞帶
@@ -370,8 +370,11 @@
 insert into sys_menu values('1601', '鏂囦欢涓婁紶', '118', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:upload',       '#', 103, 1, sysdate(), null, null, '');
 insert into sys_menu values('1602', '鏂囦欢涓嬭浇', '118', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:download',     '#', 103, 1, sysdate(), null, null, '');
 insert into sys_menu values('1603', '鏂囦欢鍒犻櫎', '118', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:remove',       '#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values('1604', '閰嶇疆娣诲姞', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:add',          '#', 103, 1, sysdate(), null, null, '');
-insert into sys_menu values('1605', '閰嶇疆缂栬緫', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:oss:edit',         '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1620', '閰嶇疆鍒楄〃', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:list',        '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1621', '閰嶇疆娣诲姞', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:add',         '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1622', '閰嶇疆缂栬緫', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:edit',        '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1623', '閰嶇疆鍒犻櫎', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:remove',      '#', 103, 1, sysdate(), null, null, '');
+
 -- 绉熸埛绠$悊鐩稿叧鎸夐挳
 insert into sys_menu values ('1606', '绉熸埛鏌ヨ', '121', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenant:query',   '#', 103, 1, sysdate(), null, null, '');
 insert into sys_menu values ('1607', '绉熸埛鏂板', '121', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:tenant:add',     '#', 103, 1, sysdate(), null, null, '');
diff --git a/script/sql/sqlserver/powerjob.sql b/script/sql/sqlserver/powerjob.sql
index 9233866..1148b2c 100644
--- a/script/sql/sqlserver/powerjob.sql
+++ b/script/sql/sqlserver/powerjob.sql
@@ -130,16 +130,16 @@
 SET IDENTITY_INSERT [pj_job_info] ON
 GO
 
-INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'1', N'{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', N'1', N'5', N'', N'2', N'1', NULL, N'2023-06-02 15:01:27.7170000', N'2023-07-04 17:22:12.3740000', N'1', N'0', N'', N'?????????', NULL, N'{}', N'{\"type\":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.StandaloneProcessorDemo', N'1', N'2', NULL, N'1', N'30000', N'3')
+INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'1', N'{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', N'1', N'5', N'', N'2', N'1', NULL, N'2023-06-02 15:01:27.7170000', N'2023-07-04 17:22:12.3740000', N'1', N'0', N'', N'?????????', NULL, N'{}', N'{"type":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.StandaloneProcessorDemo', N'1', N'2', NULL, N'1', N'30000', N'3')
 GO
 
-INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'2', N'{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', N'1', N'5', N'', N'1', N'2', NULL, N'2023-06-02 15:04:45.3420000', N'2023-07-04 17:22:12.8160000', N'0', N'0', NULL, N'???????', NULL, N'{}', N'{\"type\":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.BroadcastProcessorDemo', N'1', N'2', NULL, N'1', N'30000', N'3')
+INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'2', N'{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', N'1', N'5', N'', N'1', N'2', NULL, N'2023-06-02 15:04:45.3420000', N'2023-07-04 17:22:12.8160000', N'0', N'0', NULL, N'???????', NULL, N'{}', N'{"type":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.BroadcastProcessorDemo', N'1', N'2', NULL, N'1', N'30000', N'3')
 GO
 
-INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'3', N'{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', N'1', N'5', N'', N'1', N'4', NULL, N'2023-06-02 15:13:23.5190000', N'2023-06-02 16:03:22.4210000', N'0', N'0', NULL, N'Map?????', NULL, N'{}', N'{\"type\":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.MapProcessorDemo', N'1', N'2', NULL, N'1', N'1000', N'3')
+INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'3', N'{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', N'1', N'5', N'', N'1', N'4', NULL, N'2023-06-02 15:13:23.5190000', N'2023-06-02 16:03:22.4210000', N'0', N'0', NULL, N'Map?????', NULL, N'{}', N'{"type":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.MapProcessorDemo', N'1', N'2', NULL, N'1', N'1000', N'3')
 GO
 
-INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'4', N'{\"alertThreshold\":0,\"silenceWindowLen\":0,\"statisticWindowLen\":0}', N'1', N'5', N'', N'1', N'3', NULL, N'2023-06-02 15:45:25.8960000', N'2023-06-02 16:03:23.1250000', N'0', N'0', NULL, N'MapReduce?????', NULL, N'{}', N'{\"type\":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.MapReduceProcessorDemo', N'1', N'2', NULL, N'1', N'1000', N'3')
+INSERT INTO [pj_job_info] ([id], [alarm_config], [app_id], [concurrency], [designated_workers], [dispatch_strategy], [execute_type], [extra], [gmt_create], [gmt_modified], [instance_retry_num], [instance_time_limit], [job_description], [job_name], [job_params], [lifecycle], [log_config], [max_instance_num], [max_worker_count], [min_cpu_cores], [min_disk_space], [min_memory_space], [next_trigger_time], [notify_user_ids], [processor_info], [processor_type], [status], [tag], [task_retry_num], [time_expression], [time_expression_type]) VALUES (N'4', N'{"alertThreshold":0,"silenceWindowLen":0,"statisticWindowLen":0}', N'1', N'5', N'', N'1', N'3', NULL, N'2023-06-02 15:45:25.8960000', N'2023-06-02 16:03:23.1250000', N'0', N'0', NULL, N'MapReduce?????', NULL, N'{}', N'{"type":1}', N'0', N'0', N'0.000000000000000', N'0.000000000000000', N'0.000000000000000', NULL, NULL, N'org.dromara.job.processors.MapReduceProcessorDemo', N'1', N'2', NULL, N'1', N'1000', N'3')
 GO
 
 SET IDENTITY_INSERT [pj_job_info] OFF
diff --git a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
index 2045c58..a27ac5d 100644
--- a/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
+++ b/script/sql/sqlserver/sqlserver_ry_vue_5.X.sql
@@ -1808,9 +1808,13 @@
 GO
 INSERT sys_menu VALUES (1603, N'鏂囦欢鍒犻櫎', 118, 4, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:oss:remove', N'#', 103, 1, getdate(), NULL, NULL, N'');
 GO
-INSERT sys_menu VALUES (1604, N'閰嶇疆娣诲姞', 118, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:oss:add', N'#', 103, 1, getdate(), NULL, NULL, N'');
+INSERT sys_menu VALUES (1620, N'閰嶇疆鍒楄〃', 118, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:list', N'#', 103, 1, getdate(), NULL, NULL, N'');
 GO
-INSERT sys_menu VALUES (1605, N'閰嶇疆缂栬緫', 118, 6, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:oss:edit', N'#', 103, 1, getdate(), NULL, NULL, N'');
+INSERT sys_menu VALUES (1621, N'閰嶇疆娣诲姞', 118, 6, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:add', N'#', 103, 1, getdate(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (1622, N'閰嶇疆缂栬緫', 118, 6, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:edit', N'#', 103, 1, getdate(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (1623, N'閰嶇疆鍒犻櫎', 118, 6, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:remove', N'#', 103, 1, getdate(), NULL, NULL, N'');
 GO
 -- 绉熸埛绠$悊鐩稿叧鎸夐挳
 INSERT sys_menu VALUES (1606, N'绉熸埛鏌ヨ', 121, 1, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:tenant:query', N'#', 103, 1, getdate(), NULL, NULL, N'');
diff --git a/script/sql/update/oracle/update_5.1.1-5.1.2.sql b/script/sql/update/oracle/update_5.1.1-5.1.2.sql
new file mode 100644
index 0000000..dcb5cbb
--- /dev/null
+++ b/script/sql/update/oracle/update_5.1.1-5.1.2.sql
@@ -0,0 +1,5 @@
+delete from sys_menu where menu_id in (1604, 1605);
+insert into sys_menu values('1620', '閰嶇疆鍒楄〃', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:list',   '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1621', '閰嶇疆娣诲姞', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:add',    '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1622', '閰嶇疆缂栬緫', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:edit',   '#', 103, 1, sysdate, null, null, '');
+insert into sys_menu values('1623', '閰嶇疆鍒犻櫎', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:remove', '#', 103, 1, sysdate, null, null, '');
diff --git a/script/sql/update/postgres/update_5.1.1-5.1.2.sql b/script/sql/update/postgres/update_5.1.1-5.1.2.sql
new file mode 100644
index 0000000..0e212de
--- /dev/null
+++ b/script/sql/update/postgres/update_5.1.1-5.1.2.sql
@@ -0,0 +1,6 @@
+delete from sys_menu where menu_id in (1604, 1605);
+insert into sys_menu values('1620', '閰嶇疆鍒楄〃', '118', '5', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:list',   '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1621', '閰嶇疆娣诲姞', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:add',    '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1622', '閰嶇疆缂栬緫', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:edit',   '#', 103, 1, now(), null, null, '');
+insert into sys_menu values('1623', '閰嶇疆鍒犻櫎', '118', '6', '#', '', '', '1', '0', 'F', '0', '0', 'system:ossConfig:remove', '#', 103, 1, now(), null, null, '');
+
diff --git a/script/sql/update/sqlserver/update_5.1.1-5.1.2.sql b/script/sql/update/sqlserver/update_5.1.1-5.1.2.sql
new file mode 100644
index 0000000..9133772
--- /dev/null
+++ b/script/sql/update/sqlserver/update_5.1.1-5.1.2.sql
@@ -0,0 +1,10 @@
+DELETE FROM sys_menu WHERE menu_id IN (1604, 1605);
+GO
+INSERT sys_menu VALUES (1620, N'閰嶇疆鍒楄〃', 118, 5, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:list', N'#', 103, 1, getdate(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (1621, N'閰嶇疆娣诲姞', 118, 6, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:add', N'#', 103, 1, getdate(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (1622, N'閰嶇疆缂栬緫', 118, 6, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:edit', N'#', 103, 1, getdate(), NULL, NULL, N'');
+GO
+INSERT sys_menu VALUES (1623, N'閰嶇疆鍒犻櫎', 118, 6, N'#', N'', N'', 1, 0, N'F', N'0', N'0', N'system:ossConfig:remove', N'#', 103, 1, getdate(), NULL, NULL, N'');
+GO
diff --git a/script/sql/update/update_5.1.1-5.1.2.sql b/script/sql/update/update_5.1.1-5.1.2.sql
new file mode 100644
index 0000000..6813949
--- /dev/null
+++ b/script/sql/update/update_5.1.1-5.1.2.sql
@@ -0,0 +1,6 @@
+delete from sys_menu where menu_id in (1604, 1605);
+insert into sys_menu values('1620', '閰嶇疆鍒楄〃', '118', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:list',        '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1621', '閰嶇疆娣诲姞', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:add',         '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1622', '閰嶇疆缂栬緫', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:edit',        '#', 103, 1, sysdate(), null, null, '');
+insert into sys_menu values('1623', '閰嶇疆鍒犻櫎', '118', '6', '#', '', '', 1, 0, 'F', '0', '0', 'system:ossConfig:remove',      '#', 103, 1, sysdate(), null, null, '');
+

--
Gitblit v1.9.3