疯狂的狮子Li
2023-12-22 203233fbaf8379623879957684de4d4b499b811a
!464 发布 5.1.2 版本 2023 最后一版
Merge pull request !464 from 疯狂的狮子Li/dev
已修改83个文件
已添加8个文件
已重命名2个文件
已删除6个文件
1513 ■■■■■ 文件已修改
.run/ruoyi-monitor-admin.run.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.run/ruoyi-powerjob-server.run.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.run/ruoyi-server.run.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/Dockerfile 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/SysRegisterService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/org/dromara/web/service/impl/XcxAuthStrategy.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-dev.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-prod.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application.yml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/i18n/messages.properties 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/i18n/messages_en_US.properties 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/i18n/messages_zh_CN.properties 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-bom/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheNames.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/sql/SqlUtil.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-encrypt/pom.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/annotation/ApiEncrypt.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/CryptoFilter.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/DecryptRequestBodyWrapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/filter/EncryptResponseBodyWrapper.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-encrypt/src/main/java/org/dromara/common/encrypt/properties/ApiDecryptProperties.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-mybatis/pom.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/MybatisExceptionHandler.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/constant/OssConstant.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-oss/src/main/java/org/dromara/common/oss/factory/OssFactory.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/QueueUtils.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/utils/RedisUtils.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/config/SaTokenConfig.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/core/dao/PlusSaTokenDao.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/handler/GlobalExceptionHandler.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-sms/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/constant/TransConstant.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-translation/src/main/java/org/dromara/common/translation/core/impl/NicknameTranslationImpl.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-translation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-extend/ruoyi-monitor-admin/Dockerfile 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-extend/ruoyi-powerjob-server/Dockerfile 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-extend/ruoyi-powerjob-server/pom.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/TestExcelController.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/controller/queue/DelayedQueueController.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-demo/src/main/resources/excel/多sheet列表.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysOssConfigController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysSocialController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysOssConfig.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysSocialVo.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysSocialService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysConfigServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssConfigServiceImpl.java 29 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSensitiveServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysSocialServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/bin/ry.bat 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/bin/ry.sh 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/docker/docker-compose.yml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/docker/nginx/conf/nginx.conf 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/oracle/oracle_ry_vue_5.X.sql 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/oracle/powerjob.sql 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/postgres/postgres_ry_vue_5.X.sql 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/postgres/powerjob.sql 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/ry_vue_5.X.sql 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/sqlserver/powerjob.sql 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/sqlserver/sqlserver_ry_vue_5.X.sql 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/oracle/update_5.1.1-5.1.2.sql 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/postgres/update_5.1.1-5.1.2.sql 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/sqlserver/update_5.1.1-5.1.2.sql 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/update/update_5.1.1-5.1.2.sql 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.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>
.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>
.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>
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、Jwt é™æ€ä½¿ç”¨åŠŸèƒ½é½å…¨ ä½Žè€¦åˆ é«˜æ‰©å±•                                                                                  | Spring Security é…ç½®ç¹çæ‰©å±•性极差                                                          |
| æƒé™æ³¨è§£        | é‡‡ç”¨ Sa-Token æ”¯æŒæ³¨è§£ ç™»å½•校验、角色校验、权限校验、二级认证校验、HttpBasic校验、忽略校验<br/>角色与权限校验支持多种条件 å¦‚ `AND` `OR` æˆ– `权限 OR è§’色` ç­‰å¤æ‚表达式        | åªæ”¯æŒæ˜¯å¦å­˜åœ¨åŒ¹é…                                                                          |
| ä¸‰æ–¹é‰´æƒ        | é‡‡ç”¨ JustAuth ç¬¬ä¸‰æ–¹ç™»å½•组件 æ”¯æŒå¾®ä¿¡ã€é’‰é’‰ç­‰æ•°åç§ä¸‰æ–¹è®¤è¯                                                                               | æ—                                                                                   |
| å…³ç³»æ•°æ®åº“支持     | åŽŸç”Ÿæ”¯æŒ MySQL、Oracle、PostgreSQL、SQLServer<br/>可同时使用异构切换                                                              | æ”¯æŒ Mysql、Oracle ä¸æ”¯æŒåŒæ—¶ä½¿ç”¨ã€ä¸æ”¯æŒå¼‚构切换                                                    |
| å…³ç³»æ•°æ®åº“支持     | åŽŸç”Ÿæ”¯æŒ MySQL、Oracle、PostgreSQL、SQLServer<br/>可同时使用异构切换(支持其他 mybatis-plus æ”¯æŒçš„æ‰€æœ‰æ•°æ®åº“ åªéœ€è¦å¢žåŠ jdbc依赖即可使用 è¾¾æ¢¦é‡‘仓等均有成功案例)      | æ”¯æŒ Mysql、Oracle ä¸æ”¯æŒåŒæ—¶ä½¿ç”¨ã€ä¸æ”¯æŒå¼‚构切换                                                    |
| ç¼“存数据库       | æ”¯æŒ 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/>例如 è¿‡æœŸæ—¶é—´ æœ€å¤§ç©ºé—²æ—¶é—´ ç»„最大长度等 åªéœ€ä¸€ä¸ªæ³¨è§£å³å¯å®Œæˆæ•°æ®è‡ªåŠ¨ç¼“å­˜                                      | éœ€æ‰‹åŠ¨ç¼–å†™Redis代码逻辑                                                                     |
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版本 -->
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}
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>
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())) {
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();
ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java
ÎļþÃû´Ó ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/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);
    }
    /**
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));
    }
    /**
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);
        }
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);
        });
    }
}
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);
        });
    }
}
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);
        });
    }
}
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());
        });
    }
}
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());
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 ç«¯å£ éšç€ä¸»åº”用端口飘逸 é¿å…é›†ç¾¤å†²çª
@@ -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
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 ç«¯å£ éšç€ä¸»åº”用端口飘逸 é¿å…é›†ç¾¤å†²çª
@@ -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
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,RSA ä½¿ç”¨è€…请自行更换
  publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==
  # å“åº”加密公钥 éžå¯¹ç§°ç®—法的公私钥 å¦‚:SM2,RSA ä½¿ç”¨è€…请自行更换
  # å¯¹åº”前端解密私钥 MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE=
  publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnNwrj4hi/y3CCJu868ghCG5dUj8wZK++RNlTLcXoMmdZWEQ/u02RgD5LyLAXGjLOjbMtC+/J9qofpSGTKSx/MCAwEAAQ==
  # è¯·æ±‚解密私钥 éžå¯¹ç§°ç®—法的公私钥 å¦‚:SM2,RSA ä½¿ç”¨è€…请自行更换
  # å¯¹åº”前端加密公钥 MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==
  privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y=
springdoc:
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=小程序code不能为空
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=对不起, æ‚¨çš„租户不存在,请联系管理员
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
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=小程序code不能为空
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=对不起, æ‚¨çš„租户不存在,请联系管理员
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>
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>
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";
    /**
     * åœ¨çº¿ç”¨æˆ·
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/DemoModeException.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/GlobalException.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/UtilException.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordNotMatchException.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/user/UserPasswordRetryLimitExceedException.java
ÎļþÒÑɾ³ý
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);
}
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注入风险");
            }
        }
    }
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>
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;
}
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());
                    // è¯·æ±‚解密
                    requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag());
                    // èŽ·å–åŠ å¯†æ³¨è§£
                    ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest);
                    if (ObjectUtil.isNotNull(apiEncrypt)) {
                        // å“åº”加密标志
                        encryptFlag = apiEncrypt.response();
                    } else {
                        // æ˜¯å¦æœ‰æ³¨è§£ï¼Œæœ‰å°±æŠ¥é”™ï¼Œæ²¡æœ‰æ”¾è¡Œ
                        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)) {
                    // ä»Žhandler获取注解
                    if (handler instanceof HandlerMethod handlerMethod) {
                        return handlerMethod.getMethodAnnotation(ApiEncrypt.class);
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }
    @Override
    public void destroy() {
    }
}
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);
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);
            }
        };
    }
}
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;
    /**
     * ç§é’¥
     * è¯·æ±‚解密私钥
     */
    private String privateKey;
}
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));
                            }
                        }
                    }
                }
ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/utils/ExcelUtil.java
@@ -270,6 +270,26 @@
    }
    /**
     * å¤šsheet模板导出 æ¨¡æ¿æ ¼å¼ä¸º {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 @@
    }
    /**
     * å¤šsheet模板导出 æ¨¡æ¿æ ¼å¼ä¸º {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 {
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性能分析插件 -->
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("未找到数据源,请联系管理员确认");
        }
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;
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";
    /**
     * é¢„览列表资源开关Key
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 + "'配置信息不存在!");
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)) {
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);
    }
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 @@
    }
    /**
     * èŽ·å¾—ç¼“å­˜çš„list对象(范围)
     *
     * @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 ç›¸å…³é…ç½®
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() {
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 {
                // å¦‚果尚未被设置为永久,那么再次set一次
                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 {
                // å¦‚果尚未被设置为永久,那么再次set一次
                this.setObject(key, this.getObject(key), timeout);
            }
            return;
        }
        RedisUtils.expire(key, Duration.ofSeconds(timeout));
    }
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;
        }
    }
}
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("演示模式,不允许操作");
    }
}
ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsAutoConfiguration.java
ÎļþÃû´Ó ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/SmsConfig.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 {
}
ruoyi-common/ruoyi-common-sms/src/main/java/org/dromara/common/sms/config/properties/SmsProperties.java
ÎļþÒÑɾ³ý
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
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);
            // æ”¯ä»˜å®åœ¨åˆ›å»ºå›žè°ƒåœ°å€æ—¶ï¼Œä¸å…è®¸ä½¿ç”¨localhost或者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("未获取到有效的Auth配置");
        };
    }
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环境 é‚£ä¹ˆåªåœ¨å½“前线程内生效
     * å¦‚果为未登录状态下 é‚£ä¹ˆåªåœ¨å½“前线程内生效
     */
    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环境 é‚£ä¹ˆåªåœ¨å½“前线程内生效
     * å¦‚果为未登录状态下 é‚£ä¹ˆåªåœ¨å½“前线程内生效
     */
    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;
        }
    }
}
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";
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;
    }
}
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
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);
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}
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}
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>
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, "多sheet列表", "excel/多sheet列表.xlsx", response);
    }
    /**
     * å¯¼å…¥è¡¨æ ¼
     */
    @PostMapping(value = "/importWithOptions", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
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("操作成功");
    }
ruoyi-modules/ruoyi-demo/src/main/resources/excel/¶àsheetÁбí.xlsx
Binary files differ
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) {
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) {
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));
    }
}
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)
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")
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 {
    /**
     * ä¸»å»º
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;
    /**
     * ç”¨æˆ·çš„æŽˆæƒcode,部分平台可能没有
     */
    @ExcelProperty(value = "用户的授权code,部分平台可能没有")
    private String code;
    /**
     * Twitter平台用户的附带属性,部分平台可能没有
     */
    @ExcelProperty(value = "Twitter平台用户的附带属性,部分平台可能没有")
    private String oauthToken;
    /**
     * Twitter平台用户的附带属性,部分平台可能没有
     */
    @ExcelProperty(value = "Twitter平台用户的附带属性,部分平台可能没有")
    private String oauthTokenSecret;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    private Date createTime;
}
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查询用户
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);
}
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;
        }
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));
    }
    /**
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));
        }
    }
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);
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));
    }
}
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();
    }
}
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}
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.
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
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:
      # æ—¶åŒºä¸Šæµ·
script/docker/nginx/conf/nginx.conf
@@ -108,7 +108,7 @@
        }
        # è§£å†³ powerjob ä»£ç†ä¹‹åŽé™æ€æ–‡ä»¶æ— æ³•访问的问题 è¯·å‹¿ä¿®æ”¹ä¹±åЍ
        location .*\.(js|css|jpg|png|svg|woff|ttf|ico)?$ {
        location ~ ^/(js|css|jpg|png|svg|woff|ttf|ico|img)/ {
            proxy_pass http://powerjob-server;
        }
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, '');
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
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, '');
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
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',  '代码生成',     '3',   '2', 'gen',              'tool/gen/index',               '', 1, 0, 'C', '0', '0', 'tool:gen:list',               'code',          103, 1, sysdate(), null, null, '代码生成菜单');
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, '');
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
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'');
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, '');
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, '');
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
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, '');