From 098d3347a0df808908aab8c554cd7c4febc5e6d9 Mon Sep 17 00:00:00 2001 From: 疯狂的狮子Li <15040126243@163.com> Date: 星期一, 26 八月 2024 11:43:59 +0800 Subject: [PATCH] !577 发布 5.2.2 正式版 安全性提升 Merge pull request !577 from 疯狂的狮子Li/dev --- ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java | 4 ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java | 20 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java | 1 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/MyBatisDataSourceMonitor.java | 105 ++ ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java | 5 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java | 4 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java | 8 ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java | 17 ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/controller/SseController.java | 87 ++ ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java | 7 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java | 12 .run/ruoyi-snailjob-server.run.xml | 2 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java | 57 ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml | 230 ----- ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java | 6 ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseAutoConfiguration.java | 36 ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java | 36 ruoyi-common/ruoyi-common-web/pom.xml | 13 ruoyi-admin/src/main/resources/application.yml | 14 script/docker/nginx/conf/nginx.conf | 5 ruoyi-modules/ruoyi-generator/pom.xml | 32 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java | 5 ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/utils/SseMessageUtils.java | 58 + ruoyi-admin/src/main/resources/application-prod.yml | 3 ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/dto/SseMessageDto.java | 29 ruoyi-admin/src/main/resources/application-dev.yml | 3 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java | 6 ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java | 7 ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java | 32 ruoyi-modules/ruoyi-generator/src/main/resources/vm/ts/types.ts.vm | 6 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java | 2 pom.xml | 71 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java | 8 ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/listener/SseTopicListener.java | 48 + ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java | 4 ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java | 2 ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm | 4 ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java | 4 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java | 4 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java | 4 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java | 129 ++ ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java | 8 script/docker/docker-compose.yml | 8 ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java | 4 ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm | 7 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java | 44 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java | 18 ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml | 3 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java | 4 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java | 9 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java | 5 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java | 8 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java | 3 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java | 2 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java | 16 ruoyi-common/ruoyi-common-sse/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports | 1 ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseProperties.java | 21 .run/ruoyi-server.run.xml | 6 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java | 10 ruoyi-common/ruoyi-common-excel/pom.xml | 5 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java | 13 ruoyi-modules/ruoyi-system/pom.xml | 5 ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/SecurityConfig.java | 29 .run/ruoyi-monitor-admin.run.xml | 2 ruoyi-extend/ruoyi-monitor-admin/pom.xml | 13 ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java | 12 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java | 6 ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java | 22 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java | 11 script/sql/sqlserver/snail_job_sqlserver.sql | 70 + ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml | 3 README.md | 4 ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java | 160 +++ ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java | 44 script/sql/snail_job.sql | 17 ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java | 52 + ruoyi-common/ruoyi-common-sse/pom.xml | 36 ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml | 83 -- ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java | 9 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java | 16 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java | 43 ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/ActuatorAuthFilter.java | 64 + ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java | 12 ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java | 9 ruoyi-common/ruoyi-common-bom/pom.xml | 9 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java | 5 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java | 20 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java | 11 ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm | 4 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java | 2 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java | 17 ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java | 7 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java | 16 ruoyi-admin/pom.xml | 37 ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java | 12 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java | 5 ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java | 21 ruoyi-common/pom.xml | 1 ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java | 13 /dev/null | 33 ruoyi-modules/ruoyi-workflow/pom.xml | 2 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java | 4 script/sql/postgres/snail_job_postgre.sql | 23 ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml | 3 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java | 11 ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java | 33 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java | 11 ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java | 4 ruoyi-common/ruoyi-common-core/pom.xml | 5 script/sql/oracle/snail_job_oracle.sql | 31 ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java | 36 111 files changed, 1,692 insertions(+), 731 deletions(-) diff --git a/.run/ruoyi-monitor-admin.run.xml b/.run/ruoyi-monitor-admin.run.xml index 5b32519..478b4f3 100644 --- a/.run/ruoyi-monitor-admin.run.xml +++ b/.run/ruoyi-monitor-admin.run.xml @@ -2,7 +2,7 @@ <configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> <deployment type="dockerfile"> <settings> - <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.2.1" /> + <option name="imageTag" value="ruoyi/ruoyi-monitor-admin:5.2.2" /> <option name="buildOnly" value="true" /> <option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" /> </settings> diff --git a/.run/ruoyi-server.run.xml b/.run/ruoyi-server.run.xml index 9fefae6..541800d 100644 --- a/.run/ruoyi-server.run.xml +++ b/.run/ruoyi-server.run.xml @@ -1,12 +1,12 @@ <component name="ProjectRunConfigurationManager"> - <configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> + <configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="婕旂ず鏈�"> <deployment type="dockerfile"> <settings> - <option name="imageTag" value="ruoyi/ruoyi-server:5.2.1" /> + <option name="imageTag" value="ruoyi/ruoyi-server:5.2.2" /> <option name="buildOnly" value="true" /> <option name="sourceFilePath" value="ruoyi-admin/Dockerfile" /> </settings> </deployment> <method v="2" /> </configuration> -</component> +</component> \ No newline at end of file diff --git a/.run/ruoyi-snailjob-server.run.xml b/.run/ruoyi-snailjob-server.run.xml index 914809d..5221eef 100644 --- a/.run/ruoyi-snailjob-server.run.xml +++ b/.run/ruoyi-snailjob-server.run.xml @@ -2,7 +2,7 @@ <configuration default="false" name="ruoyi-snailjob-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker"> <deployment type="dockerfile"> <settings> - <option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.2.1" /> + <option name="imageTag" value="ruoyi/ruoyi-snailjob-server:5.2.2" /> <option name="buildOnly" value="true" /> <option name="sourceFilePath" value="ruoyi-extend/ruoyi-snailjob-server/Dockerfile" /> </settings> diff --git a/README.md b/README.md index ad9c2ce..eeb3f7b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [](https://gitee.com/dromara/RuoYi-Vue-Plus/blob/master/LICENSE) [ <br> -[](https://gitee.com/dromara/RuoYi-Vue-Plus) +[](https://gitee.com/dromara/RuoYi-Vue-Plus) []() []() []() @@ -61,6 +61,7 @@ | 鏁版嵁搴撹繛鎺ユ睜 | 閲囩敤 HikariCP Spring瀹樻柟鍐呯疆杩炴帴姹� 閰嶇疆绠�鍗� 浠ユ�ц兘涓庣ǔ瀹氭�ч椈鍚嶅ぉ涓� | 閲囩敤 druid bug浼楀 绀惧尯缁存姢宸� 娲昏穬搴︿綆 閰嶇疆浼楀绻佺悙鎬ц兘涓�鑸� | | 鏁版嵁搴撲富閿� | 閲囩敤 闆姳ID 鍩轰簬鏃堕棿鎴崇殑 鏈夊簭澧為暱 鍞竴ID 鍐嶄篃涓嶇敤涓哄垎搴撳垎琛� 鏁版嵁鍚堝苟涓婚敭鍐茬獊閲嶅鑰屽彂鎰� | 閲囩敤 鏁版嵁搴撹嚜澧濱D 鏀寔鏁版嵁閲忔湁闄� 涓嶆敮鎸佸鏁版嵁婧愪富閿敮涓� | | WebSocket鍗忚 | 鍩轰簬 Spring 灏佽鐨� WebSocket 鍗忚 鎵╁睍浜員oken閴存潈涓庡垎甯冨紡浼氳瘽鍚屾 涓嶅啀鍙槸鍩轰簬鍗曟満鐨勫簾鐗� | 鏃� | +| SSE鎺ㄩ�� | 閲囩敤 Spring SSE 瀹炵幇 鎵╁睍浜員oken閴存潈涓庡垎甯冨紡浼氳瘽鍚屾 | 鏃� | | 搴忓垪鍖� | 閲囩敤 Jackson Spring瀹樻柟鍐呯疆搴忓垪鍖� 闈犺氨!!! | 閲囩敤 fastjson bugjson 杩滆繎闂诲悕 | | 鍒嗗竷寮忓箓绛� | 鍙傝�冪編鍥TIS闃查噸绯荤粺绠�鍖栧疄鐜�(缁嗚妭鍙湅鏂囨。) | 鎵嬪姩缂栧啓娉ㄨВ鍩轰簬aop瀹炵幇 | | 鍒嗗竷寮忛攣 | 閲囩敤 Lock4j 搴曞眰鍩轰簬 Redisson | 鏃� | @@ -72,6 +73,7 @@ | 鎺ュ彛鏂囨。 | 閲囩敤 SpringDoc銆乯avadoc 鏃犳敞瑙i浂鍏ヤ镜鍩轰簬java娉ㄩ噴<br/>鍙渶鎶婃敞閲婂啓濂� 鏃犻渶鍐嶅啓涓�澶у爢鐨勬枃妗f敞瑙d簡 | 閲囩敤 Springfox 宸插仠姝㈢淮鎶� 闇�瑕佺紪鍐欏ぇ閲忕殑娉ㄨВ鏉ユ敮鎸佹枃妗g敓鎴� | | 鏍¢獙妗嗘灦 | 閲囩敤 Validation 鏀寔娉ㄨВ涓庡伐鍏风被鏍¢獙 娉ㄨВ鏀寔鍥介檯鍖� | 浠呮敮鎸佹敞瑙� 涓旀敞瑙d笉鏀寔鍥介檯鍖� | | Excel妗嗘灦 | 閲囩敤 Alibaba EasyExcel 鍩轰簬鎻掍欢鍖�<br/>妗嗘灦瀵瑰叾澧炲姞浜嗗緢澶氬姛鑳� 渚嬪 鑷姩鍚堝苟鐩稿悓鍐呭 鑷姩鎺掑垪甯冨眬 瀛楀吀缈昏瘧绛� | 鍩轰簬 POI 鎵嬪啓瀹炵幇 鍔熻兘鏈夐檺 澶嶆潅 鎵╁睍鎬у樊 | +| 宸ヤ綔娴佹敮鎸� | 鏀寔鍚勭澶嶆潅瀹℃壒 杞姙 濮旀淳 鍔犲噺绛� 浼氱 鎴栫 绁ㄧ 绛夊姛鑳� | 鏃� | | 宸ュ叿绫绘鏋� | 閲囩敤 Hutool銆丩ombok 涓婄櫨绉嶅伐鍏疯鐩�90%鐨勪娇鐢ㄩ渶姹� 鍩轰簬娉ㄨВ鑷姩鐢熸垚 get set 绛夌畝鍖栨鏋跺ぇ閲忎唬鐮� | 鎵嬪啓宸ュ叿绋冲畾鎬у樊鏄撳嚭闂 宸ュ叿鏁伴噺鏈夐檺 浠g爜鑷冭偪闇�鑷繁鎵嬪啓 get set 绛� | | 鐩戞帶妗嗘灦 | 閲囩敤 SpringBoot-Admin 鍩轰簬SpringBoot瀹樻柟 actuator 鎺㈤拡鏈哄埗<br/>瀹炴椂鐩戞帶鏈嶅姟鐘舵�� 妗嗘灦杩樹负鍏舵墿灞曚簡鍦ㄧ嚎鏃ュ織鏌ョ湅鐩戞帶 | 鏃� | | 閾捐矾杩借釜 | 閲囩敤 Apache SkyWalking 杩樺湪涓鸿姹備笉鐭ラ亾鍘诲摢浜� 鍒板摢鍑轰簡闂鑰岀儲鎭煎悧<br/>鐢ㄤ簡瀹冨嵆鍙疄鏃舵煡鐪嬭姹傜粡杩囩殑姣忎竴澶勬瘡涓�涓妭鐐� | 鏃� | diff --git a/pom.xml b/pom.xml index 7094419..750673b 100644 --- a/pom.xml +++ b/pom.xml @@ -13,45 +13,46 @@ <description>RuoYi-Vue-Plus澶氱鎴风鐞嗙郴缁�</description> <properties> - <revision>5.2.1</revision> - <spring-boot.version>3.2.6</spring-boot.version> + <revision>5.2.2</revision> + <spring-boot.version>3.2.9</spring-boot.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>17</java.version> <mybatis.version>3.5.16</mybatis.version> - <springdoc.version>2.5.0</springdoc.version> + <springdoc.version>2.6.0</springdoc.version> <therapi-javadoc.version>0.15.0</therapi-javadoc.version> - <poi.version>5.2.3</poi.version> - <easyexcel.version>3.3.4</easyexcel.version> + <easyexcel.version>4.0.2</easyexcel.version> <velocity.version>2.3</velocity.version> <satoken.version>1.38.0</satoken.version> <mybatis-plus.version>3.5.7</mybatis-plus.version> <p6spy.version>3.9.1</p6spy.version> - <hutool.version>5.8.27</hutool.version> + <hutool.version>5.8.31</hutool.version> <okhttp.version>4.10.0</okhttp.version> <spring-boot-admin.version>3.2.3</spring-boot-admin.version> - <redisson.version>3.31.0</redisson.version> + <redisson.version>3.34.1</redisson.version> <lock4j.version>2.2.7</lock4j.version> <dynamic-ds.version>4.3.1</dynamic-ds.version> - <alibaba-ttl.version>2.14.4</alibaba-ttl.version> - <snailjob.version>1.0.1</snailjob.version> - <mapstruct-plus.version>1.3.6</mapstruct-plus.version> + <snailjob.version>1.1.2</snailjob.version> + <mapstruct-plus.version>1.4.4</mapstruct-plus.version> <mapstruct-plus.lombok.version>0.2.0</mapstruct-plus.lombok.version> - <lombok.version>1.18.32</lombok.version> + <lombok.version>1.18.34</lombok.version> <bouncycastle.version>1.76</bouncycastle.version> <justauth.version>1.16.6</justauth.version> <!-- 绂荤嚎IP鍦板潃瀹氫綅搴� --> <ip2region.version>2.7.0</ip2region.version> + <undertow.version>2.3.15.Final</undertow.version> <!-- OSS 閰嶇疆 --> <aws.sdk.version>2.25.15</aws.sdk.version> <aws.crt.version>0.29.13</aws.crt.version> <!-- SMS 閰嶇疆 --> - <sms4j.version>3.2.1</sms4j.version> + <sms4j.version>3.3.2</sms4j.version> <!-- 闄愬埗妗嗘灦涓殑fastjson鐗堟湰 --> <fastjson.version>1.2.83</fastjson.version> + <!-- 闈㈠悜杩愯鏃剁殑D-ORM渚濊禆 --> + <anyline.version>8.7.2-20240808</anyline.version> <!--宸ヤ綔娴侀厤缃�--> - <flowable.version>7.0.0</flowable.version> + <flowable.version>7.0.1</flowable.version> <!-- 鎻掍欢鐗堟湰 --> <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version> @@ -156,25 +157,9 @@ </dependency> <dependency> - <groupId>org.apache.poi</groupId> - <artifactId>poi</artifactId> - <version>${poi.version}</version> - </dependency> - <dependency> - <groupId>org.apache.poi</groupId> - <artifactId>poi-ooxml</artifactId> - <version>${poi.version}</version> - </dependency> - <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>${easyexcel.version}</version> - <exclusions> - <exclusion> - <groupId>org.apache.poi</groupId> - <artifactId>poi-ooxml-schemas</artifactId> - </exclusion> - </exclusions> </dependency> <!-- velocity浠g爜鐢熸垚浣跨敤妯℃澘 --> @@ -307,12 +292,6 @@ <version>${snailjob.version}</version> </dependency> - <dependency> - <groupId>com.alibaba</groupId> - <artifactId>transmittable-thread-local</artifactId> - <version>${alibaba-ttl.version}</version> - </dependency> - <!-- 鍔犲瘑鍖呭紩鍏� --> <dependency> <groupId>org.bouncycastle</groupId> @@ -334,6 +313,28 @@ </dependency> <dependency> + <groupId>io.undertow</groupId> + <artifactId>undertow-core</artifactId> + <version>${undertow.version}</version> + </dependency> + <dependency> + <groupId>io.undertow</groupId> + <artifactId>undertow-servlet</artifactId> + <version>${undertow.version}</version> + </dependency> + <dependency> + <groupId>io.undertow</groupId> + <artifactId>undertow-websockets-jsr</artifactId> + <version>${undertow.version}</version> + </dependency> + + <dependency> + <artifactId>commons-compress</artifactId> + <groupId>org.apache.commons</groupId> + <version>1.26.2</version> + </dependency> + + <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 610e9d7..9e97804 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -22,21 +22,28 @@ <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> </dependency> - <!-- Oracle --> - <dependency> - <groupId>com.oracle.database.jdbc</groupId> - <artifactId>ojdbc8</artifactId> - </dependency> - <!-- PostgreSql --> - <dependency> - <groupId>org.postgresql</groupId> - <artifactId>postgresql</artifactId> - </dependency> - <!-- SqlServer --> - <dependency> - <groupId>com.microsoft.sqlserver</groupId> - <artifactId>mssql-jdbc</artifactId> - </dependency> + +<!-- <!– mp鏀寔鐨勬暟鎹簱鍧囨敮鎸� 鍙渶瑕佸鍔犲搴旂殑jdbc渚濊禆鍗冲彲 –>--> +<!-- <!– Oracle –>--> +<!-- <dependency>--> +<!-- <groupId>com.oracle.database.jdbc</groupId>--> +<!-- <artifactId>ojdbc8</artifactId>--> +<!-- </dependency>--> +<!-- <!– 鍏煎oracle浣庣増鏈� –>--> +<!-- <dependency>--> +<!-- <groupId>com.oracle.database.nls</groupId>--> +<!-- <artifactId>orai18n</artifactId>--> +<!-- </dependency>--> +<!-- <!– PostgreSql –>--> +<!-- <dependency>--> +<!-- <groupId>org.postgresql</groupId>--> +<!-- <artifactId>postgresql</artifactId>--> +<!-- </dependency>--> +<!-- <!– SqlServer –>--> +<!-- <dependency>--> +<!-- <groupId>com.microsoft.sqlserver</groupId>--> +<!-- <artifactId>mssql-jdbc</artifactId>--> +<!-- </dependency>--> <dependency> <groupId>org.dromara</groupId> diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java index 1db68f1..b561693 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java @@ -24,9 +24,9 @@ import org.dromara.common.social.config.properties.SocialLoginConfigProperties; import org.dromara.common.social.config.properties.SocialProperties; import org.dromara.common.social.utils.SocialUtils; +import org.dromara.common.sse.dto.SseMessageDto; +import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.tenant.helper.TenantHelper; -import org.dromara.common.websocket.dto.WebSocketMessageDto; -import org.dromara.common.websocket.utils.WebSocketUtils; import org.dromara.system.domain.bo.SysTenantBo; import org.dromara.system.domain.vo.SysClientVo; import org.dromara.system.domain.vo.SysTenantVo; @@ -102,11 +102,11 @@ Long userId = LoginHelper.getUserId(); scheduledExecutorService.schedule(() -> { - WebSocketMessageDto dto = new WebSocketMessageDto(); + SseMessageDto dto = new SseMessageDto(); dto.setMessage("娆㈣繋鐧诲綍RuoYi-Vue-Plus鍚庡彴绠$悊绯荤粺"); - dto.setSessionKeys(List.of(userId)); - WebSocketUtils.publishMessage(dto); - }, 3, TimeUnit.SECONDS); + dto.setUserIds(List.of(userId)); + SseMessageUtils.publishMessage(dto); + }, 5, TimeUnit.SECONDS); return R.ok(loginVo); } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java index a472404..07595e0 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/listener/UserActionListener.java @@ -3,6 +3,8 @@ import cn.dev33.satoken.config.SaTokenConfig; import cn.dev33.satoken.listener.SaTokenListener; import cn.dev33.satoken.stp.SaLoginModel; +import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.convert.Convert; import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgentUtil; import lombok.RequiredArgsConstructor; @@ -81,7 +83,10 @@ */ @Override public void doLogout(String loginType, Object loginId, String tokenValue) { - RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); + String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); + TenantHelper.dynamic(tenantId, () -> { + RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); + }); log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue); } @@ -90,7 +95,10 @@ */ @Override public void doKickout(String loginType, Object loginId, String tokenValue) { - RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); + String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); + TenantHelper.dynamic(tenantId, () -> { + RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); + }); log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue); } @@ -99,7 +107,10 @@ */ @Override public void doReplaced(String loginType, Object loginId, String tokenValue) { - RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); + String tenantId = Convert.toStr(StpUtil.getExtra(tokenValue, LoginHelper.TENANT_KEY)); + TenantHelper.dynamic(tenantId, () -> { + RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue); + }); log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue); } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java index af6e7f5..c7ad917 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java @@ -4,13 +4,14 @@ import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Opt; import cn.hutool.core.util.ObjectUtil; import com.baomidou.lock.annotation.Lock4j; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.zhyd.oauth.model.AuthUser; +import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.Constants; -import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.domain.dto.RoleDTO; import org.dromara.common.core.domain.model.LoginUser; @@ -155,16 +156,13 @@ loginUser.setUserType(user.getUserType()); loginUser.setMenuPermission(permissionService.getMenuPermission(user.getUserId())); loginUser.setRolePermission(permissionService.getRolePermission(user.getUserId())); - TenantHelper.dynamic(user.getTenantId(), () -> { - SysDeptVo dept = null; - if (ObjectUtil.isNotNull(user.getDeptId())) { - dept = deptService.selectDeptById(user.getDeptId()); - } - loginUser.setDeptName(ObjectUtil.isNull(dept) ? "" : dept.getDeptName()); - loginUser.setDeptCategory(ObjectUtil.isNull(dept) ? "" : dept.getDeptCategory()); - List<SysRoleVo> roles = roleService.selectRolesByUserId(user.getUserId()); - loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class)); - }); + if (ObjectUtil.isNotNull(user.getDeptId())) { + Opt<SysDeptVo> deptOpt = Opt.of(user.getDeptId()).map(deptService::selectDeptById); + loginUser.setDeptName(deptOpt.map(SysDeptVo::getDeptName).orElse(StringUtils.EMPTY)); + loginUser.setDeptCategory(deptOpt.map(SysDeptVo::getDeptCategory).orElse(StringUtils.EMPTY)); + } + List<SysRoleVo> roles = roleService.selectRolesByUserId(user.getUserId()); + loginUser.setRoles(BeanUtil.copyToList(roles, RoleDTO.class)); return loginUser; } @@ -186,7 +184,7 @@ * 鐧诲綍鏍¢獙 */ public void checkLogin(LoginType loginType, String tenantId, String username, Supplier<Boolean> supplier) { - String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username; + String errorKey = CacheConstants.PWD_ERR_CNT_KEY + username; String loginFail = Constants.LOGIN_FAIL; // 鑾峰彇鐢ㄦ埛鐧诲綍閿欒娆℃暟锛岄粯璁や负0 (鍙嚜瀹氫箟闄愬埗绛栫暐 渚嬪: key + username + ip) diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java index 38fdc44..b5a2497 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/EmailAuthStrategy.java @@ -21,7 +21,6 @@ import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; -import org.dromara.system.domain.SysClient; import org.dromara.system.domain.SysUser; import org.dromara.system.domain.vo.SysClientVo; import org.dromara.system.domain.vo.SysUserVo; @@ -51,13 +50,12 @@ String tenantId = loginBody.getTenantId(); String email = loginBody.getEmail(); String emailCode = loginBody.getEmailCode(); - - // 閫氳繃閭鏌ユ壘鐢ㄦ埛 - SysUserVo user = loadUserByEmail(tenantId, email); - - loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode)); - // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� - LoginUser loginUser = loginService.buildLoginUser(user); + LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> { + SysUserVo user = loadUserByEmail(email); + loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode)); + // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� + return loginService.buildLoginUser(user); + }); loginUser.setClientKey(client.getClientKey()); loginUser.setDeviceType(client.getDeviceType()); SaLoginModel model = new SaLoginModel(); @@ -89,18 +87,16 @@ return code.equals(emailCode); } - private SysUserVo loadUserByEmail(String tenantId, String email) { - return TenantHelper.dynamic(tenantId, () -> { - SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().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 user; - }); + private SysUserVo loadUserByEmail(String email) { + SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().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 user; } } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java index 5d3ebd7..f28024f 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/PasswordAuthStrategy.java @@ -62,11 +62,12 @@ if (captchaEnabled) { validateCaptcha(tenantId, username, code, uuid); } - - SysUserVo user = loadUserByUsername(tenantId, username); - loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword())); - // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser - LoginUser loginUser = loginService.buildLoginUser(user); + LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> { + SysUserVo user = loadUserByUsername(username); + loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword())); + // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser + return loginService.buildLoginUser(user); + }); loginUser.setClientKey(client.getClientKey()); loginUser.setDeviceType(client.getDeviceType()); SaLoginModel model = new SaLoginModel(); @@ -107,18 +108,16 @@ } } - private SysUserVo loadUserByUsername(String tenantId, String username) { - return TenantHelper.dynamic(tenantId, () -> { - SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().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 user; - }); + private SysUserVo loadUserByUsername(String username) { + SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().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 user; } } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java index f883632..89f8462 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SmsAuthStrategy.java @@ -21,7 +21,6 @@ import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; -import org.dromara.system.domain.SysClient; import org.dromara.system.domain.SysUser; import org.dromara.system.domain.vo.SysClientVo; import org.dromara.system.domain.vo.SysUserVo; @@ -51,13 +50,12 @@ String tenantId = loginBody.getTenantId(); String phonenumber = loginBody.getPhonenumber(); String smsCode = loginBody.getSmsCode(); - - // 閫氳繃鎵嬫満鍙锋煡鎵剧敤鎴� - SysUserVo user = loadUserByPhonenumber(tenantId, phonenumber); - - loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode)); - // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� - LoginUser loginUser = loginService.buildLoginUser(user); + LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> { + SysUserVo user = loadUserByPhonenumber(phonenumber); + loginService.checkLogin(LoginType.SMS, tenantId, user.getUserName(), () -> !validateSmsCode(tenantId, phonenumber, smsCode)); + // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� + return loginService.buildLoginUser(user); + }); loginUser.setClientKey(client.getClientKey()); loginUser.setDeviceType(client.getDeviceType()); SaLoginModel model = new SaLoginModel(); @@ -89,18 +87,16 @@ return code.equals(smsCode); } - private SysUserVo loadUserByPhonenumber(String tenantId, String phonenumber) { - return TenantHelper.dynamic(tenantId, () -> { - SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().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 user; - }); + private SysUserVo loadUserByPhonenumber(String phonenumber) { + SysUserVo user = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().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 user; } } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java index 01db200..8463026 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/impl/SocialAuthStrategy.java @@ -92,11 +92,11 @@ } else { social = list.get(0); } - // 鏌ユ壘鐢ㄦ埛 - SysUserVo user = loadUser(social.getTenantId(), social.getUserId()); - - // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� - LoginUser loginUser = loginService.buildLoginUser(user); + LoginUser loginUser = TenantHelper.dynamic(social.getTenantId(), () -> { + SysUserVo user = loadUser(social.getUserId()); + // 姝ゅ鍙牴鎹櫥褰曠敤鎴风殑鏁版嵁涓嶅悓 鑷鍒涘缓 loginUser 灞炴�т笉澶熺敤缁ф壙鎵╁睍灏辫浜� + return loginService.buildLoginUser(user); + }); loginUser.setClientKey(client.getClientKey()); loginUser.setDeviceType(client.getDeviceType()); SaLoginModel model = new SaLoginModel(); @@ -116,18 +116,16 @@ return loginVo; } - private SysUserVo loadUser(String tenantId, Long userId) { - return TenantHelper.dynamic(tenantId, () -> { - SysUserVo user = userMapper.selectVoById(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", ""); - } - return user; - }); + private SysUserVo loadUser(Long userId) { + SysUserVo user = userMapper.selectVoById(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", ""); + } + return user; } } diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index ea5cafa..5e20dae 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -5,6 +5,9 @@ url: http://localhost:9090/admin instance: service-host-type: IP + metadata: + username: ${spring.boot.admin.client.username} + userpassword: ${spring.boot.admin.client.password} username: ruoyi password: 123456 diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 2a4bc11..2823bba 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -8,6 +8,9 @@ url: http://localhost:9090/admin instance: service-host-type: IP + metadata: + username: ${spring.boot.admin.client.username} + userpassword: ${spring.boot.admin.client.password} username: ruoyi password: 123456 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 27de286..5d94bef 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -121,9 +121,6 @@ # swagger 鏂囨。閰嶇疆 - /*/api-docs - /*/api-docs/** - # actuator 鐩戞帶閰嶇疆 - - /actuator - - /actuator/** # 澶氱鎴烽厤缃� tenant: @@ -259,10 +256,15 @@ logfile: external-file: ./logs/sys-console.log +--- # 榛樿/鎺ㄨ崘浣跨敤sse鎺ㄩ�� +sse: + enabled: true + path: /resource/sse + --- # websocket websocket: # 濡傛灉鍏抽棴 闇�瑕佸拰鍓嶇寮�鍏充竴璧峰叧闂� - enabled: true + enabled: false # 璺緞 path: /resource/websocket # 璁剧疆璁块棶婧愬湴鍧� @@ -270,6 +272,10 @@ --- #flowable閰嶇疆 flowable: + # 寮�鍏� 鐢ㄤ簬鍚姩/鍋滅敤宸ヤ綔娴� + enabled: true + process.enabled: ${flowable.enabled} + eventregistry.enabled: ${flowable.enabled} async-executor-activate: false #鍏抽棴瀹氭椂浠诲姟JOB # 灏哾atabaseSchemaUpdate璁剧疆涓簍rue銆傚綋Flowable鍙戠幇搴撲笌鏁版嵁搴撹〃缁撴瀯涓嶄竴鑷存椂锛屼細鑷姩灏嗘暟鎹簱琛ㄧ粨鏋勫崌绾ц嚦鏂扮増鏈�� database-schema-update: true diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 45493d3..2930fd0 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -33,6 +33,7 @@ <module>ruoyi-common-encrypt</module> <module>ruoyi-common-tenant</module> <module>ruoyi-common-websocket</module> + <module>ruoyi-common-sse</module> </modules> <artifactId>ruoyi-common</artifactId> diff --git a/ruoyi-common/ruoyi-common-bom/pom.xml b/ruoyi-common/ruoyi-common-bom/pom.xml index 5388d8c..455408d 100644 --- a/ruoyi-common/ruoyi-common-bom/pom.xml +++ b/ruoyi-common/ruoyi-common-bom/pom.xml @@ -14,7 +14,7 @@ </description> <properties> - <revision>5.2.1</revision> + <revision>5.2.2</revision> </properties> <dependencyManagement> @@ -172,6 +172,13 @@ <version>${revision}</version> </dependency> + <!-- SSE妯″潡 --> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-sse</artifactId> + <version>${revision}</version> + </dependency> + </dependencies> </dependencyManagement> diff --git a/ruoyi-common/ruoyi-common-core/pom.xml b/ruoyi-common/ruoyi-common-core/pom.xml index 5925c9b..ad37e90 100644 --- a/ruoyi-common/ruoyi-common-core/pom.xml +++ b/ruoyi-common/ruoyi-common-core/pom.xml @@ -94,11 +94,6 @@ <artifactId>ip2region</artifactId> </dependency> - <dependency> - <groupId>com.alibaba</groupId> - <artifactId>transmittable-thread-local</artifactId> - </dependency> - </dependencies> </project> diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java index 67bc8e4..ceb8370 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/CacheConstants.java @@ -22,4 +22,9 @@ */ String SYS_DICT_KEY = "sys_dict:"; + /** + * 鐧诲綍璐︽埛瀵嗙爜閿欒娆℃暟 redis key + */ + String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; + } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java index ae9bc2e..5352b11 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/GlobalConstants.java @@ -28,11 +28,6 @@ String RATE_LIMIT_KEY = GLOBAL_REDIS_KEY + "rate_limit:"; /** - * 鐧诲綍璐︽埛瀵嗙爜閿欒娆℃暟 redis key - */ - String PWD_ERR_CNT_KEY = GLOBAL_REDIS_KEY + "pwd_err_cnt:"; - - /** * 涓夋柟璁よ瘉 redis key */ String SOCIAL_AUTH_CODE_KEY = GLOBAL_REDIS_KEY + "social_auth_codes:"; diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java index 6f3b0b9..76f6dd4 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java @@ -68,6 +68,16 @@ String DICT_NORMAL = "0"; /** + * 閫氱敤瀛樺湪鏍囧織 + */ + String DEL_FLAG_NORMAL = "0"; + + /** + * 閫氱敤鍒犻櫎鏍囧織 + */ + String DEL_FLAG_REMOVED = "2"; + + /** * 鏄惁涓虹郴缁熼粯璁わ紙鏄級 */ String YES = "Y"; diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java index 0f2878d..43aef28 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/service/UserService.java @@ -66,4 +66,20 @@ * @return 鐢ㄦ埛ids */ List<Long> selectUserIdsByRoleIds(List<Long> roleIds); + + /** + * 閫氳繃瑙掕壊ID鏌ヨ鐢ㄦ埛 + * + * @param roleIds 瑙掕壊ids + * @return 鐢ㄦ埛 + */ + List<UserDTO> selectUsersByRoleIds(List<Long> roleIds); + + /** + * 閫氳繃閮ㄩ棬ID鏌ヨ鐢ㄦ埛 + * + * @param deptIds 閮ㄩ棬ids + * @return 鐢ㄦ埛 + */ + List<UserDTO> selectUsersByDeptIds(List<Long> deptIds); } diff --git a/ruoyi-common/ruoyi-common-excel/pom.xml b/ruoyi-common/ruoyi-common-excel/pom.xml index dd4a5ee..14b9410 100644 --- a/ruoyi-common/ruoyi-common-excel/pom.xml +++ b/ruoyi-common/ruoyi-common-excel/pom.xml @@ -25,6 +25,11 @@ <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> </dependency> + <dependency> + <artifactId>commons-compress</artifactId> + <groupId>org.apache.commons</groupId> + <version>1.26.2</version> + </dependency> </dependencies> </project> diff --git a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java index 7c0a48b..7c7721c 100644 --- a/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java +++ b/ruoyi-common/ruoyi-common-excel/src/main/java/org/dromara/common/excel/core/CellMergeStrategy.java @@ -107,7 +107,7 @@ } if (!cellValue.equals(val)) { - if ((i - repeatCell.getCurrent() > 1) && isMerge(list, i, field)) { + if ((i - repeatCell.getCurrent() > 1)) { cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); } map.put(field, new RepeatCell(val, i)); @@ -115,6 +115,11 @@ if (i > repeatCell.getCurrent() && isMerge(list, i, field)) { cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex, colNum, colNum)); } + } else if (!isMerge(list, i, field)) { + if ((i - repeatCell.getCurrent() > 1)) { + cellList.add(new CellRangeAddress(repeatCell.getCurrent() + rowIndex, i + rowIndex - 1, colNum, colNum)); + } + map.put(field, new RepeatCell(val, i)); } } } diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java index 1b51c27..0ea3007 100644 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java +++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/config/MailConfig.java @@ -1,7 +1,7 @@ package org.dromara.common.mail.config; +import cn.hutool.extra.mail.MailAccount; import org.dromara.common.mail.config.properties.MailProperties; -import org.dromara.common.mail.utils.MailAccount; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/GlobalMailAccount.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/GlobalMailAccount.java deleted file mode 100644 index fdae869..0000000 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/GlobalMailAccount.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.dromara.common.mail.utils; - -import cn.hutool.core.io.IORuntimeException; - -/** - * 鍏ㄥ眬閭欢甯愭埛锛屼緷璧栦簬閭欢閰嶇疆鏂囦欢{@link MailAccount#MAIL_SETTING_PATHS} - * - * @author looly - */ -public enum GlobalMailAccount { - INSTANCE; - - private final MailAccount mailAccount; - - /** - * 鏋勯�� - */ - GlobalMailAccount() { - mailAccount = createDefaultAccount(); - } - - /** - * 鑾峰緱閭欢甯愭埛 - * - * @return 閭欢甯愭埛 - */ - public MailAccount getAccount() { - return this.mailAccount; - } - - /** - * 鍒涘缓榛樿甯愭埛 - * - * @return MailAccount - */ - private MailAccount createDefaultAccount() { - for (String mailSettingPath : MailAccount.MAIL_SETTING_PATHS) { - try { - return new MailAccount(mailSettingPath); - } catch (IORuntimeException ignore) { - //ignore - } - } - return null; - } -} diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java deleted file mode 100644 index b755e73..0000000 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/InternalMailUtil.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.dromara.common.mail.utils; - -import cn.hutool.core.util.ArrayUtil; -import jakarta.mail.internet.AddressException; -import jakarta.mail.internet.InternetAddress; -import jakarta.mail.internet.MimeUtility; - -import java.io.UnsupportedEncodingException; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * 閭欢鍐呴儴宸ュ叿绫� - * - * @author looly - * @since 3.2.3 - */ -public class InternalMailUtil { - - /** - * 灏嗗涓瓧绗︿覆閭欢鍦板潃杞负{@link InternetAddress}鍒楄〃<br> - * 鍗曚釜瀛楃涓插湴鍧�鍙互鏄涓湴鍧�鍚堝苟鐨勫瓧绗︿覆 - * - * @param addrStrs 鍦板潃鏁扮粍 - * @param charset 缂栫爜锛堜富瑕佺敤浜庝腑鏂囩敤鎴峰悕鐨勭紪鐮侊級 - * @return 鍦板潃鏁扮粍 - * @since 4.0.3 - */ - public static InternetAddress[] parseAddressFromStrs(String[] addrStrs, Charset charset) { - final List<InternetAddress> resultList = new ArrayList<>(addrStrs.length); - InternetAddress[] addrs; - for (String addrStr : addrStrs) { - addrs = parseAddress(addrStr, charset); - if (ArrayUtil.isNotEmpty(addrs)) { - Collections.addAll(resultList, addrs); - } - } - return resultList.toArray(new InternetAddress[0]); - } - - /** - * 瑙f瀽绗竴涓湴鍧� - * - * @param address 鍦板潃瀛楃涓� - * @param charset 缂栫爜锛寋@code null}琛ㄧず浣跨敤绯荤粺灞炴�у畾涔夌殑缂栫爜鎴栫郴缁熺紪鐮� - * @return 鍦板潃鍒楄〃 - */ - public static InternetAddress parseFirstAddress(String address, Charset charset) { - final InternetAddress[] internetAddresses = parseAddress(address, charset); - if (ArrayUtil.isEmpty(internetAddresses)) { - try { - return new InternetAddress(address); - } catch (AddressException e) { - throw new MailException(e); - } - } - return internetAddresses[0]; - } - - /** - * 灏嗕竴涓湴鍧�瀛楃涓茶В鏋愪负澶氫釜鍦板潃<br> - * 鍦板潃闂翠娇鐢�" "銆�","銆�";"鍒嗛殧 - * - * @param address 鍦板潃瀛楃涓� - * @param charset 缂栫爜锛寋@code null}琛ㄧず浣跨敤绯荤粺灞炴�у畾涔夌殑缂栫爜鎴栫郴缁熺紪鐮� - * @return 鍦板潃鍒楄〃 - */ - public static InternetAddress[] parseAddress(String address, Charset charset) { - InternetAddress[] addresses; - try { - addresses = InternetAddress.parse(address); - } catch (AddressException e) { - throw new MailException(e); - } - //缂栫爜鐢ㄦ埛鍚� - if (ArrayUtil.isNotEmpty(addresses)) { - final String charsetStr = null == charset ? null : charset.name(); - for (InternetAddress internetAddress : addresses) { - try { - internetAddress.setPersonal(internetAddress.getPersonal(), charsetStr); - } catch (UnsupportedEncodingException e) { - throw new MailException(e); - } - } - } - - return addresses; - } - - /** - * 缂栫爜涓枃瀛楃<br> - * 缂栫爜澶辫触杩斿洖鍘熷瓧绗︿覆 - * - * @param text 琚紪鐮佺殑鏂囨湰 - * @param charset 缂栫爜 - * @return 缂栫爜鍚庣殑缁撴灉 - */ - public static String encodeText(String text, Charset charset) { - try { - return MimeUtility.encodeText(text, charset.name(), null); - } catch (UnsupportedEncodingException e) { - // ignore - } - return text; - } -} diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java deleted file mode 100644 index 6ca4b69..0000000 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/Mail.java +++ /dev/null @@ -1,483 +0,0 @@ -package org.dromara.common.mail.utils; - -import cn.hutool.core.builder.Builder; -import cn.hutool.core.io.FileUtil; -import cn.hutool.core.io.IORuntimeException; -import cn.hutool.core.io.IoUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import jakarta.activation.DataHandler; -import jakarta.activation.DataSource; -import jakarta.activation.FileDataSource; -import jakarta.activation.FileTypeMap; -import jakarta.mail.*; -import jakarta.mail.internet.MimeBodyPart; -import jakarta.mail.internet.MimeMessage; -import jakarta.mail.internet.MimeMultipart; -import jakarta.mail.internet.MimeUtility; -import jakarta.mail.util.ByteArrayDataSource; - -import java.io.*; -import java.nio.charset.Charset; -import java.util.Date; - -/** - * 閭欢鍙戦�佸鎴风 - * - * @author looly - * @since 3.2.0 - */ -public class Mail implements Builder<MimeMessage> { - @Serial - private static final long serialVersionUID = 1L; - - /** - * 閭甯愭埛淇℃伅浠ュ強涓�浜涘鎴风閰嶇疆淇℃伅 - */ - private final MailAccount mailAccount; - /** - * 鏀朵欢浜哄垪琛� - */ - private String[] tos; - /** - * 鎶勯�佷汉鍒楄〃锛坈arbon copy锛� - */ - private String[] ccs; - /** - * 瀵嗛�佷汉鍒楄〃锛坆lind carbon copy锛� - */ - private String[] bccs; - /** - * 鍥炲鍦板潃(reply-to) - */ - private String[] reply; - /** - * 鏍囬 - */ - private String title; - /** - * 鍐呭 - */ - private String content; - /** - * 鏄惁涓篐TML - */ - private boolean isHtml; - /** - * 姝f枃銆侀檮浠跺拰鍥剧墖鐨勬贩鍚堥儴鍒� - */ - private final Multipart multipart = new MimeMultipart(); - /** - * 鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负false - */ - private boolean useGlobalSession = false; - - /** - * debug杈撳嚭浣嶇疆锛屽彲浠ヨ嚜瀹氫箟debug鏃ュ織 - */ - private PrintStream debugOutput; - - /** - * 鍒涘缓閭欢瀹㈡埛绔� - * - * @param mailAccount 閭欢甯愬彿 - * @return Mail - */ - public static Mail create(MailAccount mailAccount) { - return new Mail(mailAccount); - } - - /** - * 鍒涘缓閭欢瀹㈡埛绔紝浣跨敤鍏ㄥ眬閭欢甯愭埛 - * - * @return Mail - */ - public static Mail create() { - return new Mail(); - } - - // --------------------------------------------------------------- Constructor start - - /** - * 鏋勯�狅紝浣跨敤鍏ㄥ眬閭欢甯愭埛 - */ - public Mail() { - this(GlobalMailAccount.INSTANCE.getAccount()); - } - - /** - * 鏋勯�� - * - * @param mailAccount 閭欢甯愭埛锛屽鏋滀负null浣跨敤榛樿閰嶇疆鏂囦欢鐨勫叏灞�閭欢閰嶇疆 - */ - public Mail(MailAccount mailAccount) { - mailAccount = (null != mailAccount) ? mailAccount : GlobalMailAccount.INSTANCE.getAccount(); - this.mailAccount = mailAccount.defaultIfEmpty(); - } - // --------------------------------------------------------------- Constructor end - - // --------------------------------------------------------------- Getters and Setters start - - /** - * 璁剧疆鏀朵欢浜� - * - * @param tos 鏀朵欢浜哄垪琛� - * @return this - * @see #setTos(String...) - */ - public Mail to(String... tos) { - return setTos(tos); - } - - /** - * 璁剧疆澶氫釜鏀朵欢浜� - * - * @param tos 鏀朵欢浜哄垪琛� - * @return this - */ - public Mail setTos(String... tos) { - this.tos = tos; - return this; - } - - /** - * 璁剧疆澶氫釜鎶勯�佷汉锛坈arbon copy锛� - * - * @param ccs 鎶勯�佷汉鍒楄〃 - * @return this - * @since 4.0.3 - */ - public Mail setCcs(String... ccs) { - this.ccs = ccs; - return this; - } - - /** - * 璁剧疆澶氫釜瀵嗛�佷汉锛坆lind carbon copy锛� - * - * @param bccs 瀵嗛�佷汉鍒楄〃 - * @return this - * @since 4.0.3 - */ - public Mail setBccs(String... bccs) { - this.bccs = bccs; - return this; - } - - /** - * 璁剧疆澶氫釜鍥炲鍦板潃(reply-to) - * - * @param reply 鍥炲鍦板潃(reply-to)鍒楄〃 - * @return this - * @since 4.6.0 - */ - public Mail setReply(String... reply) { - this.reply = reply; - return this; - } - - /** - * 璁剧疆鏍囬 - * - * @param title 鏍囬 - * @return this - */ - public Mail setTitle(String title) { - this.title = title; - return this; - } - - /** - * 璁剧疆姝f枃<br> - * 姝f枃鍙互鏄櫘閫氭枃鏈篃鍙互鏄疕TML锛堥粯璁ゆ櫘閫氭枃鏈級锛屽彲浠ラ�氳繃璋冪敤{@link #setHtml(boolean)} 璁剧疆鏄惁涓篐TML - * - * @param content 姝f枃 - * @return this - */ - public Mail setContent(String content) { - this.content = content; - return this; - } - - /** - * 璁剧疆鏄惁鏄疕TML - * - * @param isHtml 鏄惁涓篐TML - * @return this - */ - public Mail setHtml(boolean isHtml) { - this.isHtml = isHtml; - return this; - } - - /** - * 璁剧疆姝f枃 - * - * @param content 姝f枃鍐呭 - * @param isHtml 鏄惁涓篐TML - * @return this - */ - public Mail setContent(String content, boolean isHtml) { - setContent(content); - return setHtml(isHtml); - } - - /** - * 璁剧疆鏂囦欢绫诲瀷闄勪欢锛屾枃浠跺彲浠ユ槸鍥剧墖鏂囦欢锛屾鏃惰嚜鍔ㄨ缃甤id锛堟鏂囦腑寮曠敤鍥剧墖锛夛紝榛樿cid涓烘枃浠跺悕 - * - * @param files 闄勪欢鏂囦欢鍒楄〃 - * @return this - */ - public Mail setFiles(File... files) { - if (ArrayUtil.isEmpty(files)) { - return this; - } - - final DataSource[] attachments = new DataSource[files.length]; - for (int i = 0; i < files.length; i++) { - attachments[i] = new FileDataSource(files[i]); - } - return setAttachments(attachments); - } - - /** - * 澧炲姞闄勪欢鎴栧浘鐗囷紝闄勪欢浣跨敤{@link DataSource} 褰㈠紡琛ㄧず锛屽彲浠ヤ娇鐢▄@link FileDataSource}鍖呰鏂囦欢琛ㄧず鏂囦欢闄勪欢 - * - * @param attachments 闄勪欢鍒楄〃 - * @return this - * @since 4.0.9 - */ - public Mail setAttachments(DataSource... attachments) { - if (ArrayUtil.isNotEmpty(attachments)) { - final Charset charset = this.mailAccount.getCharset(); - MimeBodyPart bodyPart; - String nameEncoded; - try { - for (DataSource attachment : attachments) { - bodyPart = new MimeBodyPart(); - bodyPart.setDataHandler(new DataHandler(attachment)); - nameEncoded = attachment.getName(); - if (this.mailAccount.isEncodefilename()) { - nameEncoded = InternalMailUtil.encodeText(nameEncoded, charset); - } - // 鏅�氶檮浠舵枃浠跺悕 - bodyPart.setFileName(nameEncoded); - if (StrUtil.startWith(attachment.getContentType(), "image/")) { - // 鍥剧墖闄勪欢锛岀敤浜庢鏂囦腑寮曠敤鍥剧墖 - bodyPart.setContentID(nameEncoded); - } - this.multipart.addBodyPart(bodyPart); - } - } catch (MessagingException e) { - throw new MailException(e); - } - } - return this; - } - - /** - * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓诧紝鍥剧墖绫诲瀷榛樿涓�"image/jpeg" - * - * @param cid 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid} - * @param imageStream 鍥剧墖鏂囦欢 - * @return this - * @since 4.6.3 - */ - public Mail addImage(String cid, InputStream imageStream) { - return addImage(cid, imageStream, null); - } - - /** - * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓� - * - * @param cid 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid} - * @param imageStream 鍥剧墖娴侊紝涓嶅叧闂� - * @param contentType 鍥剧墖绫诲瀷锛宯ull璧嬪�奸粯璁ょ殑"image/jpeg" - * @return this - * @since 4.6.3 - */ - public Mail addImage(String cid, InputStream imageStream, String contentType) { - ByteArrayDataSource imgSource; - try { - imgSource = new ByteArrayDataSource(imageStream, ObjectUtil.defaultIfNull(contentType, "image/jpeg")); - } catch (IOException e) { - throw new IORuntimeException(e); - } - imgSource.setName(cid); - return setAttachments(imgSource); - } - - /** - * 澧炲姞鍥剧墖锛屽浘鐗囩殑閿搴斿埌閭欢妯℃澘涓殑鍗犱綅瀛楃涓� - * - * @param cid 鍥剧墖涓庡崰浣嶇锛屽崰浣嶇鏍煎紡涓篶id:${cid} - * @param imageFile 鍥剧墖鏂囦欢 - * @return this - * @since 4.6.3 - */ - public Mail addImage(String cid, File imageFile) { - InputStream in = null; - try { - in = FileUtil.getInputStream(imageFile); - return addImage(cid, in, FileTypeMap.getDefaultFileTypeMap().getContentType(imageFile)); - } finally { - IoUtil.close(in); - } - } - - /** - * 璁剧疆瀛楃闆嗙紪鐮� - * - * @param charset 瀛楃闆嗙紪鐮� - * @return this - * @see MailAccount#setCharset(Charset) - */ - public Mail setCharset(Charset charset) { - this.mailAccount.setCharset(charset); - return this; - } - - /** - * 璁剧疆鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负true - * - * @param isUseGlobalSession 鏄惁浣跨敤鍏ㄥ眬浼氳瘽锛岄粯璁や负true - * @return this - * @since 4.0.2 - */ - public Mail setUseGlobalSession(boolean isUseGlobalSession) { - this.useGlobalSession = isUseGlobalSession; - return this; - } - - /** - * 璁剧疆debug杈撳嚭浣嶇疆锛屽彲浠ヨ嚜瀹氫箟debug鏃ュ織 - * - * @param debugOutput debug杈撳嚭浣嶇疆 - * @return this - * @since 5.5.6 - */ - public Mail setDebugOutput(PrintStream debugOutput) { - this.debugOutput = debugOutput; - return this; - } - // --------------------------------------------------------------- Getters and Setters end - - @Override - public MimeMessage build() { - try { - return buildMsg(); - } catch (MessagingException e) { - throw new MailException(e); - } - } - - /** - * 鍙戦�� - * - * @return message-id - * @throws MailException 閭欢鍙戦�佸紓甯� - */ - public String send() throws MailException { - try { - return doSend(); - } catch (MessagingException e) { - if (e instanceof SendFailedException) { - // 褰撳湴鍧�鏃犳晥鏃讹紝鏄剧ず鏇村姞璇︾粏鐨勬棤鏁堝湴鍧�淇℃伅 - final Address[] invalidAddresses = ((SendFailedException) e).getInvalidAddresses(); - final String msg = StrUtil.format("Invalid Addresses: {}", ArrayUtil.toString(invalidAddresses)); - throw new MailException(msg, e); - } - throw new MailException(e); - } - } - - // --------------------------------------------------------------- Private method start - - /** - * 鎵ц鍙戦�� - * - * @return message-id - * @throws MessagingException 鍙戦�佸紓甯� - */ - private String doSend() throws MessagingException { - final MimeMessage mimeMessage = buildMsg(); - Transport.send(mimeMessage); - return mimeMessage.getMessageID(); - } - - /** - * 鏋勫缓娑堟伅 - * - * @return {@link MimeMessage}娑堟伅 - * @throws MessagingException 娑堟伅寮傚父 - */ - private MimeMessage buildMsg() throws MessagingException { - final Charset charset = this.mailAccount.getCharset(); - final MimeMessage msg = new MimeMessage(getSession()); - // 鍙戜欢浜� - final String from = this.mailAccount.getFrom(); - if (StrUtil.isEmpty(from)) { - // 鐢ㄦ埛鏈彁渚涘彂閫佹柟锛屽垯浠嶴ession涓嚜鍔ㄨ幏鍙� - msg.setFrom(); - } else { - msg.setFrom(InternalMailUtil.parseFirstAddress(from, charset)); - } - // 鏍囬 - msg.setSubject(this.title, (null == charset) ? null : charset.name()); - // 鍙戦�佹椂闂� - msg.setSentDate(new Date()); - // 鍐呭鍜岄檮浠� - msg.setContent(buildContent(charset)); - // 鏀朵欢浜� - msg.setRecipients(MimeMessage.RecipientType.TO, InternalMailUtil.parseAddressFromStrs(this.tos, charset)); - // 鎶勯�佷汉 - if (ArrayUtil.isNotEmpty(this.ccs)) { - msg.setRecipients(MimeMessage.RecipientType.CC, InternalMailUtil.parseAddressFromStrs(this.ccs, charset)); - } - // 瀵嗛�佷汉 - if (ArrayUtil.isNotEmpty(this.bccs)) { - msg.setRecipients(MimeMessage.RecipientType.BCC, InternalMailUtil.parseAddressFromStrs(this.bccs, charset)); - } - // 鍥炲鍦板潃(reply-to) - if (ArrayUtil.isNotEmpty(this.reply)) { - msg.setReplyTo(InternalMailUtil.parseAddressFromStrs(this.reply, charset)); - } - - return msg; - } - - /** - * 鏋勫缓閭欢淇℃伅涓讳綋 - * - * @param charset 缂栫爜锛寋@code null}鍒欎娇鐢▄@link MimeUtility#getDefaultJavaCharset()} - * @return 閭欢淇℃伅涓讳綋 - * @throws MessagingException 娑堟伅寮傚父 - */ - private Multipart buildContent(Charset charset) throws MessagingException { - final String charsetStr = null != charset ? charset.name() : MimeUtility.getDefaultJavaCharset(); - // 姝f枃 - final MimeBodyPart body = new MimeBodyPart(); - body.setContent(content, StrUtil.format("text/{}; charset={}", isHtml ? "html" : "plain", charsetStr)); - this.multipart.addBodyPart(body); - - return this.multipart; - } - - /** - * 鑾峰彇榛樿閭欢浼氳瘽<br> - * 濡傛灉涓哄叏灞�鍗曚緥鐨勪細璇濓紝鍒欏叏灞�鍙厑璁镐竴涓偖浠跺笎鍙凤紝鍚﹀垯姣忔鍙戦�侀偖浠朵細鏂板缓涓�涓柊鐨勪細璇� - * - * @return 閭欢浼氳瘽 {@link Session} - */ - private Session getSession() { - final Session session = MailUtils.getSession(this.mailAccount, this.useGlobalSession); - - if (null != this.debugOutput) { - session.setDebugOut(debugOutput); - } - - return session; - } - // --------------------------------------------------------------- Private method end -} diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailAccount.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailAccount.java deleted file mode 100644 index 2a732a1..0000000 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailAccount.java +++ /dev/null @@ -1,659 +0,0 @@ -package org.dromara.common.mail.utils; - -import cn.hutool.core.util.CharsetUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import cn.hutool.setting.Setting; - -import java.io.Serial; -import java.io.Serializable; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -/** - * 閭欢璐︽埛瀵硅薄 - * - * @author Luxiaolei - */ -public class MailAccount implements Serializable { - @Serial - private static final long serialVersionUID = -6937313421815719204L; - - private static final String MAIL_PROTOCOL = "mail.transport.protocol"; - private static final String SMTP_HOST = "mail.smtp.host"; - private static final String SMTP_PORT = "mail.smtp.port"; - private static final String SMTP_AUTH = "mail.smtp.auth"; - private static final String SMTP_TIMEOUT = "mail.smtp.timeout"; - private static final String SMTP_CONNECTION_TIMEOUT = "mail.smtp.connectiontimeout"; - private static final String SMTP_WRITE_TIMEOUT = "mail.smtp.writetimeout"; - - // SSL - private static final String STARTTLS_ENABLE = "mail.smtp.starttls.enable"; - private static final String SSL_ENABLE = "mail.smtp.ssl.enable"; - private static final String SSL_PROTOCOLS = "mail.smtp.ssl.protocols"; - private static final String SOCKET_FACTORY = "mail.smtp.socketFactory.class"; - private static final String SOCKET_FACTORY_FALLBACK = "mail.smtp.socketFactory.fallback"; - private static final String SOCKET_FACTORY_PORT = "smtp.socketFactory.port"; - - // System Properties - private static final String SPLIT_LONG_PARAMS = "mail.mime.splitlongparameters"; - //private static final String ENCODE_FILE_NAME = "mail.mime.encodefilename"; - //private static final String CHARSET = "mail.mime.charset"; - - // 鍏朵粬 - private static final String MAIL_DEBUG = "mail.debug"; - - public static final String[] MAIL_SETTING_PATHS = new String[]{"config/mail.setting", "config/mailAccount.setting", "mail.setting"}; - - /** - * SMTP鏈嶅姟鍣ㄥ煙鍚� - */ - private String host; - /** - * SMTP鏈嶅姟绔彛 - */ - private Integer port; - /** - * 鏄惁闇�瑕佺敤鎴峰悕瀵嗙爜楠岃瘉 - */ - private Boolean auth; - /** - * 鐢ㄦ埛鍚� - */ - private String user; - /** - * 瀵嗙爜 - */ - private String pass; - /** - * 鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯 - */ - private String from; - - /** - * 鏄惁鎵撳紑璋冭瘯妯″紡锛岃皟璇曟ā寮忎細鏄剧ず涓庨偖浠舵湇鍔″櫒閫氫俊杩囩▼锛岄粯璁や笉寮�鍚� - */ - private boolean debug; - /** - * 缂栫爜鐢ㄤ簬缂栫爜閭欢姝f枃鍜屽彂閫佷汉銆佹敹浠朵汉绛変腑鏂� - */ - private Charset charset = CharsetUtil.CHARSET_UTF_8; - /** - * 瀵逛簬瓒呴暱鍙傛暟鏄惁鍒囧垎涓哄浠斤紝榛樿涓篺alse锛堝浗鍐呴偖绠遍檮浠朵笉鏀寔鍒囧垎鐨勯檮浠跺悕锛� - */ - private boolean splitlongparameters = false; - /** - * 瀵逛簬鏂囦欢鍚嶆槸鍚︿娇鐢▄@link #charset}缂栫爜锛岄粯璁や负 {@code true} - */ - private boolean encodefilename = true; - - /** - * 浣跨敤 STARTTLS瀹夊叏杩炴帴锛孲TARTTLS鏄绾枃鏈�氫俊鍗忚鐨勬墿灞曘�傚畠灏嗙函鏂囨湰杩炴帴鍗囩骇涓哄姞瀵嗚繛鎺ワ紙TLS鎴朣SL锛夛紝 鑰屼笉鏄娇鐢ㄤ竴涓崟鐙殑鍔犲瘑閫氫俊绔彛銆� - */ - private boolean starttlsEnable = false; - /** - * 浣跨敤 SSL瀹夊叏杩炴帴 - */ - private Boolean sslEnable; - - /** - * SSL鍗忚锛屽涓崗璁敤绌烘牸鍒嗛殧 - */ - private String sslProtocols; - - /** - * 鎸囧畾瀹炵幇javax.net.SocketFactory鎺ュ彛鐨勭被鐨勫悕绉�,杩欎釜绫诲皢琚敤浜庡垱寤篠MTP鐨勫鎺ュ瓧 - */ - private String socketFactoryClass = "javax.net.ssl.SSLSocketFactory"; - /** - * 濡傛灉璁剧疆涓簍rue,鏈兘鍒涘缓涓�涓鎺ュ瓧浣跨敤鎸囧畾鐨勫鎺ュ瓧宸ュ巶绫诲皢瀵艰嚧浣跨敤java.net.Socket鍒涘缓鐨勫鎺ュ瓧绫�, 榛樿鍊间负true - */ - private boolean socketFactoryFallback; - /** - * 鎸囧畾鐨勭鍙h繛鎺ュ埌鍦ㄤ娇鐢ㄦ寚瀹氱殑濂楁帴瀛楀伐鍘傘�傚鏋滄病鏈夎缃�,灏嗕娇鐢ㄩ粯璁ょ鍙� - */ - private int socketFactoryPort = 465; - - /** - * SMTP瓒呮椂鏃堕暱锛屽崟浣嶆绉掞紝缂虹渷鍊间笉瓒呮椂 - */ - private long timeout; - /** - * Socket杩炴帴瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂 - */ - private long connectionTimeout; - /** - * Socket鍐欏嚭瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂 - */ - private long writeTimeout; - - /** - * 鑷畾涔夌殑鍏朵粬灞炴�э紝姝よ嚜瀹氫箟灞炴�т細瑕嗙洊榛樿灞炴�� - */ - private final Map<String, Object> customProperty = new HashMap<>(); - - // -------------------------------------------------------------- Constructor start - - /** - * 鏋勯��,鎵�鏈夊弬鏁伴渶鑷瀹氫箟鎴栦繚鎸侀粯璁ゅ�� - */ - public MailAccount() { - } - - /** - * 鏋勯�� - * - * @param settingPath 閰嶇疆鏂囦欢璺緞 - */ - public MailAccount(String settingPath) { - this(new Setting(settingPath)); - } - - /** - * 鏋勯�� - * - * @param setting 閰嶇疆鏂囦欢 - */ - public MailAccount(Setting setting) { - setting.toBean(this); - } - - // -------------------------------------------------------------- Constructor end - - /** - * 鑾峰緱SMTP鏈嶅姟鍣ㄥ煙鍚� - * - * @return SMTP鏈嶅姟鍣ㄥ煙鍚� - */ - public String getHost() { - return host; - } - - /** - * 璁剧疆SMTP鏈嶅姟鍣ㄥ煙鍚� - * - * @param host SMTP鏈嶅姟鍣ㄥ煙鍚� - * @return this - */ - public MailAccount setHost(String host) { - this.host = host; - return this; - } - - /** - * 鑾峰緱SMTP鏈嶅姟绔彛 - * - * @return SMTP鏈嶅姟绔彛 - */ - public Integer getPort() { - return port; - } - - /** - * 璁剧疆SMTP鏈嶅姟绔彛 - * - * @param port SMTP鏈嶅姟绔彛 - * @return this - */ - public MailAccount setPort(Integer port) { - this.port = port; - return this; - } - - /** - * 鏄惁闇�瑕佺敤鎴峰悕瀵嗙爜楠岃瘉 - * - * @return 鏄惁闇�瑕佺敤鎴峰悕瀵嗙爜楠岃瘉 - */ - public Boolean isAuth() { - return auth; - } - - /** - * 璁剧疆鏄惁闇�瑕佺敤鎴峰悕瀵嗙爜楠岃瘉 - * - * @param isAuth 鏄惁闇�瑕佺敤鎴峰悕瀵嗙爜楠岃瘉 - * @return this - */ - public MailAccount setAuth(boolean isAuth) { - this.auth = isAuth; - return this; - } - - /** - * 鑾峰彇鐢ㄦ埛鍚� - * - * @return 鐢ㄦ埛鍚� - */ - public String getUser() { - return user; - } - - /** - * 璁剧疆鐢ㄦ埛鍚� - * - * @param user 鐢ㄦ埛鍚� - * @return this - */ - public MailAccount setUser(String user) { - this.user = user; - return this; - } - - /** - * 鑾峰彇瀵嗙爜 - * - * @return 瀵嗙爜 - */ - public String getPass() { - return pass; - } - - /** - * 璁剧疆瀵嗙爜 - * - * @param pass 瀵嗙爜 - * @return this - */ - public MailAccount setPass(String pass) { - this.pass = pass; - return this; - } - - /** - * 鑾峰彇鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯 - * - * @return 鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯 - */ - public String getFrom() { - return from; - } - - /** - * 璁剧疆鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯<br> - * 鍙戜欢浜哄彲浠ユ槸浠ヤ笅褰㈠紡锛� - * - * <pre> - * 1. user@xxx.xx - * 2. name <user@xxx.xx> - * </pre> - * - * @param from 鍙戦�佹柟锛岄伒寰猂FC-822鏍囧噯 - * @return this - */ - public MailAccount setFrom(String from) { - this.from = from; - return this; - } - - /** - * 鏄惁鎵撳紑璋冭瘯妯″紡锛岃皟璇曟ā寮忎細鏄剧ず涓庨偖浠舵湇鍔″櫒閫氫俊杩囩▼锛岄粯璁や笉寮�鍚� - * - * @return 鏄惁鎵撳紑璋冭瘯妯″紡锛岃皟璇曟ā寮忎細鏄剧ず涓庨偖浠舵湇鍔″櫒閫氫俊杩囩▼锛岄粯璁や笉寮�鍚� - * @since 4.0.2 - */ - public boolean isDebug() { - return debug; - } - - /** - * 璁剧疆鏄惁鎵撳紑璋冭瘯妯″紡锛岃皟璇曟ā寮忎細鏄剧ず涓庨偖浠舵湇鍔″櫒閫氫俊杩囩▼锛岄粯璁や笉寮�鍚� - * - * @param debug 鏄惁鎵撳紑璋冭瘯妯″紡锛岃皟璇曟ā寮忎細鏄剧ず涓庨偖浠舵湇鍔″櫒閫氫俊杩囩▼锛岄粯璁や笉寮�鍚� - * @return this - * @since 4.0.2 - */ - public MailAccount setDebug(boolean debug) { - this.debug = debug; - return this; - } - - /** - * 鑾峰彇瀛楃闆嗙紪鐮� - * - * @return 缂栫爜锛屽彲鑳戒负{@code null} - */ - public Charset getCharset() { - return charset; - } - - /** - * 璁剧疆瀛楃闆嗙紪鐮侊紝姝ら�夐」涓嶄細淇敼鍏ㄥ眬閰嶇疆锛岃嫢淇敼鍏ㄥ眬閰嶇疆锛岃璁剧疆姝ら」涓簕@code null}骞惰缃細 - * <pre> - * System.setProperty("mail.mime.charset", charset); - * </pre> - * - * @param charset 瀛楃闆嗙紪鐮侊紝{@code null} 鍒欒〃绀轰娇鐢ㄥ叏灞�璁剧疆鐨勯粯璁ょ紪鐮侊紝鍏ㄥ眬缂栫爜涓簃ail.mime.charset绯荤粺灞炴�� - * @return this - */ - public MailAccount setCharset(Charset charset) { - this.charset = charset; - return this; - } - - /** - * 瀵逛簬瓒呴暱鍙傛暟鏄惁鍒囧垎涓哄浠斤紝榛樿涓篺alse锛堝浗鍐呴偖绠遍檮浠朵笉鏀寔鍒囧垎鐨勯檮浠跺悕锛� - * - * @return 瀵逛簬瓒呴暱鍙傛暟鏄惁鍒囧垎涓哄浠� - */ - public boolean isSplitlongparameters() { - return splitlongparameters; - } - - /** - * 璁剧疆瀵逛簬瓒呴暱鍙傛暟鏄惁鍒囧垎涓哄浠斤紝榛樿涓篺alse锛堝浗鍐呴偖绠遍檮浠朵笉鏀寔鍒囧垎鐨勯檮浠跺悕锛�<br> - * 娉ㄦ剰姝ら」涓哄叏灞�璁剧疆锛屾椤逛細璋冪敤 - * <pre> - * System.setProperty("mail.mime.splitlongparameters", true) - * </pre> - * - * @param splitlongparameters 瀵逛簬瓒呴暱鍙傛暟鏄惁鍒囧垎涓哄浠� - */ - public void setSplitlongparameters(boolean splitlongparameters) { - this.splitlongparameters = splitlongparameters; - } - - /** - * 瀵逛簬鏂囦欢鍚嶆槸鍚︿娇鐢▄@link #charset}缂栫爜锛岄粯璁や负 {@code true} - * - * @return 瀵逛簬鏂囦欢鍚嶆槸鍚︿娇鐢▄@link #charset}缂栫爜锛岄粯璁や负 {@code true} - * @since 5.7.16 - */ - public boolean isEncodefilename() { - - return encodefilename; - } - - /** - * 璁剧疆瀵逛簬鏂囦欢鍚嶆槸鍚︿娇鐢▄@link #charset}缂栫爜锛屾閫夐」涓嶄細淇敼鍏ㄥ眬閰嶇疆<br> - * 濡傛灉姝ら�夐」璁剧疆涓簕@code false}锛屽垯鏄惁缂栫爜鍙栧喅浜庝袱涓郴缁熷睘鎬э細 - * <ul> - * <li>mail.mime.encodefilename 鏄惁缂栫爜闄勪欢鏂囦欢鍚�</li> - * <li>mail.mime.charset 缂栫爜鏂囦欢鍚嶇殑缂栫爜</li> - * </ul> - * - * @param encodefilename 瀵逛簬鏂囦欢鍚嶆槸鍚︿娇鐢▄@link #charset}缂栫爜 - * @since 5.7.16 - */ - public void setEncodefilename(boolean encodefilename) { - this.encodefilename = encodefilename; - } - - /** - * 鏄惁浣跨敤 STARTTLS瀹夊叏杩炴帴锛孲TARTTLS鏄绾枃鏈�氫俊鍗忚鐨勬墿灞曘�傚畠灏嗙函鏂囨湰杩炴帴鍗囩骇涓哄姞瀵嗚繛鎺ワ紙TLS鎴朣SL锛夛紝 鑰屼笉鏄娇鐢ㄤ竴涓崟鐙殑鍔犲瘑閫氫俊绔彛銆� - * - * @return 鏄惁浣跨敤 STARTTLS瀹夊叏杩炴帴 - */ - public boolean isStarttlsEnable() { - return this.starttlsEnable; - } - - /** - * 璁剧疆鏄惁浣跨敤STARTTLS瀹夊叏杩炴帴锛孲TARTTLS鏄绾枃鏈�氫俊鍗忚鐨勬墿灞曘�傚畠灏嗙函鏂囨湰杩炴帴鍗囩骇涓哄姞瀵嗚繛鎺ワ紙TLS鎴朣SL锛夛紝 鑰屼笉鏄娇鐢ㄤ竴涓崟鐙殑鍔犲瘑閫氫俊绔彛銆� - * - * @param startttlsEnable 鏄惁浣跨敤STARTTLS瀹夊叏杩炴帴 - * @return this - */ - public MailAccount setStarttlsEnable(boolean startttlsEnable) { - this.starttlsEnable = startttlsEnable; - return this; - } - - /** - * 鏄惁浣跨敤 SSL瀹夊叏杩炴帴 - * - * @return 鏄惁浣跨敤 SSL瀹夊叏杩炴帴 - */ - public Boolean isSslEnable() { - return this.sslEnable; - } - - /** - * 璁剧疆鏄惁浣跨敤SSL瀹夊叏杩炴帴 - * - * @param sslEnable 鏄惁浣跨敤SSL瀹夊叏杩炴帴 - * @return this - */ - public MailAccount setSslEnable(Boolean sslEnable) { - this.sslEnable = sslEnable; - return this; - } - - /** - * 鑾峰彇SSL鍗忚锛屽涓崗璁敤绌烘牸鍒嗛殧 - * - * @return SSL鍗忚锛屽涓崗璁敤绌烘牸鍒嗛殧 - * @since 5.5.7 - */ - public String getSslProtocols() { - return sslProtocols; - } - - /** - * 璁剧疆SSL鍗忚锛屽涓崗璁敤绌烘牸鍒嗛殧 - * - * @param sslProtocols SSL鍗忚锛屽涓崗璁敤绌烘牸鍒嗛殧 - * @since 5.5.7 - */ - public void setSslProtocols(String sslProtocols) { - this.sslProtocols = sslProtocols; - } - - /** - * 鑾峰彇鎸囧畾瀹炵幇javax.net.SocketFactory鎺ュ彛鐨勭被鐨勫悕绉�,杩欎釜绫诲皢琚敤浜庡垱寤篠MTP鐨勫鎺ュ瓧 - * - * @return 鎸囧畾瀹炵幇javax.net.SocketFactory鎺ュ彛鐨勭被鐨勫悕绉�, 杩欎釜绫诲皢琚敤浜庡垱寤篠MTP鐨勫鎺ュ瓧 - */ - public String getSocketFactoryClass() { - return socketFactoryClass; - } - - /** - * 璁剧疆鎸囧畾瀹炵幇javax.net.SocketFactory鎺ュ彛鐨勭被鐨勫悕绉�,杩欎釜绫诲皢琚敤浜庡垱寤篠MTP鐨勫鎺ュ瓧 - * - * @param socketFactoryClass 鎸囧畾瀹炵幇javax.net.SocketFactory鎺ュ彛鐨勭被鐨勫悕绉�,杩欎釜绫诲皢琚敤浜庡垱寤篠MTP鐨勫鎺ュ瓧 - * @return this - */ - public MailAccount setSocketFactoryClass(String socketFactoryClass) { - this.socketFactoryClass = socketFactoryClass; - return this; - } - - /** - * 濡傛灉璁剧疆涓簍rue,鏈兘鍒涘缓涓�涓鎺ュ瓧浣跨敤鎸囧畾鐨勫鎺ュ瓧宸ュ巶绫诲皢瀵艰嚧浣跨敤java.net.Socket鍒涘缓鐨勫鎺ュ瓧绫�, 榛樿鍊间负true - * - * @return 濡傛灉璁剧疆涓簍rue, 鏈兘鍒涘缓涓�涓鎺ュ瓧浣跨敤鎸囧畾鐨勫鎺ュ瓧宸ュ巶绫诲皢瀵艰嚧浣跨敤java.net.Socket鍒涘缓鐨勫鎺ュ瓧绫�, 榛樿鍊间负true - */ - public boolean isSocketFactoryFallback() { - return socketFactoryFallback; - } - - /** - * 濡傛灉璁剧疆涓簍rue,鏈兘鍒涘缓涓�涓鎺ュ瓧浣跨敤鎸囧畾鐨勫鎺ュ瓧宸ュ巶绫诲皢瀵艰嚧浣跨敤java.net.Socket鍒涘缓鐨勫鎺ュ瓧绫�, 榛樿鍊间负true - * - * @param socketFactoryFallback 濡傛灉璁剧疆涓簍rue,鏈兘鍒涘缓涓�涓鎺ュ瓧浣跨敤鎸囧畾鐨勫鎺ュ瓧宸ュ巶绫诲皢瀵艰嚧浣跨敤java.net.Socket鍒涘缓鐨勫鎺ュ瓧绫�, 榛樿鍊间负true - * @return this - */ - public MailAccount setSocketFactoryFallback(boolean socketFactoryFallback) { - this.socketFactoryFallback = socketFactoryFallback; - return this; - } - - /** - * 鑾峰彇鎸囧畾鐨勭鍙h繛鎺ュ埌鍦ㄤ娇鐢ㄦ寚瀹氱殑濂楁帴瀛楀伐鍘傘�傚鏋滄病鏈夎缃�,灏嗕娇鐢ㄩ粯璁ょ鍙� - * - * @return 鎸囧畾鐨勭鍙h繛鎺ュ埌鍦ㄤ娇鐢ㄦ寚瀹氱殑濂楁帴瀛楀伐鍘傘�傚鏋滄病鏈夎缃�,灏嗕娇鐢ㄩ粯璁ょ鍙� - */ - public int getSocketFactoryPort() { - return socketFactoryPort; - } - - /** - * 鎸囧畾鐨勭鍙h繛鎺ュ埌鍦ㄤ娇鐢ㄦ寚瀹氱殑濂楁帴瀛楀伐鍘傘�傚鏋滄病鏈夎缃�,灏嗕娇鐢ㄩ粯璁ょ鍙� - * - * @param socketFactoryPort 鎸囧畾鐨勭鍙h繛鎺ュ埌鍦ㄤ娇鐢ㄦ寚瀹氱殑濂楁帴瀛楀伐鍘傘�傚鏋滄病鏈夎缃�,灏嗕娇鐢ㄩ粯璁ょ鍙� - * @return this - */ - public MailAccount setSocketFactoryPort(int socketFactoryPort) { - this.socketFactoryPort = socketFactoryPort; - return this; - } - - /** - * 璁剧疆SMTP瓒呮椂鏃堕暱锛屽崟浣嶆绉掞紝缂虹渷鍊间笉瓒呮椂 - * - * @param timeout SMTP瓒呮椂鏃堕暱锛屽崟浣嶆绉掞紝缂虹渷鍊间笉瓒呮椂 - * @return this - * @since 4.1.17 - */ - public MailAccount setTimeout(long timeout) { - this.timeout = timeout; - return this; - } - - /** - * 璁剧疆Socket杩炴帴瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂 - * - * @param connectionTimeout Socket杩炴帴瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂 - * @return this - * @since 4.1.17 - */ - public MailAccount setConnectionTimeout(long connectionTimeout) { - this.connectionTimeout = connectionTimeout; - return this; - } - - /** - * 璁剧疆Socket鍐欏嚭瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂 - * - * @param writeTimeout Socket鍐欏嚭瓒呮椂鍊硷紝鍗曚綅姣锛岀己鐪佸�间笉瓒呮椂 - * @return this - * @since 5.8.3 - */ - public MailAccount setWriteTimeout(long writeTimeout) { - this.writeTimeout = writeTimeout; - return this; - } - - /** - * 鑾峰彇鑷畾涔夊睘鎬у垪琛� - * - * @return 鑷畾涔夊弬鏁板垪琛� - * @since 5.6.4 - */ - public Map<String, Object> getCustomProperty() { - return customProperty; - } - - /** - * 璁剧疆鑷畾涔夊睘鎬э紝濡俶ail.smtp.ssl.socketFactory - * - * @param key 灞炴�у悕锛岀┖鐧借蹇界暐 - * @param value 灞炴�у�硷紝 null琚拷鐣� - * @return this - * @since 5.6.4 - */ - public MailAccount setCustomProperty(String key, Object value) { - if (StrUtil.isNotBlank(key) && ObjectUtil.isNotNull(value)) { - this.customProperty.put(key, value); - } - return this; - } - - /** - * 鑾峰緱SMTP鐩稿叧淇℃伅 - * - * @return {@link Properties} - */ - public Properties getSmtpProps() { - //鍏ㄥ眬绯荤粺鍙傛暟 - System.setProperty(SPLIT_LONG_PARAMS, String.valueOf(this.splitlongparameters)); - - final Properties p = new Properties(); - p.put(MAIL_PROTOCOL, "smtp"); - p.put(SMTP_HOST, this.host); - p.put(SMTP_PORT, String.valueOf(this.port)); - p.put(SMTP_AUTH, String.valueOf(this.auth)); - if (this.timeout > 0) { - p.put(SMTP_TIMEOUT, String.valueOf(this.timeout)); - } - if (this.connectionTimeout > 0) { - p.put(SMTP_CONNECTION_TIMEOUT, String.valueOf(this.connectionTimeout)); - } - // issue#2355 - if (this.writeTimeout > 0) { - p.put(SMTP_WRITE_TIMEOUT, String.valueOf(this.writeTimeout)); - } - - p.put(MAIL_DEBUG, String.valueOf(this.debug)); - - if (this.starttlsEnable) { - //STARTTLS鏄绾枃鏈�氫俊鍗忚鐨勬墿灞曘�傚畠灏嗙函鏂囨湰杩炴帴鍗囩骇涓哄姞瀵嗚繛鎺ワ紙TLS鎴朣SL锛夛紝 鑰屼笉鏄娇鐢ㄤ竴涓崟鐙殑鍔犲瘑閫氫俊绔彛銆� - p.put(STARTTLS_ENABLE, "true"); - - if (null == this.sslEnable) { - //涓轰簡鍏煎鏃х増鏈紝褰撶敤鎴锋病鏈夋椤归厤缃椂锛屾寜鐓tarttlsEnable寮�鍚姸鎬佹椂瀵瑰緟 - this.sslEnable = true; - } - } - - // SSL - if (null != this.sslEnable && this.sslEnable) { - p.put(SSL_ENABLE, "true"); - p.put(SOCKET_FACTORY, socketFactoryClass); - p.put(SOCKET_FACTORY_FALLBACK, String.valueOf(this.socketFactoryFallback)); - p.put(SOCKET_FACTORY_PORT, String.valueOf(this.socketFactoryPort)); - // issue#IZN95@Gitee锛屽湪Linux涓嬮渶鑷畾涔塖SL鍗忚鐗堟湰 - if (StrUtil.isNotBlank(this.sslProtocols)) { - p.put(SSL_PROTOCOLS, this.sslProtocols); - } - } - - // 琛ュ厖鑷畾涔夊睘鎬э紝鍏佽鑷畾灞炴�ц鐩栧凡缁忚缃殑鍊� - p.putAll(this.customProperty); - - return p; - } - - /** - * 濡傛灉鏌愪簺鍊间负null锛屼娇鐢ㄩ粯璁ゅ�� - * - * @return this - */ - public MailAccount defaultIfEmpty() { - // 鍘绘帀鍙戜欢浜虹殑濮撳悕閮ㄥ垎 - final String fromAddress = InternalMailUtil.parseFirstAddress(this.from, this.charset).getAddress(); - - if (StrUtil.isBlank(this.host)) { - // 濡傛灉SMTP鍦板潃涓虹┖锛岄粯璁や娇鐢╯mtp.<鍙戜欢浜洪偖绠卞悗缂�> - this.host = StrUtil.format("smtp.{}", StrUtil.subSuf(fromAddress, fromAddress.indexOf('@') + 1)); - } - if (StrUtil.isBlank(user)) { - // 濡傛灉鐢ㄦ埛鍚嶄负绌猴紝榛樿涓哄彂浠朵汉锛坕ssue#I4FYVY@Gitee锛� - //this.user = StrUtil.subPre(fromAddress, fromAddress.indexOf('@')); - this.user = fromAddress; - } - if (null == this.auth) { - // 濡傛灉瀵嗙爜闈炵┖鐧斤紝鍒欎娇鐢ㄨ璇佹ā寮� - this.auth = (false == StrUtil.isBlank(this.pass)); - } - if (null == this.port) { - // 绔彛鍦⊿SL鐘舵�佷笅榛樿涓巗ocketFactoryPort涓�鑷达紝闈濻SL鐘舵�佷笅榛樿涓�25 - this.port = (null != this.sslEnable && this.sslEnable) ? this.socketFactoryPort : 25; - } - if (null == this.charset) { - // 榛樿UTF-8缂栫爜 - this.charset = CharsetUtil.CHARSET_UTF_8; - } - - return this; - } - - @Override - public String toString() { - return "MailAccount [host=" + host + ", port=" + port + ", auth=" + auth + ", user=" + user + ", pass=" + (StrUtil.isEmpty(this.pass) ? "" : "******") + ", from=" + from + ", startttlsEnable=" - + starttlsEnable + ", socketFactoryClass=" + socketFactoryClass + ", socketFactoryFallback=" + socketFactoryFallback + ", socketFactoryPort=" + socketFactoryPort + "]"; - } -} diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailException.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailException.java deleted file mode 100644 index cc199d4..0000000 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailException.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.dromara.common.mail.utils; - -import cn.hutool.core.exceptions.ExceptionUtil; -import cn.hutool.core.util.StrUtil; - -import java.io.Serial; - -/** - * 閭欢寮傚父 - * - * @author xiaoleilu - */ -public class MailException extends RuntimeException { - @Serial - private static final long serialVersionUID = 8247610319171014183L; - - public MailException(Throwable e) { - super(ExceptionUtil.getMessage(e), e); - } - - public MailException(String message) { - super(message); - } - - public MailException(String messageTemplate, Object... params) { - super(StrUtil.format(messageTemplate, params)); - } - - public MailException(String message, Throwable throwable) { - super(message, throwable); - } - - public MailException(String message, Throwable throwable, boolean enableSuppression, boolean writableStackTrace) { - super(message, throwable, enableSuppression, writableStackTrace); - } - - public MailException(Throwable throwable, String messageTemplate, Object... params) { - super(StrUtil.format(messageTemplate, params), throwable); - } -} diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java index 040cc57..a28701f 100644 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java +++ b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/MailUtils.java @@ -5,6 +5,9 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.CharUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.mail.JakartaMail; +import cn.hutool.extra.mail.JakartaUserPassAuthenticator; +import cn.hutool.extra.mail.MailAccount; import jakarta.mail.Authenticator; import jakarta.mail.Session; import lombok.AccessLevel; @@ -17,7 +20,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; - +import java.util.Map.Entry; /** * 閭欢宸ュ叿绫� @@ -385,7 +388,7 @@ public static Session getSession(MailAccount mailAccount, boolean isSingleton) { Authenticator authenticator = null; if (mailAccount.isAuth()) { - authenticator = new UserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass()); + authenticator = new JakartaUserPassAuthenticator(mailAccount.getUser(), mailAccount.getPass()); } return isSingleton ? Session.getDefaultInstance(mailAccount.getSmtpProps(), authenticator) // @@ -412,7 +415,7 @@ */ private static String send(MailAccount mailAccount, boolean useGlobalSession, Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, Map<String, InputStream> imageMap, boolean isHtml, File... files) { - final Mail mail = Mail.create(mailAccount).setUseGlobalSession(useGlobalSession); + final JakartaMail mail = JakartaMail.create(mailAccount).setUseGlobalSession(useGlobalSession); // 鍙�夋妱閫佷汉 if (CollUtil.isNotEmpty(ccs)) { @@ -431,7 +434,7 @@ // 鍥剧墖 if (MapUtil.isNotEmpty(imageMap)) { - for (Map.Entry<String, InputStream> entry : imageMap.entrySet()) { + for (Entry<String, InputStream> entry : imageMap.entrySet()) { mail.addImage(entry.getKey(), entry.getValue()); // 鍏抽棴娴� IoUtil.close(entry.getValue()); @@ -463,5 +466,4 @@ return result; } // ------------------------------------------------------------------------------------------------------------------------ Private method end - } diff --git a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java b/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java deleted file mode 100644 index fbbe5e3..0000000 --- a/ruoyi-common/ruoyi-common-mail/src/main/java/org/dromara/common/mail/utils/UserPassAuthenticator.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.dromara.common.mail.utils; - -import jakarta.mail.Authenticator; -import jakarta.mail.PasswordAuthentication; - -/** - * 鐢ㄦ埛鍚嶅瘑鐮侀獙璇佸櫒 - * - * @author looly - * @since 3.1.2 - */ -public class UserPassAuthenticator extends Authenticator { - - private final String user; - private final String pass; - - /** - * 鏋勯�� - * - * @param user 鐢ㄦ埛鍚� - * @param pass 瀵嗙爜 - */ - public UserPassAuthenticator(String user, String pass) { - this.user = user; - this.pass = pass; - } - - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(this.user, this.pass); - } - -} diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java index f8c5cd0..2879b9d 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataColumn.java @@ -30,4 +30,11 @@ */ String[] value() default "dept_id"; + /** + * 鏉冮檺鏍囪瘑绗� 鐢ㄤ簬閫氳繃鑿滃崟鏉冮檺鏍囪瘑绗︽潵鑾峰彇鏁版嵁鏉冮檺 + * 鎷ユ湁姝ゆ爣璇嗙鐨勮鑹� 灏嗕笉浼氭嫾鎺ユ瑙掕壊鐨勬暟鎹繃婊ql + * + * @return 鏉冮檺鏍囪瘑绗� + */ + String permission() default ""; } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java index 6fd3c3e..f5f22d5 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/annotation/DataPermission.java @@ -20,4 +20,11 @@ */ DataColumn[] value(); + /** + * 鏉冮檺鎷兼帴鏍囪瘑绗�(鐢ㄤ簬鎸囧畾杩炴帴璇彞鐨剆ql绗﹀彿) + * 濡備笉濉� 榛樿 select 鐢� OR 鍏朵粬璇彞鐢� AND + * 鍐呭 OR 鎴栬�� AND + */ + String joinStr() default ""; + } diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java index 455cecb..981bd42 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/enums/DataScopeType.java @@ -13,9 +13,9 @@ * 鍐呯疆鏁版嵁锛� * - {@code user}: 褰撳墠鐧诲綍鐢ㄦ埛淇℃伅锛屽弬鑰� {@link LoginUser} * 鍐呯疆鏈嶅姟锛� - * - {@code sdss}: 绯荤粺鏁版嵁鏉冮檺鏈嶅姟锛屽弬鑰� {@link ISysDataScopeService} + * - {@code sdss}: 绯荤粺鏁版嵁鏉冮檺鏈嶅姟锛屽弬鑰� ISysDataScopeService * 濡傞渶鎵╁睍鏁版嵁锛屽彲浠ラ�氳繃 {@link DataPermissionHelper} 杩涜鎿嶄綔 - * 濡傞渶鎵╁睍鏈嶅姟锛屽彲浠ラ�氳繃 {@link ISysDataScopeService} 鑷缂栧啓 + * 濡傞渶鎵╁睍鏈嶅姟锛屽彲浠ラ�氳繃 ISysDataScopeService 鑷缂栧啓 * </p> * * @author Lion Li @@ -32,29 +32,21 @@ /** * 鑷畾鏁版嵁鏉冮檺 - * 浣跨敤 SpEL 琛ㄨ揪寮忥細`#{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} )` - * 濡傛灉涓嶆弧瓒虫潯浠讹紝鍒欎娇鐢ㄩ粯璁� SQL 琛ㄨ揪寮忥細`1 = 0` */ CUSTOM("2", " #{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} ) ", " 1 = 0 "), /** * 閮ㄩ棬鏁版嵁鏉冮檺 - * 浣跨敤 SpEL 琛ㄨ揪寮忥細`#{#deptName} = #{#user.deptId}` - * 濡傛灉涓嶆弧瓒虫潯浠讹紝鍒欎娇鐢ㄩ粯璁� SQL 琛ㄨ揪寮忥細`1 = 0` */ DEPT("3", " #{#deptName} = #{#user.deptId} ", " 1 = 0 "), /** * 閮ㄩ棬鍙婁互涓嬫暟鎹潈闄� - * 浣跨敤 SpEL 琛ㄨ揪寮忥細`#{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )}` - * 濡傛灉涓嶆弧瓒虫潯浠讹紝鍒欎娇鐢ㄩ粯璁� SQL 琛ㄨ揪寮忥細`1 = 0` */ DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", " 1 = 0 "), /** * 浠呮湰浜烘暟鎹潈闄� - * 浣跨敤 SpEL 琛ㄨ揪寮忥細`#{#userName} = #{#user.userId}` - * 濡傛灉涓嶆弧瓒虫潯浠讹紝鍒欎娇鐢ㄩ粯璁� SQL 琛ㄨ揪寮忥細`1 = 0` */ SELF("5", " #{#userName} = #{#user.userId} ", " 1 = 0 "); diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java index 99e6b38..7d44d26 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/InjectionMetaObjectHandler.java @@ -48,6 +48,10 @@ ? baseEntity.getCreateDept() : loginUser.getDeptId()); } } + } else { + Date date = new Date(); + this.strictInsertFill(metaObject, "createTime", Date.class, date); + this.strictInsertFill(metaObject, "updateTime", Date.class, date); } } catch (Exception e) { throw new ServiceException("鑷姩娉ㄥ叆寮傚父 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED); @@ -72,6 +76,8 @@ if (ObjectUtil.isNotNull(userId)) { baseEntity.setUpdateBy(userId); } + } else { + this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date()); } } catch (Exception e) { throw new ServiceException("鑷姩娉ㄥ叆寮傚父 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED); diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java index 74279bd..5ac74c3 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java @@ -99,7 +99,7 @@ return where; } // 鏋勯�犳暟鎹繃婊ゆ潯浠剁殑 SQL 鐗囨 - String dataFilterSql = buildDataFilter(dataPermission.value(), isSelect); + String dataFilterSql = buildDataFilter(dataPermission, isSelect); if (StringUtils.isBlank(dataFilterSql)) { return where; } @@ -120,14 +120,17 @@ /** * 鏋勫缓鏁版嵁杩囨护鏉′欢鐨� SQL 璇彞 * - * @param dataColumns 鏁版嵁鏉冮檺娉ㄨВ涓殑鍒椾俊鎭� - * @param isSelect 鏍囧織褰撳墠鎿嶄綔鏄惁涓烘煡璇㈡搷浣滐紝鏌ヨ鎿嶄綔鍜屾洿鏂版垨鍒犻櫎鎿嶄綔鍦ㄥ鐞嗚繃婊ゆ潯浠舵椂浼氭湁涓嶅悓鐨勫鐞嗘柟寮� + * @param dataPermission 鏁版嵁鏉冮檺娉ㄨВ + * @param isSelect 鏍囧織褰撳墠鎿嶄綔鏄惁涓烘煡璇㈡搷浣滐紝鏌ヨ鎿嶄綔鍜屾洿鏂版垨鍒犻櫎鎿嶄綔鍦ㄥ鐞嗚繃婊ゆ潯浠舵椂浼氭湁涓嶅悓鐨勫鐞嗘柟寮� * @return 鏋勫缓鐨勬暟鎹繃婊ゆ潯浠剁殑 SQL 璇彞 * @throws ServiceException 濡傛灉瑙掕壊鐨勬暟鎹寖鍥村紓甯告垨鑰� key 涓� value 鐨勯暱搴︿笉鍖归厤锛屽垯鎶涘嚭 ServiceException 寮傚父 */ - private String buildDataFilter(DataColumn[] dataColumns, boolean isSelect) { + private String buildDataFilter(DataPermission dataPermission, boolean isSelect) { // 鏇存柊鎴栧垹闄ら渶婊¤冻鎵�鏈夋潯浠� String joinStr = isSelect ? " OR " : " AND "; + if (StringUtils.isNotBlank(dataPermission.joinStr())) { + joinStr = " " + dataPermission.joinStr() + " "; + } LoginUser user = DataPermissionHelper.getVariable("user"); StandardEvaluationContext context = new StandardEvaluationContext(); context.setBeanResolver(beanResolver); @@ -145,7 +148,7 @@ return ""; } boolean isSuccess = false; - for (DataColumn dataColumn : dataColumns) { + for (DataColumn dataColumn : dataPermission.value()) { if (dataColumn.key().length != dataColumn.value().length) { throw new ServiceException("瑙掕壊鏁版嵁鑼冨洿寮傚父 => key涓巚alue闀垮害涓嶅尮閰�"); } @@ -155,6 +158,13 @@ )) { continue; } + // 鍖呭惈鏉冮檺鏍囪瘑绗� 杩欑洿鎺ヨ烦杩� + if (StringUtils.isNotBlank(dataColumn.permission()) && + CollUtil.contains(user.getMenuPermission(), dataColumn.permission()) + ) { + isSuccess = true; + continue; + } // 璁剧疆娉ㄨВ鍙橀噺 key 涓鸿〃杈惧紡鍙橀噺 value 涓哄彉閲忓�� for (int i = 0; i < dataColumn.key().length; i++) { context.setVariable(dataColumn.key()[i], dataColumn.value()[i]); diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java index 2afe9ee..932f173 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java @@ -2,14 +2,17 @@ import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.model.SaStorage; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.dromara.common.core.utils.reflect.ReflectUtils; import java.util.HashMap; import java.util.Map; +import java.util.Stack; import java.util.function.Supplier; /** @@ -23,6 +26,8 @@ public class DataPermissionHelper { private static final String DATA_PERMISSION_KEY = "data:permission"; + + private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new); /** * 浠庝笂涓嬫枃涓幏鍙栨寚瀹氶敭鐨勫彉閲忓�硷紝骞跺皢鍏惰浆鎹负鎸囧畾鐨勭被鍨� @@ -66,23 +71,54 @@ throw new NullPointerException("data permission context type exception"); } + private static IgnoreStrategy getIgnoreStrategy() { + Object ignoreStrategyLocal = ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL")); + if (ignoreStrategyLocal instanceof ThreadLocal<?> IGNORE_STRATEGY_LOCAL) { + if (IGNORE_STRATEGY_LOCAL.get() instanceof IgnoreStrategy ignoreStrategy) { + return ignoreStrategy; + } + } + return null; + } + /** * 寮�鍚拷鐣ユ暟鎹潈闄�(寮�鍚悗闇�鎵嬪姩璋冪敤 {@link #disableIgnore()} 鍏抽棴) */ public static void enableIgnore() { - InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().dataPermission(true).build()); + IgnoreStrategy ignoreStrategy = getIgnoreStrategy(); + if (ObjectUtil.isNull(ignoreStrategy)) { + InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().dataPermission(true).build()); + } else { + ignoreStrategy.setDataPermission(true); + } + Stack<Integer> reentrantStack = REENTRANT_IGNORE.get(); + reentrantStack.push(reentrantStack.size() + 1); } /** * 鍏抽棴蹇界暐鏁版嵁鏉冮檺 */ public static void disableIgnore() { - InterceptorIgnoreHelper.clearIgnoreStrategy(); + IgnoreStrategy ignoreStrategy = getIgnoreStrategy(); + if (ObjectUtil.isNotNull(ignoreStrategy)) { + boolean noOtherIgnoreStrategy = !Boolean.TRUE.equals(ignoreStrategy.getDynamicTableName()) + && !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack()) + && !Boolean.TRUE.equals(ignoreStrategy.getIllegalSql()) + && !Boolean.TRUE.equals(ignoreStrategy.getTenantLine()) + && CollectionUtil.isEmpty(ignoreStrategy.getOthers()); + Stack<Integer> reentrantStack = REENTRANT_IGNORE.get(); + boolean empty = reentrantStack.isEmpty() || reentrantStack.pop() == 1; + if (noOtherIgnoreStrategy && empty) { + InterceptorIgnoreHelper.clearIgnoreStrategy(); + } else if (empty) { + ignoreStrategy.setDataPermission(false); + } + + } } /** * 鍦ㄥ拷鐣ユ暟鎹潈闄愪腑鎵ц - * <p>绂佹鍦ㄥ拷鐣ユ暟鎹潈闄愪腑鎵ц蹇界暐鏁版嵁鏉冮檺</p> * * @param handle 澶勭悊鎵ц鏂规硶 */ @@ -97,7 +133,6 @@ /** * 鍦ㄥ拷鐣ユ暟鎹潈闄愪腑鎵ц - * <p>绂佹鍦ㄥ拷鐣ユ暟鎹潈闄愪腑鎵ц蹇界暐鏁版嵁鏉冮檺</p> * * @param handle 澶勭悊鎵ц鏂规硶 */ diff --git a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java index 02735b0..1f4904a 100644 --- a/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java +++ b/ruoyi-common/ruoyi-common-ratelimiter/src/main/java/org/dromara/common/ratelimiter/aspectj/RateLimiterAspect.java @@ -80,11 +80,11 @@ private String getCombineKey(RateLimiter rateLimiter, JoinPoint point) { String key = rateLimiter.key(); - if (StringUtils.isNotBlank(key)) { + // 鍒ゆ柇 key 涓嶄负绌� 鍜� 涓嶆槸琛ㄨ揪寮� + if (StringUtils.isNotBlank(key) && StringUtils.containsAny(key, "#")) { MethodSignature signature = (MethodSignature) point.getSignature(); Method targetMethod = signature.getMethod(); Object[] args = point.getArgs(); - //noinspection DataFlowIssue MethodBasedEvaluationContext context = new MethodBasedEvaluationContext(null, targetMethod, args, pnd); context.setBeanResolver(new BeanFactoryResolver(SpringUtils.getBeanFactory())); diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java index ee1d405..793e21f 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/CaffeineCacheDecorator.java @@ -15,15 +15,17 @@ private static final com.github.benmanes.caffeine.cache.Cache<Object, Object> CAFFEINE = SpringUtils.getBean("caffeine"); + private final String name; private final Cache cache; - public CaffeineCacheDecorator(Cache cache) { + public CaffeineCacheDecorator(String name, Cache cache) { + this.name = name; this.cache = cache; } @Override public String getName() { - return cache.getName(); + return name; } @Override @@ -32,7 +34,7 @@ } public String getUniqueKey(Object key) { - return cache.getName() + ":" + key; + return name + ":" + key; } @Override diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java index a48cb14..740e2a1 100644 --- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java +++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/manager/PlusSpringCacheManager.java @@ -156,7 +156,7 @@ private Cache createMap(String name, CacheConfig config) { RMap<Object, Object> map = RedisUtils.getClient().getMap(name); - Cache cache = new CaffeineCacheDecorator(new RedissonCache(map, allowNullValues)); + Cache cache = new CaffeineCacheDecorator(name, new RedissonCache(map, allowNullValues)); if (transactionAware) { cache = new TransactionAwareCacheDecorator(cache); } @@ -170,7 +170,7 @@ private Cache createMapCache(String name, CacheConfig config) { RMapCache<Object, Object> map = RedisUtils.getClient().getMapCache(name); - Cache cache = new CaffeineCacheDecorator(new RedissonCache(map, config, allowNullValues)); + Cache cache = new CaffeineCacheDecorator(name, new RedissonCache(map, config, allowNullValues)); if (transactionAware) { cache = new TransactionAwareCacheDecorator(cache); } diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java index b9283e0..5fd49d1 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java @@ -1,11 +1,15 @@ package org.dromara.common.security.config; import cn.dev33.satoken.exception.NotLoginException; +import cn.dev33.satoken.filter.SaServletFilter; +import cn.dev33.satoken.httpauth.basic.SaHttpBasicUtil; import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.stp.StpUtil; +import cn.dev33.satoken.util.SaResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; @@ -14,6 +18,7 @@ import org.dromara.common.security.handler.AllUrlHandler; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -71,4 +76,19 @@ .excludePathPatterns(securityProperties.getExcludes()); } + /** + * 瀵� actuator 鍋ュ悍妫�鏌ユ帴鍙� 鍋氳处鍙峰瘑鐮侀壌鏉� + */ + @Bean + public SaServletFilter getSaServletFilter() { + String username = SpringUtils.getProperty("spring.boot.admin.client.username"); + String password = SpringUtils.getProperty("spring.boot.admin.client.password"); + return new SaServletFilter() + .addInclude("/actuator", "/actuator/**") + .setAuth(obj -> { + SaHttpBasicUtil.check(username + ":" + password); + }) + .setError(e -> SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED)); + } + } diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java index 9d1978a..995dcbd 100644 --- a/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java +++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/org/dromara/common/sensitive/core/SensitiveStrategy.java @@ -37,7 +37,57 @@ /** * 閾惰鍗� */ - BANK_CARD(DesensitizedUtil::bankCard); + BANK_CARD(DesensitizedUtil::bankCard), + + /** + * 涓枃鍚� + */ + CHINESE_NAME(DesensitizedUtil::chineseName), + + /** + * 鍥哄畾鐢佃瘽 + */ + FIXED_PHONE(DesensitizedUtil::fixedPhone), + + /** + * 鐢ㄦ埛ID + */ + USER_ID(s -> String.valueOf(DesensitizedUtil.userId())), + + /** + * 瀵嗙爜 + */ + PASSWORD(DesensitizedUtil::password), + + /** + * ipv4 + */ + IPV4(DesensitizedUtil::ipv4), + + /** + * ipv6 + */ + IPV6(DesensitizedUtil::ipv6), + + /** + * 涓浗澶ч檰杞︾墝锛屽寘鍚櫘閫氳溅杈嗐�佹柊鑳芥簮杞﹁締 + */ + CAR_LICENSE(DesensitizedUtil::carLicense), + + /** + * 鍙樉绀虹涓�涓瓧绗� + */ + FIRST_MASK(DesensitizedUtil::firstMask), + + /** + * 娓呯┖涓簄ull + */ + CLEAR(s -> DesensitizedUtil.clear()), + + /** + * 娓呯┖涓�"" + */ + CLEAR_TO_NULL(s -> DesensitizedUtil.clearToNull()); //鍙嚜琛屾坊鍔犲叾浠栬劚鏁忕瓥鐣� diff --git a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java index 04f6214..9191fca 100644 --- a/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java +++ b/ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java @@ -58,9 +58,9 @@ 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 "stack_overflow" -> new AuthStackOverflowRequest(builder.build(), STATE_CACHE); case "huawei" -> new AuthHuaweiRequest(builder.build(), STATE_CACHE); - case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(builder.agentId("").build(), STATE_CACHE); + case "wechat_enterprise" -> new AuthWeChatEnterpriseQrcodeRequest(builder.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); diff --git a/ruoyi-common/ruoyi-common-sse/pom.xml b/ruoyi-common/ruoyi-common-sse/pom.xml new file mode 100644 index 0000000..ae44c98 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/pom.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common</artifactId> + <version>${revision}</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>ruoyi-common-sse</artifactId> + + <description> + ruoyi-common-sse 妯″潡 + </description> + + <dependencies> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-core</artifactId> + </dependency> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-redis</artifactId> + </dependency> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-satoken</artifactId> + </dependency> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-json</artifactId> + </dependency> + </dependencies> +</project> diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseAutoConfiguration.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseAutoConfiguration.java new file mode 100644 index 0000000..0cf8054 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseAutoConfiguration.java @@ -0,0 +1,36 @@ +package org.dromara.common.sse.config; + +import org.dromara.common.sse.controller.SseController; +import org.dromara.common.sse.core.SseEmitterManager; +import org.dromara.common.sse.listener.SseTopicListener; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +/** + * SSE 鑷姩瑁呴厤 + * + * @author Lion Li + */ +@AutoConfiguration +@ConditionalOnProperty(value = "sse.enabled", havingValue = "true") +@EnableConfigurationProperties(SseProperties.class) +public class SseAutoConfiguration { + + @Bean + public SseEmitterManager sseEmitterManager() { + return new SseEmitterManager(); + } + + @Bean + public SseTopicListener sseTopicListener() { + return new SseTopicListener(); + } + + @Bean + public SseController sseController(SseEmitterManager sseEmitterManager) { + return new SseController(sseEmitterManager); + } + +} diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseProperties.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseProperties.java new file mode 100644 index 0000000..ce4e173 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseProperties.java @@ -0,0 +1,21 @@ +package org.dromara.common.sse.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * SSE 閰嶇疆椤� + * + * @author Lion Li + */ +@Data +@ConfigurationProperties("sse") +public class SseProperties { + + private Boolean enabled; + + /** + * 璺緞 + */ + private String path; +} diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/controller/SseController.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/controller/SseController.java new file mode 100644 index 0000000..e5331e4 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/controller/SseController.java @@ -0,0 +1,87 @@ +package org.dromara.common.sse.controller; + +import cn.dev33.satoken.annotation.SaIgnore; +import cn.dev33.satoken.stp.StpUtil; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.domain.R; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.common.sse.core.SseEmitterManager; +import org.dromara.common.sse.dto.SseMessageDto; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.util.List; + +/** + * SSE 鎺у埗鍣� + * + * @author Lion Li + */ +@RestController +@ConditionalOnProperty(value = "sse.enabled", havingValue = "true") +@RequiredArgsConstructor +public class SseController implements DisposableBean { + + private final SseEmitterManager sseEmitterManager; + + /** + * 寤虹珛 SSE 杩炴帴 + */ + @GetMapping(value = "${sse.path}", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public SseEmitter connect() { + String tokenValue = StpUtil.getTokenValue(); + Long userId = LoginHelper.getUserId(); + return sseEmitterManager.connect(userId, tokenValue); + } + + /** + * 鍏抽棴 SSE 杩炴帴 + */ + @SaIgnore + @GetMapping(value = "${sse.path}/close") + public R<Void> close() { + String tokenValue = StpUtil.getTokenValue(); + Long userId = LoginHelper.getUserId(); + sseEmitterManager.disconnect(userId, tokenValue); + return R.ok(); + } + + /** + * 鍚戠壒瀹氱敤鎴峰彂閫佹秷鎭� + * + * @param userId 鐩爣鐢ㄦ埛鐨� ID + * @param msg 瑕佸彂閫佺殑娑堟伅鍐呭 + */ + @GetMapping(value = "${sse.path}/send") + public R<Void> send(Long userId, String msg) { + SseMessageDto dto = new SseMessageDto(); + dto.setUserIds(List.of(userId)); + dto.setMessage(msg); + sseEmitterManager.publishMessage(dto); + return R.ok(); + } + + /** + * 鍚戞墍鏈夌敤鎴峰彂閫佹秷鎭� + * + * @param msg 瑕佸彂閫佺殑娑堟伅鍐呭 + */ + @GetMapping(value = "${sse.path}/sendAll") + public R<Void> send(String msg) { + sseEmitterManager.publishAll(msg); + return R.ok(); + } + + /** + * 娓呯悊璧勬簮銆傛鏂规硶鐩墠涓嶆墽琛屼换浣曟搷浣滐紝浣嗛伩鍏嶅洜鏈疄鐜拌�屽鑷撮敊璇� + */ + @Override + public void destroy() throws Exception { + // 閿�姣佹椂涓嶉渶瑕佸仛浠�涔� 姝ゆ柟娉曢伩鍏嶆棤鐢ㄦ搷浣滄姤閿� + } + +} diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java new file mode 100644 index 0000000..1d37a27 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java @@ -0,0 +1,160 @@ +package org.dromara.common.sse.core; + +import cn.hutool.core.collection.CollUtil; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.redis.utils.RedisUtils; +import org.dromara.common.sse.dto.SseMessageDto; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; + +/** + * 绠$悊 Server-Sent Events (SSE) 杩炴帴 + * + * @author Lion Li + */ +@Slf4j +public class SseEmitterManager { + + /** + * 璁㈤槄鐨勯閬� + */ + private final static String SSE_TOPIC = "global:sse"; + + private final static Map<Long, Map<String, SseEmitter>> USER_TOKEN_EMITTERS = new ConcurrentHashMap<>(); + + /** + * 寤虹珛涓庢寚瀹氱敤鎴风殑 SSE 杩炴帴 + * + * @param userId 鐢ㄦ埛鐨勫敮涓�鏍囪瘑绗︼紝鐢ㄤ簬鍖哄垎涓嶅悓鐢ㄦ埛鐨勮繛鎺� + * @param token 鐢ㄦ埛鐨勫敮涓�浠ょ墝锛岀敤浜庤瘑鍒叿浣撶殑杩炴帴 + * @return 杩斿洖涓�涓� SseEmitter 瀹炰緥锛屽鎴风鍙互閫氳繃璇ュ疄渚嬫帴鏀� SSE 浜嬩欢 + */ + public SseEmitter connect(Long userId, String token) { + // 浠� USER_TOKEN_EMITTERS 涓幏鍙栨垨鍒涘缓褰撳墠鐢ㄦ埛鐨� SseEmitter 鏄犲皠琛紙ConcurrentHashMap锛� + // 姣忎釜鐢ㄦ埛鍙互鏈夊涓� SSE 杩炴帴锛岄�氳繃 token 杩涜鍖哄垎 + Map<String, SseEmitter> emitters = USER_TOKEN_EMITTERS.computeIfAbsent(userId, k -> new ConcurrentHashMap<>()); + + // 鍒涘缓涓�涓柊鐨� SseEmitter 瀹炰緥锛岃秴鏃舵椂闂磋缃负 0 琛ㄧず鏃犻檺鍒� + SseEmitter emitter = new SseEmitter(0L); + + emitters.put(token, emitter); + + // 褰� emitter 瀹屾垚銆佽秴鏃舵垨鍙戠敓閿欒鏃讹紝浠庢槧灏勮〃涓Щ闄ゅ搴旂殑 token + emitter.onCompletion(() -> emitters.remove(token)); + emitter.onTimeout(() -> emitters.remove(token)); + emitter.onError((e) -> emitters.remove(token)); + + try { + // 鍚戝鎴风鍙戦�佷竴鏉¤繛鎺ユ垚鍔熺殑浜嬩欢 + emitter.send(SseEmitter.event().comment("connected")); + } catch (IOException e) { + // 濡傛灉鍙戦�佹秷鎭け璐ワ紝鍒欎粠鏄犲皠琛ㄤ腑绉婚櫎 emitter + emitters.remove(token); + } + return emitter; + } + + /** + * 鏂紑鎸囧畾鐢ㄦ埛鐨� SSE 杩炴帴 + * + * @param userId 鐢ㄦ埛鐨勫敮涓�鏍囪瘑绗︼紝鐢ㄤ簬鍖哄垎涓嶅悓鐢ㄦ埛鐨勮繛鎺� + * @param token 鐢ㄦ埛鐨勫敮涓�浠ょ墝锛岀敤浜庤瘑鍒叿浣撶殑杩炴帴 + */ + public void disconnect(Long userId, String token) { + Map<String, SseEmitter> emitters = USER_TOKEN_EMITTERS.get(userId); + if (emitters != null) { + try { + emitters.get(token).send(SseEmitter.event().comment("disconnected")); + } catch (Exception ignore) { + } + emitters.remove(token); + } + } + + /** + * 璁㈤槄SSE娑堟伅涓婚锛屽苟鎻愪緵涓�涓秷璐硅�呭嚱鏁版潵澶勭悊鎺ユ敹鍒扮殑娑堟伅 + * + * @param consumer 澶勭悊SSE娑堟伅鐨勬秷璐硅�呭嚱鏁� + */ + public void subscribeMessage(Consumer<SseMessageDto> consumer) { + RedisUtils.subscribe(SSE_TOPIC, SseMessageDto.class, consumer); + } + + /** + * 鍚戞寚瀹氱殑鐢ㄦ埛浼氳瘽鍙戦�佹秷鎭� + * + * @param userId 瑕佸彂閫佹秷鎭殑鐢ㄦ埛id + * @param message 瑕佸彂閫佺殑娑堟伅鍐呭 + */ + public void sendMessage(Long userId, String message) { + Map<String, SseEmitter> emitters = USER_TOKEN_EMITTERS.get(userId); + if (emitters != null) { + for (Map.Entry<String, SseEmitter> entry : emitters.entrySet()) { + try { + entry.getValue().send(SseEmitter.event() + .name("message") + .data(message)); + } catch (Exception e) { + emitters.remove(entry.getKey()); + } + } + } + } + + /** + * 鏈満鍏ㄧ敤鎴蜂細璇濆彂閫佹秷鎭� + * + * @param message 瑕佸彂閫佺殑娑堟伅鍐呭 + */ + public void sendMessage(String message) { + for (Long userId : USER_TOKEN_EMITTERS.keySet()) { + sendMessage(userId, message); + } + } + + /** + * 鍙戝竷SSE璁㈤槄娑堟伅 + * + * @param sseMessageDto 瑕佸彂甯冪殑SSE娑堟伅瀵硅薄 + */ + public void publishMessage(SseMessageDto sseMessageDto) { + List<Long> unsentUserIds = new ArrayList<>(); + // 褰撳墠鏈嶅姟鍐呯敤鎴�,鐩存帴鍙戦�佹秷鎭� + for (Long userId : sseMessageDto.getUserIds()) { + if (USER_TOKEN_EMITTERS.containsKey(userId)) { + sendMessage(userId, sseMessageDto.getMessage()); + continue; + } + unsentUserIds.add(userId); + } + // 涓嶅湪褰撳墠鏈嶅姟鍐呯敤鎴�,鍙戝竷璁㈤槄娑堟伅 + if (CollUtil.isNotEmpty(unsentUserIds)) { + SseMessageDto broadcastMessage = new SseMessageDto(); + broadcastMessage.setMessage(sseMessageDto.getMessage()); + broadcastMessage.setUserIds(unsentUserIds); + RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> { + log.info("SSE鍙戦�佷富棰樿闃呮秷鎭痶opic:{} session keys:{} message:{}", + SSE_TOPIC, unsentUserIds, sseMessageDto.getMessage()); + }); + } + } + + /** + * 鍚戞墍鏈夌殑鐢ㄦ埛鍙戝竷璁㈤槄鐨勬秷鎭�(缇ゅ彂) + * + * @param message 瑕佸彂甯冪殑娑堟伅鍐呭 + */ + public void publishAll(String message) { + SseMessageDto broadcastMessage = new SseMessageDto(); + broadcastMessage.setMessage(message); + RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> { + log.info("SSE鍙戦�佷富棰樿闃呮秷鎭痶opic:{} message:{}", SSE_TOPIC, message); + }); + } +} diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/dto/SseMessageDto.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/dto/SseMessageDto.java new file mode 100644 index 0000000..a2e1210 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/dto/SseMessageDto.java @@ -0,0 +1,29 @@ +package org.dromara.common.sse.dto; + +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.List; + +/** + * 娑堟伅鐨刣to + * + * @author zendwang + */ +@Data +public class SseMessageDto implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 闇�瑕佹帹閫佸埌鐨剆ession key 鍒楄〃 + */ + private List<Long> userIds; + + /** + * 闇�瑕佸彂閫佺殑娑堟伅 + */ + private String message; +} diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/listener/SseTopicListener.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/listener/SseTopicListener.java new file mode 100644 index 0000000..7a4dff1 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/listener/SseTopicListener.java @@ -0,0 +1,48 @@ +package org.dromara.common.sse.listener; + +import cn.hutool.core.collection.CollUtil; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.sse.core.SseEmitterManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.core.Ordered; + +/** + * SSE 涓婚璁㈤槄鐩戝惉鍣� + * + * @author Lion Li + */ +@Slf4j +public class SseTopicListener implements ApplicationRunner, Ordered { + + @Autowired + private SseEmitterManager sseEmitterManager; + + /** + * 鍦⊿pring Boot搴旂敤绋嬪簭鍚姩鏃跺垵濮嬪寲SSE涓婚璁㈤槄鐩戝惉鍣� + * + * @param args 搴旂敤绋嬪簭鍙傛暟 + * @throws Exception 鍒濆鍖栬繃绋嬩腑鍙兘鎶涘嚭鐨勫紓甯� + */ + @Override + public void run(ApplicationArguments args) throws Exception { + sseEmitterManager.subscribeMessage((message) -> { + log.info("SSE涓婚璁㈤槄鏀跺埌娑堟伅session keys={} message={}", message.getUserIds(), message.getMessage()); + // 濡傛灉key涓嶄负绌哄氨鎸夌収key鍙戞秷鎭� 濡傛灉涓虹┖灏辩兢鍙� + if (CollUtil.isNotEmpty(message.getUserIds())) { + message.getUserIds().forEach(key -> { + sseEmitterManager.sendMessage(key, message.getMessage()); + }); + } else { + sseEmitterManager.sendMessage(message.getMessage()); + } + }); + log.info("鍒濆鍖朣SE涓婚璁㈤槄鐩戝惉鍣ㄦ垚鍔�"); + } + + @Override + public int getOrder() { + return -1; + } +} diff --git a/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/utils/SseMessageUtils.java b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/utils/SseMessageUtils.java new file mode 100644 index 0000000..c6abdc8 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/utils/SseMessageUtils.java @@ -0,0 +1,58 @@ +package org.dromara.common.sse.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.common.sse.core.SseEmitterManager; +import org.dromara.common.sse.dto.SseMessageDto; + +/** + * SSE宸ュ叿绫� + * + * @author Lion Li + */ +@Slf4j +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class SseMessageUtils { + + private final static SseEmitterManager MANAGER = SpringUtils.getBean(SseEmitterManager.class); + + /** + * 鍚戞寚瀹氱殑WebSocket浼氳瘽鍙戦�佹秷鎭� + * + * @param userId 瑕佸彂閫佹秷鎭殑鐢ㄦ埛id + * @param message 瑕佸彂閫佺殑娑堟伅鍐呭 + */ + public static void sendMessage(Long userId, String message) { + MANAGER.sendMessage(userId, message); + } + + /** + * 鏈満鍏ㄧ敤鎴蜂細璇濆彂閫佹秷鎭� + * + * @param message 瑕佸彂閫佺殑娑堟伅鍐呭 + */ + public static void sendMessage(String message) { + MANAGER.sendMessage(message); + } + + /** + * 鍙戝竷SSE璁㈤槄娑堟伅 + * + * @param sseMessageDto 瑕佸彂甯冪殑SSE娑堟伅瀵硅薄 + */ + public static void publishMessage(SseMessageDto sseMessageDto) { + MANAGER.publishMessage(sseMessageDto); + } + + /** + * 鍚戞墍鏈夌殑鐢ㄦ埛鍙戝竷璁㈤槄鐨勬秷鎭�(缇ゅ彂) + * + * @param message 瑕佸彂甯冪殑娑堟伅鍐呭 + */ + public static void publishAll(String message) { + MANAGER.publishAll(message); + } + +} diff --git a/ruoyi-common/ruoyi-common-sse/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/ruoyi-common/ruoyi-common-sse/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..b809713 --- /dev/null +++ b/ruoyi-common/ruoyi-common-sse/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.dromara.common.sse.config.SseAutoConfiguration diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java index 9d087e1..b185612 100644 --- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java @@ -1,8 +1,9 @@ package org.dromara.common.tenant.helper; import cn.dev33.satoken.stp.StpUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; -import com.alibaba.ttl.TransmittableThreadLocal; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import lombok.AccessLevel; @@ -11,9 +12,11 @@ import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.core.utils.reflect.ReflectUtils; import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; +import java.util.Stack; import java.util.function.Supplier; /** @@ -27,7 +30,9 @@ private static final String DYNAMIC_TENANT_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "dynamicTenant"; - private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>(); + private static final ThreadLocal<String> TEMP_DYNAMIC_TENANT = new ThreadLocal<>(); + + private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new); /** * 绉熸埛鍔熻兘鏄惁鍚敤 @@ -36,18 +41,49 @@ return Convert.toBool(SpringUtils.getProperty("tenant.enable"), false); } + private static IgnoreStrategy getIgnoreStrategy() { + Object ignoreStrategyLocal = ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL")); + if (ignoreStrategyLocal instanceof ThreadLocal<?> IGNORE_STRATEGY_LOCAL) { + if (IGNORE_STRATEGY_LOCAL.get() instanceof IgnoreStrategy ignoreStrategy) { + return ignoreStrategy; + } + } + return null; + } + /** * 寮�鍚拷鐣ョ鎴�(寮�鍚悗闇�鎵嬪姩璋冪敤 {@link #disableIgnore()} 鍏抽棴) */ public static void enableIgnore() { - InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build()); + IgnoreStrategy ignoreStrategy = getIgnoreStrategy(); + if (ObjectUtil.isNull(ignoreStrategy)) { + InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().tenantLine(true).build()); + } else { + ignoreStrategy.setTenantLine(true); + } + Stack<Integer> reentrantStack = REENTRANT_IGNORE.get(); + reentrantStack.push(reentrantStack.size() + 1); } /** * 鍏抽棴蹇界暐绉熸埛 */ public static void disableIgnore() { - InterceptorIgnoreHelper.clearIgnoreStrategy(); + IgnoreStrategy ignoreStrategy = getIgnoreStrategy(); + if (ObjectUtil.isNotNull(ignoreStrategy)) { + boolean noOtherIgnoreStrategy = !Boolean.TRUE.equals(ignoreStrategy.getDynamicTableName()) + && !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack()) + && !Boolean.TRUE.equals(ignoreStrategy.getIllegalSql()) + && !Boolean.TRUE.equals(ignoreStrategy.getDataPermission()) + && CollectionUtil.isEmpty(ignoreStrategy.getOthers()); + Stack<Integer> reentrantStack = REENTRANT_IGNORE.get(); + boolean empty = reentrantStack.isEmpty() || reentrantStack.pop() == 1; + if (noOtherIgnoreStrategy && empty) { + InterceptorIgnoreHelper.clearIgnoreStrategy(); + } else if (empty) { + ignoreStrategy.setTenantLine(false); + } + } } /** diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java index d230afc..346e36f 100644 --- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/manager/TenantSpringCacheManager.java @@ -1,5 +1,7 @@ package org.dromara.common.tenant.manager; +import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; +import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.redis.manager.PlusSpringCacheManager; @@ -11,6 +13,7 @@ * * @author Lion Li */ +@Slf4j public class TenantSpringCacheManager extends PlusSpringCacheManager { public TenantSpringCacheManager() { @@ -18,10 +21,16 @@ @Override public Cache getCache(String name) { + if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) { + return super.getCache(name); + } if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) { return super.getCache(name); } String tenantId = TenantHelper.getTenantId(); + if (StringUtils.isBlank(tenantId)) { + log.error("鏃犳硶鑾峰彇鏈夋晥鐨勭鎴穒d -> Null"); + } if (StringUtils.startsWith(name, tenantId)) { // 濡傛灉瀛樺湪鍒欑洿鎺ヨ繑鍥� return super.getCache(name); diff --git a/ruoyi-common/ruoyi-common-web/pom.xml b/ruoyi-common/ruoyi-common-web/pom.xml index b250fa9..5e366bc 100644 --- a/ruoyi-common/ruoyi-common-web/pom.xml +++ b/ruoyi-common/ruoyi-common-web/pom.xml @@ -44,6 +44,19 @@ </dependency> <dependency> + <groupId>io.undertow</groupId> + <artifactId>undertow-core</artifactId> + </dependency> + <dependency> + <groupId>io.undertow</groupId> + <artifactId>undertow-servlet</artifactId> + </dependency> + <dependency> + <groupId>io.undertow</groupId> + <artifactId>undertow-websockets-jsr</artifactId> + </dependency> + + <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java index bd47c18..061d3aa 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java @@ -16,9 +16,12 @@ import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MissingPathVariableException; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.servlet.NoHandlerFoundException; + +import java.io.IOException; /** * 鍏ㄥ眬寮傚父澶勭悊鍣� @@ -92,6 +95,20 @@ /** * 鎷︽埅鏈煡鐨勮繍琛屾椂寮傚父 */ + @ResponseStatus(org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR) + @ExceptionHandler(IOException.class) + public void handleRuntimeException(IOException e, HttpServletRequest request) { + String requestURI = request.getRequestURI(); + if (requestURI.contains("sse")) { + // sse 缁忓父鎬ц繛鎺ヤ腑鏂� 渚嬪鍏抽棴娴忚鍣� 鐩存帴灞忚斀 + return; + } + log.error("璇锋眰鍦板潃'{}',杩炴帴涓柇", requestURI, e); + } + + /** + * 鎷︽埅鏈煡鐨勮繍琛屾椂寮傚父 + */ @ExceptionHandler(RuntimeException.class) public R<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) { String requestURI = request.getRequestURI(); diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java index 12c8086..614a559 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java @@ -6,7 +6,6 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.time.StopWatch; -import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.json.utils.JsonUtils; import org.dromara.common.web.filter.RepeatedlyRequestWrapper; @@ -19,7 +18,6 @@ /** * web鐨勮皟鐢ㄦ椂闂寸粺璁℃嫤鎴櫒 - * dev鐜鏈夋晥 * * @author Lion Li * @since 3.3.0 @@ -27,37 +25,34 @@ @Slf4j public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { - private final String prodProfile = "prod"; - private final static ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - if (!prodProfile.equals(SpringUtils.getActiveProfile())) { - String url = request.getMethod() + " " + request.getRequestURI(); + String url = request.getMethod() + " " + request.getRequestURI(); - // 鎵撳嵃璇锋眰鍙傛暟 - if (isJsonRequest(request)) { - String jsonParam = ""; - if (request instanceof RepeatedlyRequestWrapper) { - BufferedReader reader = request.getReader(); - jsonParam = IoUtil.read(reader); - } - log.info("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[json],鍙傛暟:[{}]", url, jsonParam); - } else { - Map<String, String[]> parameterMap = request.getParameterMap(); - if (MapUtil.isNotEmpty(parameterMap)) { - String parameters = JsonUtils.toJsonString(parameterMap); - log.info("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[param],鍙傛暟:[{}]", url, parameters); - } else { - log.info("[PLUS]寮�濮嬭姹� => URL[{}],鏃犲弬鏁�", url); - } + // 鎵撳嵃璇锋眰鍙傛暟 + if (isJsonRequest(request)) { + String jsonParam = ""; + if (request instanceof RepeatedlyRequestWrapper) { + BufferedReader reader = request.getReader(); + jsonParam = IoUtil.read(reader); } - - StopWatch stopWatch = new StopWatch(); - KEY_CACHE.set(stopWatch); - stopWatch.start(); + log.info("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[json],鍙傛暟:[{}]", url, jsonParam); + } else { + Map<String, String[]> parameterMap = request.getParameterMap(); + if (MapUtil.isNotEmpty(parameterMap)) { + String parameters = JsonUtils.toJsonString(parameterMap); + log.info("[PLUS]寮�濮嬭姹� => URL[{}],鍙傛暟绫诲瀷[param],鍙傛暟:[{}]", url, parameters); + } else { + log.info("[PLUS]寮�濮嬭姹� => URL[{}],鏃犲弬鏁�", url); + } } + + StopWatch stopWatch = new StopWatch(); + KEY_CACHE.set(stopWatch); + stopWatch.start(); + return true; } @@ -68,12 +63,10 @@ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { - if (!prodProfile.equals(SpringUtils.getActiveProfile())) { - StopWatch stopWatch = KEY_CACHE.get(); - stopWatch.stop(); - log.info("[PLUS]缁撴潫璇锋眰 => URL[{}],鑰楁椂:[{}]姣", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime()); - KEY_CACHE.remove(); - } + StopWatch stopWatch = KEY_CACHE.get(); + stopWatch.stop(); + log.info("[PLUS]缁撴潫璇锋眰 => URL[{}],鑰楁椂:[{}]姣", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime()); + KEY_CACHE.remove(); } /** diff --git a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java index afe76e0..8c4170a 100644 --- a/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java +++ b/ruoyi-common/ruoyi-common-websocket/src/main/java/org/dromara/common/websocket/utils/WebSocketUtils.java @@ -113,7 +113,7 @@ * @param session WebSocket浼氳瘽 * @param message 瑕佸彂閫佺殑WebSocket娑堟伅瀵硅薄 */ - private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) { + private synchronized static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) { if (session == null || !session.isOpen()) { log.warn("[send] session浼氳瘽宸茬粡鍏抽棴"); } else { diff --git a/ruoyi-extend/ruoyi-monitor-admin/pom.xml b/ruoyi-extend/ruoyi-monitor-admin/pom.xml index 91194c6..77c9eb7 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/pom.xml +++ b/ruoyi-extend/ruoyi-monitor-admin/pom.xml @@ -12,10 +12,21 @@ <artifactId>ruoyi-monitor-admin</artifactId> <dependencies> - <!-- SpringWeb妯″潡 --> + <!-- SpringBoot Web瀹瑰櫒 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> + <exclusions> + <exclusion> + <artifactId>spring-boot-starter-tomcat</artifactId> + <groupId>org.springframework.boot</groupId> + </exclusion> + </exclusions> + </dependency> + <!-- web 瀹瑰櫒浣跨敤 undertow 鎬ц兘鏇村己 --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <!-- spring security 瀹夊叏璁よ瘉 --> diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java index 3f5dec8..3458cc9 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/config/SecurityConfig.java @@ -39,9 +39,7 @@ .authorizeHttpRequests((authorize) -> authorize.requestMatchers( new AntPathRequestMatcher(adminContextPath + "/assets/**"), - new AntPathRequestMatcher(adminContextPath + "/login"), - new AntPathRequestMatcher("/actuator"), - new AntPathRequestMatcher("/actuator/**") + new AntPathRequestMatcher(adminContextPath + "/login") ).permitAll() .anyRequest().authenticated()) .formLogin((formLogin) -> diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java index 477a598..838eefc 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/java/org/dromara/monitor/admin/notifier/CustomNotifier.java @@ -9,6 +9,8 @@ import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; +import static de.codecentric.boot.admin.server.domain.values.StatusInfo.*; + /** * 鑷畾涔変簨浠堕�氱煡澶勭悊 * @@ -28,13 +30,26 @@ return Mono.fromRunnable(() -> { // 瀹炰緥鐘舵�佹敼鍙樹簨浠� if (event instanceof InstanceStatusChangedEvent) { + // 鑾峰彇瀹炰緥娉ㄥ唽鍚嶇О String registName = instance.getRegistration().getName(); + // 鑾峰彇瀹炰緥ID String instanceId = event.getInstance().getValue(); + // 鑾峰彇瀹炰緥鐘舵�� String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus(); - log.info("Instance Status Change: [{}],[{}],[{}]", registName, instanceId, status); + // 鑾峰彇鏈嶅姟URL + String serviceUrl = instance.getRegistration().getServiceUrl(); + String statusName = switch (status) { + case STATUS_UP -> "鏈嶅姟涓婄嚎"; // 瀹炰緥鎴愬姛鍚姩骞跺彲浠ユ甯稿鐞嗚姹� + case STATUS_OFFLINE -> "鏈嶅姟绂荤嚎"; //瀹炰緥琚墜鍔ㄦ垨鑷姩鍦颁粠鏈嶅姟涓Щ闄� + case STATUS_RESTRICTED -> "鏈嶅姟鍙楅檺"; //琛ㄧず瀹炰緥鍦ㄦ煇浜涙柟闈㈠彈闄愶紝鍙兘鏃犳硶瀹屽叏鎻愪緵鎵�鏈夋湇鍔� + case STATUS_OUT_OF_SERVICE -> "鍋滄鏈嶅姟鐘舵��"; //琛ㄧず瀹炰緥宸茶鏍囪涓哄仠姝㈡彁渚涙湇鍔★紝鍙兘鏄鍒掑唴缁存姢鎴栨祴璇� + case STATUS_DOWN -> "鏈嶅姟涓嬬嚎"; //瀹炰緥鍥犲穿婧冦�侀敊璇垨鍏朵粬鍘熷洜鍋滄杩愯 + case STATUS_UNKNOWN -> "鏈嶅姟鏈煡寮傚父"; //鐩戞帶绯荤粺鏃犳硶纭畾瀹炰緥鐨勫綋鍓嶇姸鎬� + default -> "鏈煡鐘舵��"; //娌℃湁鍖归厤鐨勭姸鎬� + }; + log.info("Instance Status Change: 鐘舵�佸悕绉般�恵}銆�, 娉ㄥ唽鍚嶇О銆恵}銆�, 瀹炰緥ID銆恵}銆�, 鐘舵�併�恵}銆�, 鏈嶅姟URL銆恵}銆�", + statusName, registName, instanceId, status, serviceUrl); } - }); } - } diff --git a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml index 1b729ef..beee587 100644 --- a/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml +++ b/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml @@ -41,5 +41,8 @@ url: http://localhost:9090/admin instance: service-host-type: IP + metadata: + username: ${spring.boot.admin.client.username} + userpassword: ${spring.boot.admin.client.password} username: ruoyi password: 123456 diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/ActuatorAuthFilter.java b/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/ActuatorAuthFilter.java new file mode 100644 index 0000000..e3a6892 --- /dev/null +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/ActuatorAuthFilter.java @@ -0,0 +1,64 @@ +package com.aizuda.snailjob.server.starter.filter; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public class ActuatorAuthFilter implements Filter { + + private final String username; + private final String password; + + public ActuatorAuthFilter(String username, String password) { + this.username = username; + this.password = password; + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + // 鑾峰彇 Authorization 澶� + String authHeader = request.getHeader("Authorization"); + + if (authHeader == null || !authHeader.startsWith("Basic ")) { + // 濡傛灉娌℃湁鎻愪緵 Authorization 鎴栬�呮牸寮忎笉瀵癸紝鍒欒繑鍥� 401 + response.setHeader("WWW-Authenticate", "Basic realm=\"realm\""); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + return; + } + + // 瑙g爜 Base64 缂栫爜鐨勭敤鎴峰悕鍜屽瘑鐮� + String base64Credentials = authHeader.substring("Basic ".length()); + byte[] credDecoded = Base64.getDecoder().decode(base64Credentials); + String credentials = new String(credDecoded, StandardCharsets.UTF_8); + String[] split = credentials.split(":"); + if (split.length != 2) { + response.setHeader("WWW-Authenticate", "Basic realm=\"realm\""); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + return; + } + // 楠岃瘉鐢ㄦ埛鍚嶅拰瀵嗙爜 + if (!username.equals(split[0]) && password.equals(split[1])) { + response.setHeader("WWW-Authenticate", "Basic realm=\"realm\""); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); + return; + } + // 濡傛灉璁よ瘉鎴愬姛锛岀户缁鐞嗚姹� + filterChain.doFilter(request, response); + } + + @Override + public void init(FilterConfig filterConfig) { + } + + @Override + public void destroy() { + } + +} diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/SecurityConfig.java b/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/SecurityConfig.java new file mode 100644 index 0000000..3cae8f5 --- /dev/null +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/java/com/aizuda/snailjob/server/starter/filter/SecurityConfig.java @@ -0,0 +1,29 @@ +package com.aizuda.snailjob.server.starter.filter; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 鏉冮檺瀹夊叏閰嶇疆 + * + * @author Lion Li + */ +@Configuration +public class SecurityConfig { + + @Value("${spring.boot.admin.client.username}") + private String username; + @Value("${spring.boot.admin.client.password}") + private String password; + + @Bean + public FilterRegistrationBean<ActuatorAuthFilter> actuatorFilterRegistrationBean() { + FilterRegistrationBean<ActuatorAuthFilter> registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new ActuatorAuthFilter(username, password)); + registrationBean.addUrlPatterns("/actuator", "/actuator/**"); + return registrationBean; + } + +} diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml index 3c65077..cbe40be 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml @@ -43,5 +43,8 @@ url: http://localhost:9090/admin instance: service-host-type: IP + metadata: + username: ${spring.boot.admin.client.username} + userpassword: ${spring.boot.admin.client.password} username: ruoyi password: 123456 diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml index 37ab887..3ba983c 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml @@ -43,5 +43,8 @@ url: http://localhost:9090/admin instance: service-host-type: IP + metadata: + username: ${spring.boot.admin.client.username} + userpassword: ${spring.boot.admin.client.password} username: ruoyi password: 123456 diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java index bd94b1c..6aeeb50 100644 --- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java +++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/mapper/TestDemoMapper.java @@ -4,14 +4,14 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import org.apache.poi.ss.formula.functions.T; +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.demo.domain.TestDemo; import org.dromara.demo.domain.vo.TestDemoVo; -import org.apache.ibatis.annotations.Param; +import java.io.Serializable; import java.util.Collection; import java.util.List; @@ -44,16 +44,17 @@ List<TestDemo> selectList(@Param(Constants.WRAPPER) Wrapper<TestDemo> queryWrapper); @Override - @DataPermission({ + @DataPermission(value = { @DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "userName", value = "user_id") - }) - int updateById(@Param(Constants.ENTITY) TestDemo entity); + }, joinStr = "AND") + List<TestDemo> selectBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList); @Override @DataPermission({ @DataColumn(key = "deptName", value = "dept_id"), @DataColumn(key = "userName", value = "user_id") }) - int deleteByIds(@Param(Constants.COLL) Collection<?> idList); + int updateById(@Param(Constants.ENTITY) TestDemo entity); + } diff --git a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java index 86b39c2..3cfde3a 100644 --- a/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java +++ b/ruoyi-modules/ruoyi-demo/src/main/java/org/dromara/demo/service/impl/TestDemoServiceImpl.java @@ -3,6 +3,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; @@ -12,7 +14,6 @@ import org.dromara.demo.domain.vo.TestDemoVo; import org.dromara.demo.mapper.TestDemoMapper; import org.dromara.demo.service.ITestDemoService; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.Collection; @@ -99,7 +100,11 @@ @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if (isValid) { - //TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠� + // 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠� + List<TestDemo> list = baseMapper.selectBatchIds(ids); + if (list.size() != ids.size()) { + throw new ServiceException("鎮ㄦ病鏈夊垹闄ゆ潈闄�!"); + } } return baseMapper.deleteByIds(ids) > 0; } diff --git a/ruoyi-modules/ruoyi-generator/pom.xml b/ruoyi-modules/ruoyi-generator/pom.xml index de34f69..b7fd94f 100644 --- a/ruoyi-modules/ruoyi-generator/pom.xml +++ b/ruoyi-modules/ruoyi-generator/pom.xml @@ -47,6 +47,38 @@ <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> </dependency> + + <dependency> + <groupId>org.anyline</groupId> + <artifactId>anyline-environment-spring-data-jdbc</artifactId> + <version>${anyline.version}</version> + </dependency> + + <dependency> + <groupId>org.anyline</groupId> + <artifactId>anyline-data-jdbc-mysql</artifactId> + <version>${anyline.version}</version> + </dependency> + + <!-- anyline鏀寔100+绉嶇被鍨嬫暟鎹簱 娣诲姞瀵瑰簲鐨刯dbc渚濊禆涓巃nyline瀵瑰簲鏁版嵁搴撲緷璧栧寘鍗冲彲 --> +<!-- <dependency>--> +<!-- <groupId>org.anyline</groupId>--> +<!-- <artifactId>anyline-data-jdbc-oracle</artifactId>--> +<!-- <version>${anyline.version}</version>--> +<!-- </dependency>--> + +<!-- <dependency>--> +<!-- <groupId>org.anyline</groupId>--> +<!-- <artifactId>anyline-data-jdbc-postgresql</artifactId>--> +<!-- <version>${anyline.version}</version>--> +<!-- </dependency>--> + +<!-- <dependency>--> +<!-- <groupId>org.anyline</groupId>--> +<!-- <artifactId>anyline-data-jdbc-mssql</artifactId>--> +<!-- <version>${anyline.version}</version>--> +<!-- </dependency>--> + </dependencies> </project> diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/MyBatisDataSourceMonitor.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/MyBatisDataSourceMonitor.java new file mode 100644 index 0000000..8c0f352 --- /dev/null +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/config/MyBatisDataSourceMonitor.java @@ -0,0 +1,105 @@ +package org.dromara.generator.config; + +import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; +import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; +import lombok.extern.slf4j.Slf4j; +import org.anyline.data.datasource.DataSourceMonitor; +import org.anyline.data.runtime.DataRuntime; +import org.anyline.util.ConfigTable; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.util.HashMap; +import java.util.Map; + +/** + * anyline 閫傞厤 鍔ㄦ�佹暟鎹簮鏀归�� + * + * @author Lion Li + */ +@Slf4j +@Component +public class MyBatisDataSourceMonitor implements DataSourceMonitor { + + public MyBatisDataSourceMonitor() { + // 璋冩暣鎵ц妯″紡涓鸿嚜瀹氫箟 + ConfigTable.KEEP_ADAPTER = 2; + // 绂佺敤缂撳瓨 + ConfigTable.METADATA_CACHE_SCOPE = 0; + } + + private final Map<String, String> features = new HashMap<>(); + + /** + * 鏁版嵁婧愮壒寰� 鐢ㄦ潵瀹氬噯 adapter 鍖呭惈鏁版嵁搴撴垨JDBC鍗忚鍏抽敭瀛�<br/> + * 涓�鑸細閫氳繃 浜у搧鍚峗url 鍚堟垚 濡傛灉杩斿洖null 涓婂眰鏂规硶浼氶�氳繃driver_浜у搧鍚峗url鍚堟垚 + * + * @param datasource 鏁版嵁婧� + * @return String 杩斿洖null鐢变笂灞傝嚜鍔ㄦ彁鍙� + */ + @Override + public String feature(DataRuntime runtime, Object datasource) { + String feature = null; + if (datasource instanceof JdbcTemplate jdbc) { + DataSource ds = jdbc.getDataSource(); + if (ds instanceof DynamicRoutingDataSource) { + String key = DynamicDataSourceContextHolder.peek(); + feature = features.get(key); + if (null == feature) { + Connection con = null; + try { + con = DataSourceUtils.getConnection(ds); + DatabaseMetaData meta = con.getMetaData(); + String url = meta.getURL(); + feature = meta.getDatabaseProductName().toLowerCase().replace(" ", "") + "_" + url; + features.put(key, feature); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + if (null != con && !DataSourceUtils.isConnectionTransactional(con, ds)) { + DataSourceUtils.releaseConnection(con, ds); + } + } + } + } + } + return feature; + } + + /** + * 鏁版嵁婧愬敮涓�鏍囪瘑 濡傛灉涓嶅疄鐜板垯榛樿feature + * @param datasource 鏁版嵁婧� + * @return String 杩斿洖null鐢变笂灞傝嚜鍔ㄦ彁鍙� + */ + @Override + public String key(DataRuntime runtime, Object datasource) { + if(datasource instanceof JdbcTemplate jdbc){ + DataSource ds = jdbc.getDataSource(); + if(ds instanceof DynamicRoutingDataSource){ + return DynamicDataSourceContextHolder.peek(); + } + } + return runtime.getKey(); + } + + /** + * ConfigTable.KEEP_ADAPTER=2 : 鏍规嵁褰撳墠鎺ュ彛鍒ゆ柇鏄惁淇濇寔鍚屼竴涓暟鎹簮缁戝畾鍚屼竴涓猘dapter<br/> + * DynamicRoutingDataSource绫诲瀷鐨勮繑鍥瀎alse,鍥犱负鍚屼竴涓狣ynamicRoutingDataSource鍙兘瀵瑰簲澶氱被鏁版嵁搴�, 濡傛灉椤圭洰涓彧鏈変竴绉嶆暟鎹簱 搴旇鐩存帴杩斿洖true + * + * @param datasource 鏁版嵁婧� + * @return boolean + */ + @Override + public boolean keepAdapter(DataRuntime runtime, Object datasource) { + if (datasource instanceof JdbcTemplate jdbc) { + DataSource ds = jdbc.getDataSource(); + return !(ds instanceof DynamicRoutingDataSource); + } + return true; + } + +} diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java index ebdb993..e1560b4 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/domain/GenTableColumn.java @@ -17,7 +17,6 @@ * * @author Lion Li */ - @Data @EqualsAndHashCode(callSuper = true) @TableName("gen_table_column") diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java index f38d39c..ed8ed20 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableColumnMapper.java @@ -1,12 +1,8 @@ package org.dromara.generator.mapper; -import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.annotation.InterceptorIgnore; -import org.apache.ibatis.annotations.Param; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.generator.domain.GenTableColumn; - -import java.util.List; /** * 涓氬姟瀛楁 鏁版嵁灞� @@ -15,14 +11,5 @@ */ @InterceptorIgnore(dataPermission = "true", tenantLine = "true") public interface GenTableColumnMapper extends BaseMapperPlus<GenTableColumn, GenTableColumn> { - /** - * 鏍规嵁琛ㄥ悕绉版煡璇㈠垪淇℃伅 - * - * @param tableName 琛ㄥ悕绉� - * @param dataName 鏁版嵁婧愬悕绉� - * @return 鍒椾俊鎭� - */ - @DS("#dataName") - List<GenTableColumn> selectDbTableColumnsByName(@Param("tableName") String tableName, String dataName); } diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java index c2ff7b6..63f4c15 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/mapper/GenTableMapper.java @@ -18,22 +18,6 @@ public interface GenTableMapper extends BaseMapperPlus<GenTable, GenTable> { /** - * 鏌ヨ鎹簱鍒楄〃 - * - * @param genTable 鏌ヨ鏉′欢 - * @return 鏁版嵁搴撹〃闆嗗悎 - */ - Page<GenTable> selectPageDbTableList(@Param("page") Page<GenTable> page, @Param("genTable") GenTable genTable); - - /** - * 鏌ヨ鎹簱鍒楄〃 - * - * @param tableNames 琛ㄥ悕绉扮粍 - * @return 鏁版嵁搴撹〃闆嗗悎 - */ - List<GenTable> selectDbTableListByNames(String[] tableNames); - - /** * 鏌ヨ鎵�鏈夎〃淇℃伅 * * @return 琛ㄤ俊鎭泦鍚� diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java index 02a9fa7..99935f7 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/GenTableServiceImpl.java @@ -9,15 +9,20 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; +import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.anyline.metadata.Column; +import org.anyline.metadata.Table; +import org.anyline.proxy.ServiceProxy; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.dromara.common.core.constant.Constants; import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.core.utils.file.FileUtils; @@ -41,11 +46,7 @@ import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -62,6 +63,8 @@ private final GenTableMapper baseMapper; private final GenTableColumnMapper genTableColumnMapper; private final IdentifierGenerator identifierGenerator; + + private static final String[] TABLE_IGNORE = new String[]{"sj_", "act_", "flw_", "gen_"}; /** * 鏌ヨ涓氬姟瀛楁鍒楄〃 @@ -99,7 +102,7 @@ Map<String, Object> params = genTable.getParams(); QueryWrapper<GenTable> wrapper = Wrappers.query(); wrapper - .eq(StringUtils.isNotEmpty(genTable.getDataName()),"data_name", genTable.getDataName()) + .eq(StringUtils.isNotEmpty(genTable.getDataName()), "data_name", genTable.getDataName()) .like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName())) .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment())) .between(params.get("beginTime") != null && params.get("endTime") != null, @@ -107,11 +110,67 @@ return wrapper; } + /** + * 鏌ヨ鏁版嵁搴撳垪琛� + * + * @param genTable 鍖呭惈鏌ヨ鏉′欢鐨凣enTable瀵硅薄 + * @param pageQuery 鍖呭惈鍒嗛〉淇℃伅鐨凱ageQuery瀵硅薄 + * @return 鍖呭惈鍒嗛〉缁撴灉鐨凾ableDataInfo瀵硅薄 + */ @DS("#genTable.dataName") @Override public TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery) { - genTable.getParams().put("genTableNames",baseMapper.selectTableNameList(genTable.getDataName())); - Page<GenTable> page = baseMapper.selectPageDbTableList(pageQuery.build(), genTable); + // 鑾峰彇鏌ヨ鏉′欢 + String tableName = genTable.getTableName(); + String tableComment = genTable.getTableComment(); + + LinkedHashMap<String, Table<?>> tablesMap = ServiceProxy.metadata().tables(); + if (CollUtil.isEmpty(tablesMap)) { + return TableDataInfo.build(); + } + List<String> tableNames = baseMapper.selectTableNameList(genTable.getDataName()); + String[] tableArrays; + if (CollUtil.isNotEmpty(tableNames)) { + tableArrays = tableNames.toArray(new String[0]); + } else { + tableArrays = new String[0]; + } + // 杩囨护骞惰浆鎹㈣〃鏍兼暟鎹� + List<GenTable> tables = tablesMap.values().stream() + .filter(x -> !StringUtils.containsAnyIgnoreCase(x.getName(), TABLE_IGNORE)) + .filter(x -> { + if (CollUtil.isEmpty(tableNames)) { + return true; + } + return !StringUtils.equalsAnyIgnoreCase(x.getName(), tableArrays); + }) + .filter(x -> { + boolean nameMatches = true; + boolean commentMatches = true; + // 杩涜琛ㄥ悕绉扮殑妯$硦鏌ヨ + if (StringUtils.isNotBlank(tableName)) { + nameMatches = StringUtils.containsIgnoreCase(x.getName(), tableName); + } + // 杩涜琛ㄦ弿杩扮殑妯$硦鏌ヨ + if (StringUtils.isNotBlank(tableComment)) { + commentMatches = StringUtils.containsIgnoreCase(x.getComment(), tableComment); + } + // 鍚屾椂鍖归厤鍚嶇О鍜屾弿杩� + return nameMatches && commentMatches; + }) + .map(x -> { + GenTable gen = new GenTable(); + gen.setTableName(x.getName()); + gen.setTableComment(x.getComment()); + gen.setCreateTime(x.getCreateTime()); + gen.setUpdateTime(x.getUpdateTime()); + return gen; + }).toList(); + + IPage<GenTable> page = pageQuery.build(); + page.setTotal(tables.size()); + // 鎵嬪姩鍒嗛〉 set鏁版嵁 + page.setRecords(CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tables)); return TableDataInfo.build(page); } @@ -125,7 +184,29 @@ @DS("#dataName") @Override public List<GenTable> selectDbTableListByNames(String[] tableNames, String dataName) { - return baseMapper.selectDbTableListByNames(tableNames); + Set<String> tableNameSet = new HashSet<>(List.of(tableNames)); + LinkedHashMap<String, Table<?>> tablesMap = ServiceProxy.metadata().tables(); + + if (CollUtil.isEmpty(tablesMap)) { + return new ArrayList<>(); + } + + List<Table<?>> tableList = tablesMap.values().stream() + .filter(x -> !StringUtils.containsAnyIgnoreCase(x.getName(), TABLE_IGNORE)) + .filter(x -> tableNameSet.contains(x.getName())).toList(); + + if (CollUtil.isEmpty(tableList)) { + return new ArrayList<>(); + } + return tableList.stream().map(x -> { + GenTable gen = new GenTable(); + gen.setDataName(dataName); + gen.setTableName(x.getName()); + gen.setTableComment(x.getComment()); + gen.setCreateTime(x.getCreateTime()); + gen.setUpdateTime(x.getUpdateTime()); + return gen; + }).toList(); } /** @@ -187,7 +268,7 @@ int row = baseMapper.insert(table); if (row > 0) { // 淇濆瓨鍒椾俊鎭� - List<GenTableColumn> genTableColumns = genTableColumnMapper.selectDbTableColumnsByName(tableName, dataName); + List<GenTableColumn> genTableColumns = SpringUtils.getAopProxy(this).selectDbTableColumnsByName(tableName, dataName); List<GenTableColumn> saveColumns = new ArrayList<>(); for (GenTableColumn column : genTableColumns) { GenUtils.initColumnField(column, table); @@ -201,6 +282,32 @@ } catch (Exception e) { throw new ServiceException("瀵煎叆澶辫触锛�" + e.getMessage()); } + } + + /** + * 鏍规嵁琛ㄥ悕绉版煡璇㈠垪淇℃伅 + * + * @param tableName 琛ㄥ悕绉� + * @param dataName 鏁版嵁婧愬悕绉� + * @return 鍒椾俊鎭� + */ + @DS("#dataName") + @Override + public List<GenTableColumn> selectDbTableColumnsByName(String tableName, String dataName) { + LinkedHashMap<String, Column> columns = ServiceProxy.metadata().columns(tableName); + List<GenTableColumn> tableColumns = new ArrayList<>(); + columns.forEach((columnName, column) -> { + GenTableColumn tableColumn = new GenTableColumn(); + tableColumn.setIsPk(String.valueOf(column.isPrimaryKey())); + tableColumn.setColumnName(column.getName()); + tableColumn.setColumnComment(column.getComment()); + tableColumn.setColumnType(column.getTypeName().toLowerCase()); + tableColumn.setSort(column.getPosition()); + tableColumn.setIsRequired(column.isNullable() == 0 ? "1" : "0"); + tableColumn.setIsIncrement(column.isAutoIncrement() == -1 ? "0" : "1"); + tableColumns.add(tableColumn); + }); + return tableColumns; } /** @@ -298,7 +405,7 @@ List<GenTableColumn> tableColumns = table.getColumns(); Map<String, GenTableColumn> tableColumnMap = StreamUtils.toIdentityMap(tableColumns, GenTableColumn::getColumnName); - List<GenTableColumn> dbTableColumns = genTableColumnMapper.selectDbTableColumnsByName(table.getTableName(), table.getDataName()); + List<GenTableColumn> dbTableColumns = SpringUtils.getAopProxy(this).selectDbTableColumnsByName(table.getTableName(), table.getDataName()); if (CollUtil.isEmpty(dbTableColumns)) { throw new ServiceException("鍚屾鏁版嵁澶辫触锛屽師琛ㄧ粨鏋勪笉瀛樺湪"); } diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java index 2a2fb82..b2c20c5 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/service/IGenTableService.java @@ -86,6 +86,15 @@ void importGenTable(List<GenTable> tableList, String dataName); /** + * 鏍规嵁琛ㄥ悕绉版煡璇㈠垪淇℃伅 + * + * @param tableName 琛ㄥ悕绉� + * @param dataName 鏁版嵁婧愬悕绉� + * @return 鍒椾俊鎭� + */ + List<GenTableColumn> selectDbTableColumnsByName(String tableName, String dataName); + + /** * 棰勮浠g爜 * * @param tableId 琛ㄧ紪鍙� diff --git a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java index f5db391..6e111e3 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java +++ b/ruoyi-modules/ruoyi-generator/src/main/java/org/dromara/generator/util/VelocityUtils.java @@ -215,6 +215,9 @@ importList.add("com.fasterxml.jackson.annotation.JsonFormat"); } else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) { importList.add("java.math.BigDecimal"); + } else if (!column.isSuperColumn() && "imageUpload".equals(column.getHtmlType())) { + importList.add("org.dromara.common.translation.annotation.Translation"); + importList.add("org.dromara.common.translation.constant.TransConstant"); } } return importList; diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml index 123d51a..fc1c610 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml @@ -7,87 +7,4 @@ <resultMap type="org.dromara.generator.domain.GenTableColumn" id="GenTableColumnResult"> </resultMap> - <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult"> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()"> - select column_name, - (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else '0' end) as is_required, - (case when column_key = 'PRI' then '1' else '0' end) as is_pk, - ordinal_position as sort, - column_comment, - (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, - column_type - from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName}) - order by ordinal_position - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()"> - select lower(temp.column_name) as column_name, - (case when (temp.nullable = 'N' and temp.constraint_type != 'P') then '1' else '0' end) as is_required, - (case when temp.constraint_type = 'P' then '1' else '0' end) as is_pk, - temp.column_id as sort, - temp.comments as column_comment, - (case when temp.constraint_type = 'P' then '1' else '0' end) as is_increment, - lower(temp.data_type) as column_type - from ( - select col.column_id, col.column_name,col.nullable, col.data_type, colc.comments, uc.constraint_type, row_number() - over (partition by col.column_name order by uc.constraint_type desc) as row_flg - from user_tab_columns col - left join user_col_comments colc on colc.table_name = col.table_name and colc.column_name = col.column_name - left join user_cons_columns ucc on ucc.table_name = col.table_name and ucc.column_name = col.column_name - left join user_constraints uc on uc.constraint_name = ucc.constraint_name - where col.table_name = upper(#{tableName}) - ) temp - WHERE temp.row_flg = 1 - ORDER BY temp.column_id - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> - SELECT column_name, is_required, is_pk, sort, column_comment, is_increment, column_type - FROM ( - SELECT c.relname AS table_name, - a.attname AS column_name, - d.description AS column_comment, - CASE WHEN a.attnotnull AND con.conname IS NULL THEN 1 ELSE 0 - END AS is_required, - CASE WHEN con.conname IS NOT NULL THEN 1 ELSE 0 - END AS is_pk, - a.attnum AS sort, - CASE WHEN "position"(pg_get_expr(ad.adbin, ad.adrelid), - ((c.relname::text || '_'::text) || a.attname::text) || '_seq'::text) > 0 THEN 1 ELSE 0 - END AS is_increment, - btrim( - CASE WHEN t.typelem <![CDATA[ <> ]]> 0::oid AND t.typlen = '-1'::integer THEN 'ARRAY'::text ELSE - CASE WHEN t.typtype = 'd'::"char" THEN format_type(t.typbasetype, NULL::integer) - ELSE format_type(a.atttypid, NULL::integer) END - END, '"'::text - ) AS column_type - FROM pg_attribute a - JOIN (pg_class c JOIN pg_namespace n ON c.relnamespace = n.oid) ON a.attrelid = c.oid - LEFT JOIN pg_description d ON d.objoid = c.oid AND a.attnum = d.objsubid - LEFT JOIN pg_constraint con ON con.conrelid = c.oid AND (a.attnum = ANY (con.conkey)) - LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum - LEFT JOIN pg_type t ON a.atttypid = t.oid - WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) - AND a.attnum > 0 - AND n.nspname = 'public'::name - ORDER BY c.relname, a.attnum - ) temp - WHERE table_name = (#{tableName}) - AND column_type <![CDATA[ <> ]]> '-' - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()"> - SELECT - cast(A.NAME as nvarchar) as column_name, - cast(B.NAME as nvarchar) + (case when B.NAME = 'numeric' then '(' + cast(A.prec as nvarchar) + ',' + cast(A.scale as nvarchar) + ')' else '' end) as column_type, - cast(G.[VALUE] as nvarchar) as column_comment, - (SELECT 1 FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE Z WHERE TABLE_NAME = D.NAME and A.NAME = Z.column_name ) as is_pk, - colorder as sort - FROM SYSCOLUMNS A - LEFT JOIN SYSTYPES B ON A.XTYPE = B.XUSERTYPE - INNER JOIN SYSOBJECTS D ON A.ID = D.ID AND D.XTYPE='U' AND D.NAME != 'DTPROPERTIES' - LEFT JOIN SYS.EXTENDED_PROPERTIES G ON A.ID = G.MAJOR_ID AND A.COLID = G.MINOR_ID - LEFT JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID AND F.MINOR_ID = 0 - WHERE D.NAME = #{tableName} - ORDER BY A.COLORDER - </if> - </select> - </mapper> diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml index 901bbf0..78aa852 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml @@ -14,239 +14,25 @@ <id property="columnId" column="column_id"/> </resultMap> - <select id="selectPageDbTableList" resultMap="GenTableResult"> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()"> - select table_name, table_comment, create_time, update_time - from information_schema.tables - where table_schema = (select database()) - AND table_name NOT LIKE 'sj_%' AND table_name NOT LIKE 'gen_%' - AND table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' - <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> - AND table_name NOT IN - <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> - #{item} - </foreach> - </if> - <if test="genTable.tableName != null and genTable.tableName != ''"> - AND lower(table_name) like lower(concat('%', #{genTable.tableName}, '%')) - </if> - <if test="genTable.tableComment != null and genTable.tableComment != ''"> - AND lower(table_comment) like lower(concat('%', #{genTable.tableComment}, '%')) - </if> - order by create_time desc - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()"> - select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time - from user_tables dt, user_tab_comments dtc, user_objects uo - where dt.table_name = dtc.table_name - and dt.table_name = uo.object_name - and uo.object_type = 'TABLE' - AND dt.table_name NOT LIKE 'SJ_%' AND dt.table_name NOT LIKE 'GEN_%' - AND dt.table_name NOT LIKE 'ACT_%' AND dt.table_name NOT LIKE 'FLW_%' - <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> - AND lower(dt.table_name) NOT IN - <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> - #{item} - </foreach> - </if> - <if test="genTable.tableName != null and genTable.tableName != ''"> - AND lower(dt.table_name) like lower(concat(concat('%', #{genTable.tableName}), '%')) - </if> - <if test="genTable.tableComment != null and genTable.tableComment != ''"> - AND lower(dtc.comments) like lower(concat(concat('%', #{genTable.tableComment}), '%')) - </if> - order by create_time desc - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> - select table_name, table_comment, create_time, update_time - from ( - SELECT c.relname AS table_name, - obj_description(c.oid) AS table_comment, - CURRENT_TIMESTAMP AS create_time, - CURRENT_TIMESTAMP AS update_time - FROM pg_class c - LEFT JOIN pg_namespace n ON n.oid = c.relnamespace - WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) - AND c.relname != 'spatial_%'::text - AND n.nspname = 'public'::name - AND n.nspname <![CDATA[ <> ]]> ''::name - ) list_table - where table_name NOT LIKE 'sj_%' AND table_name NOT LIKE 'gen_%' - AND table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' - <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> - AND table_name NOT IN - <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> - #{item} - </foreach> - </if> - <if test="genTable.tableName != null and genTable.tableName != ''"> - AND lower(table_name) like lower(concat('%', #{genTable.tableName}, '%')) - </if> - <if test="genTable.tableComment != null and genTable.tableComment != ''"> - AND lower(table_comment) like lower(concat('%', #{genTable.tableComment}, '%')) - </if> - order by create_time desc - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()"> - SELECT cast(D.NAME as nvarchar) as table_name, - cast(F.VALUE as nvarchar) as table_comment, - crdate as create_time, - refdate as update_time - FROM SYSOBJECTS D - INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID - AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' - AND D.NAME NOT LIKE 'sj_%' AND D.NAME NOT LIKE 'gen_%' - AND D.NAME NOT LIKE 'act_%' AND D.NAME NOT LIKE 'flw_%' - <if test="genTable.params.genTableNames != null and genTable.params.genTableNames.size > 0"> - AND D.NAME NOT IN - <foreach collection="genTable.params.genTableNames" open="(" close=")" separator="," item="item"> - #{item} - </foreach> - </if> - <if test="genTable.tableName != null and genTable.tableName != ''"> - AND lower(D.NAME) like lower(concat(N'%', N'${genTable.tableName}', N'%')) - </if> - <if test="genTable.tableComment != null and genTable.tableComment != ''"> - AND lower(CAST(F.VALUE AS nvarchar)) like lower(concat(N'%', N'${genTable.tableComment}', N'%')) - </if> - order by crdate desc - </if> - </select> - - <select id="selectDbTableListByNames" resultMap="GenTableResult"> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()"> - select table_name, table_comment, create_time, update_time from information_schema.tables - where table_schema = (select database()) - and table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' - and table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' - and table_name in - <foreach collection="array" item="name" open="(" separator="," close=")"> - #{name} - </foreach> - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()"> - select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time - from user_tables dt, user_tab_comments dtc, user_objects uo - where dt.table_name = dtc.table_name - and dt.table_name = uo.object_name - and uo.object_type = 'TABLE' - and dt.table_name NOT LIKE 'SJ_%' AND dt.table_name NOT LIKE 'GEN_%' - and dt.table_name NOT LIKE 'ACT_%' AND dt.table_name NOT LIKE 'FLW_%' - and lower(dt.table_name) in - <foreach collection="array" item="name" open="(" separator="," close=")"> - #{name} - </foreach> - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> - select table_name, table_comment, create_time, update_time - from ( - SELECT c.relname AS table_name, - obj_description(c.oid) AS table_comment, - CURRENT_TIMESTAMP AS create_time, - CURRENT_TIMESTAMP AS update_time - FROM pg_class c - LEFT JOIN pg_namespace n ON n.oid = c.relnamespace - WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) - AND c.relname != 'spatial_%'::text - AND n.nspname = 'public'::name - AND n.nspname <![CDATA[ <> ]]> ''::name - ) list_table - where table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' - and table_name NOT LIKE 'act_%' and table_name NOT LIKE 'flw_%' - and table_name in - <foreach collection="array" item="name" open="(" separator="," close=")"> - #{name} - </foreach> - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()"> - SELECT cast(D.NAME as nvarchar) as table_name, - cast(F.VALUE as nvarchar) as table_comment, - crdate as create_time, - refdate as update_time - FROM SYSOBJECTS D - INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID - AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' - AND D.NAME NOT LIKE 'sj_%' AND D.NAME NOT LIKE 'gen_%' - AND D.NAME NOT LIKE 'act_%' AND D.NAME NOT LIKE 'flw_%' - AND D.NAME in - <foreach collection="array" item="name" open="(" separator="," close=")"> - #{name} - </foreach> - </if> - </select> - - <select id="selectTableByName" parameterType="String" resultMap="GenTableResult"> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isMySql()"> - select table_name, table_comment, create_time, update_time from information_schema.tables - where table_schema = (select database()) - and table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' - and table_name NOT LIKE 'act_%' AND table_name NOT LIKE 'flw_%' - and table_name = #{tableName} - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isOracle()"> - select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time - from user_tables dt, user_tab_comments dtc, user_objects uo - where dt.table_name = dtc.table_name - and dt.table_name = uo.object_name - and uo.object_type = 'TABLE' - AND dt.table_name NOT LIKE 'SJ_%' AND dt.table_name NOT LIKE 'GEN_%' - AND dt.table_name NOT LIKE 'ACT_%' AND dt.table_name NOT LIKE 'FLW_%' - AND dt.table_name NOT IN (select table_name from gen_table) - and lower(dt.table_name) = #{tableName} - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isPostgerSql()"> - select table_name, table_comment, create_time, update_time - from ( - SELECT c.relname AS table_name, - obj_description(c.oid) AS table_comment, - CURRENT_TIMESTAMP AS create_time, - CURRENT_TIMESTAMP AS update_time - FROM pg_class c - LEFT JOIN pg_namespace n ON n.oid = c.relnamespace - WHERE (c.relkind = ANY (ARRAY ['r'::"char", 'p'::"char"])) - AND c.relname != 'spatial_%'::text - AND n.nspname = 'public'::name - AND n.nspname <![CDATA[ <> ]]> ''::name - ) list_table - where table_name NOT LIKE 'sj_%' and table_name NOT LIKE 'gen_%' - and table_name NOT LIKE 'act_%' and table_name NOT LIKE 'flw_%' - and table_name = #{tableName} - </if> - <if test="@org.dromara.common.mybatis.helper.DataBaseHelper@isSqlServer()"> - SELECT cast(D.NAME as nvarchar) as table_name, - cast(F.VALUE as nvarchar) as table_comment, - crdate as create_time, - refdate as update_time - FROM SYSOBJECTS D - INNER JOIN SYS.EXTENDED_PROPERTIES F ON D.ID = F.MAJOR_ID - AND F.MINOR_ID = 0 AND D.XTYPE = 'U' AND D.NAME != 'DTPROPERTIES' - AND D.NAME NOT LIKE 'sj_%' AND D.NAME NOT LIKE 'gen_%' - AND D.NAME NOT LIKE 'act_%' AND D.NAME NOT LIKE 'flw_%' - AND D.NAME = #{tableName} - </if> - </select> - - <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult"> + <sql id="genSelect"> SELECT t.table_id, t.data_name, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark, c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort FROM gen_table t - LEFT JOIN gen_table_column c ON t.table_id = c.table_id + LEFT JOIN gen_table_column c ON t.table_id = c.table_id + </sql> + + <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult"> + <include refid="genSelect"/> where t.table_id = #{tableId} order by c.sort </select> <select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult"> - SELECT t.table_id, t.data_name, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark, - c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort - FROM gen_table t - LEFT JOIN gen_table_column c ON t.table_id = c.table_id + <include refid="genSelect"/> where t.table_name = #{tableName} order by c.sort </select> <select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult"> - SELECT t.table_id, t.data_name, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark, - c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort - FROM gen_table t - LEFT JOIN gen_table_column c ON t.table_id = c.table_id + <include refid="genSelect"/> order by c.sort </select> diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm index f99a2ed..c896afb 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/vo.java.vm @@ -53,6 +53,13 @@ #end private $column.javaType $column.javaField; +#if($column.htmlType == "imageUpload") + /** + * ${column.columnComment}Url + */ + @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "${column.javaField}") + private String ${column.javaField}Url"; +#end #end #end diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/ts/types.ts.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/ts/types.ts.vm index c3f6ed1..35a468e 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/ts/types.ts.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/ts/types.ts.vm @@ -9,6 +9,12 @@ #elseif($column.javaType == 'Boolean') boolean; #else string; #end +#if($column.htmlType == "imageUpload") + /** + * ${column.columnComment}Url + */ + ${column.javaField}Url: string; +#end #end #end #if ($table.tree) diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm index d13ef2f..caf3472 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index-tree.vue.vm @@ -99,9 +99,9 @@ </template> </el-table-column> #elseif($column.list && $column.htmlType == "imageUpload") - <el-table-column label="${comment}" align="center" prop="${javaField}" width="100"> + <el-table-column label="${comment}" align="center" prop="${javaField}Url" width="100"> <template #default="scope"> - <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/> + <image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/> </template> </el-table-column> #elseif($column.list && $column.dictType && "" != $column.dictType) diff --git a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index 886f4ab..a92d19a 100644 --- a/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-modules/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -101,9 +101,9 @@ </template> </el-table-column> #elseif($column.list && $column.htmlType == "imageUpload") - <el-table-column label="${comment}" align="center" prop="${javaField}" width="100"> + <el-table-column label="${comment}" align="center" prop="${javaField}Url" width="100"> <template #default="scope"> - <image-preview :src="scope.row.${javaField}" :width="50" :height="50"/> + <image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/> </template> </el-table-column> #elseif($column.list && $column.dictType && "" != $column.dictType) diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml index acf33ce..0fc6d55 100644 --- a/ruoyi-modules/ruoyi-system/pom.xml +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -95,6 +95,11 @@ <artifactId>ruoyi-common-websocket</artifactId> </dependency> + <dependency> + <groupId>org.dromara</groupId> + <artifactId>ruoyi-common-sse</artifactId> + </dependency> + </dependencies> </project> diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java index 18e32d8..98ac2d5 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/monitor/SysLogininforController.java @@ -1,7 +1,9 @@ package org.dromara.system.controller.monitor; import cn.dev33.satoken.annotation.SaCheckPermission; -import org.dromara.common.core.constant.GlobalConstants; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.domain.R; import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.log.annotation.Log; @@ -13,8 +15,6 @@ import org.dromara.system.domain.bo.SysLogininforBo; import org.dromara.system.domain.vo.SysLogininforVo; import org.dromara.system.service.ISysLogininforService; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -79,7 +79,7 @@ @Log(title = "璐︽埛瑙i攣", businessType = BusinessType.OTHER) @GetMapping("/unlock/{userName}") public R<Void> unlock(@PathVariable("userName") String userName) { - String loginName = GlobalConstants.PWD_ERR_CNT_KEY + userName; + String loginName = CacheConstants.PWD_ERR_CNT_KEY + userName; if (RedisUtils.hasKey(loginName)) { RedisUtils.deleteObject(loginName); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java index 4f5f23f..968bbe9 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java @@ -12,6 +12,7 @@ import org.dromara.system.domain.bo.SysDeptBo; import org.dromara.system.domain.vo.SysDeptVo; import org.dromara.system.service.ISysDeptService; +import org.dromara.system.service.ISysPostService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -29,6 +30,7 @@ public class SysDeptController extends BaseController { private final ISysDeptService deptService; + private final ISysPostService postService; /** * 鑾峰彇閮ㄩ棬鍒楄〃 @@ -117,6 +119,9 @@ if (deptService.checkDeptExistUser(deptId)) { return R.warn("閮ㄩ棬瀛樺湪鐢ㄦ埛,涓嶅厑璁稿垹闄�"); } + if (postService.countPostByDeptId(deptId) > 0) { + return R.warn("閮ㄩ棬瀛樺湪宀椾綅,涓嶅厑璁稿垹闄�"); + } deptService.checkDeptDataScope(deptId); return toAjax(deptService.deleteDeptById(deptId)); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java index a0aa26e..5d65137 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java @@ -8,8 +8,8 @@ import org.dromara.common.log.enums.BusinessType; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.common.web.core.BaseController; -import org.dromara.common.websocket.utils.WebSocketUtils; import org.dromara.system.domain.bo.SysNoticeBo; import org.dromara.system.domain.vo.SysNoticeVo; import org.dromara.system.service.ISysNoticeService; @@ -62,7 +62,7 @@ return R.fail(); } String type = dictService.getDictLabel("sys_notice_type", notice.getNoticeType()); - WebSocketUtils.publishAll("[" + type + "] " + notice.getNoticeTitle()); + SseMessageUtils.publishAll("[" + type + "] " + notice.getNoticeTitle()); return R.ok(); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java index 559e1d5..893b381 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysProfileController.java @@ -11,6 +11,7 @@ import org.dromara.common.idempotent.annotation.RepeatSubmit; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.mybatis.helper.DataPermissionHelper; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.web.core.BaseController; import org.dromara.system.domain.bo.SysUserBo; @@ -72,7 +73,8 @@ if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) { return R.fail("淇敼鐢ㄦ埛'" + username + "'澶辫触锛岄偖绠辫处鍙峰凡瀛樺湪"); } - if (userService.updateUserProfile(user) > 0) { + int rows = DataPermissionHelper.ignore(() -> userService.updateUserProfile(user)); + if (rows > 0) { return R.ok(); } return R.fail("淇敼涓汉淇℃伅寮傚父锛岃鑱旂郴绠$悊鍛�"); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java index 60be68a..bad240c 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantController.java @@ -24,6 +24,7 @@ import org.dromara.system.domain.bo.SysTenantBo; import org.dromara.system.domain.vo.SysTenantVo; import org.dromara.system.service.ISysTenantService; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -38,6 +39,7 @@ @RequiredArgsConstructor @RestController @RequestMapping("/system/tenant") +@ConditionalOnProperty(value = "tenant.enable", havingValue = "true") public class SysTenantController extends BaseController { private final ISysTenantService tenantService; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java index 7d99916..4bfe597 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysTenantPackageController.java @@ -20,6 +20,7 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -34,6 +35,7 @@ @RequiredArgsConstructor @RestController @RequestMapping("/system/tenant/package") +@ConditionalOnProperty(value = "tenant.enable", havingValue = "true") public class SysTenantPackageController extends BaseController { private final ISysTenantPackageService tenantPackageService; @@ -92,6 +94,9 @@ @RepeatSubmit() @PostMapping() public R<Void> add(@Validated(AddGroup.class) @RequestBody SysTenantPackageBo bo) { + if (!tenantPackageService.checkPackageNameUnique(bo)) { + return R.fail("鏂板濂楅'" + bo.getPackageName() + "'澶辫触锛屽椁愬悕绉板凡瀛樺湪"); + } return toAjax(tenantPackageService.insertByBo(bo)); } @@ -104,6 +109,9 @@ @RepeatSubmit() @PutMapping() public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantPackageBo bo) { + if (!tenantPackageService.checkPackageNameUnique(bo)) { + return R.fail("淇敼濂楅'" + bo.getPackageName() + "'澶辫触锛屽椁愬悕绉板凡瀛樺湪"); + } return toAjax(tenantPackageService.updateByBo(bo)); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java index d1f4059..86249d2 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java @@ -61,13 +61,13 @@ /** * 鐢ㄦ埛閭 */ - @Sensitive(strategy = SensitiveStrategy.EMAIL) + @Sensitive(strategy = SensitiveStrategy.EMAIL, perms = "system:user:edit") private String email; /** * 鎵嬫満鍙风爜 */ - @Sensitive(strategy = SensitiveStrategy.PHONE) + @Sensitive(strategy = SensitiveStrategy.PHONE, perms = "system:user:edit") private String phonenumber; /** diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java index c43f039..3751b23 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysPostService.java @@ -81,6 +81,14 @@ long countUserPostById(Long postId); /** + * 閫氳繃閮ㄩ棬ID鏌ヨ宀椾綅浣跨敤鏁伴噺 + * + * @param deptId 閮ㄩ棬id + * @return 缁撴灉 + */ + long countPostByDeptId(Long deptId); + + /** * 鍒犻櫎宀椾綅淇℃伅 * * @param postId 宀椾綅ID diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java index cdb887c..d060b68 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTenantPackageService.java @@ -1,9 +1,9 @@ package org.dromara.system.service; -import org.dromara.system.domain.vo.SysTenantPackageVo; -import org.dromara.system.domain.bo.SysTenantPackageBo; -import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.system.domain.bo.SysTenantPackageBo; +import org.dromara.system.domain.vo.SysTenantPackageVo; import java.util.Collection; import java.util.List; @@ -46,6 +46,11 @@ Boolean updateByBo(SysTenantPackageBo bo); /** + * 鏍¢獙濂楅鍚嶇О鏄惁鍞竴 + */ + boolean checkPackageNameUnique(SysTenantPackageBo bo); + + /** * 淇敼濂楅鐘舵�� */ int updatePackageStatus(SysTenantPackageBo bo); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java index a31c426..018f9a0 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java @@ -2,6 +2,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import org.dromara.common.core.utils.StreamUtils; @@ -38,6 +39,9 @@ */ @Override public String getRoleCustom(Long roleId) { + if (ObjectUtil.isNull(roleId)) { + return "-1"; + } List<SysRoleDept> list = roleDeptMapper.selectList( new LambdaQueryWrapper<SysRoleDept>() .select(SysRoleDept::getDeptId) @@ -45,7 +49,7 @@ if (CollUtil.isNotEmpty(list)) { return StreamUtils.join(list, rd -> Convert.toStr(rd.getDeptId())); } - return null; + return "-1"; } /** @@ -56,6 +60,9 @@ */ @Override public String getDeptAndChild(Long deptId) { + if (ObjectUtil.isNull(deptId)) { + return "-1"; + } List<SysDept> deptList = deptMapper.selectList(new LambdaQueryWrapper<SysDept>() .select(SysDept::getDeptId) .apply(DataBaseHelper.findInSet(deptId, "ancestors"))); @@ -64,7 +71,7 @@ if (CollUtil.isNotEmpty(ids)) { return StreamUtils.join(ids, Convert::toStr); } - return null; + return "-1"; } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java index 5054036..160238d 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java @@ -78,7 +78,7 @@ private LambdaQueryWrapper<SysDept> buildQueryWrapper(SysDeptBo bo) { LambdaQueryWrapper<SysDept> lqw = Wrappers.lambdaQuery(); - lqw.eq(SysDept::getDelFlag, "0"); + lqw.eq(SysDept::getDelFlag, UserConstants.DEL_FLAG_NORMAL); lqw.eq(ObjectUtil.isNotNull(bo.getDeptId()), SysDept::getDeptId, bo.getDeptId()); lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), SysDept::getParentId, bo.getParentId()); lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName()); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java index d167e8d..1866531 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysOssServiceImpl.java @@ -77,8 +77,9 @@ @Override public List<SysOssVo> listByIds(Collection<Long> ossIds) { List<SysOssVo> list = new ArrayList<>(); + SysOssServiceImpl ossService = SpringUtils.getAopProxy(this); for (Long id : ossIds) { - SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); + SysOssVo vo = ossService.getById(id); if (ObjectUtil.isNotNull(vo)) { try { list.add(this.matchingUrl(vo)); @@ -100,8 +101,9 @@ @Override public String selectUrlByIds(String ossIds) { List<String> list = new ArrayList<>(); + SysOssServiceImpl ossService = SpringUtils.getAopProxy(this); for (Long id : StringUtils.splitTo(ossIds, Convert::toLong)) { - SysOssVo vo = SpringUtils.getAopProxy(this).getById(id); + SysOssVo vo = ossService.getById(id); if (ObjectUtil.isNotNull(vo)) { try { list.add(this.matchingUrl(vo).getUrl()); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java index b8a7e60..2c38129 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysPostServiceImpl.java @@ -178,6 +178,17 @@ } /** + * 閫氳繃閮ㄩ棬ID鏌ヨ宀椾綅浣跨敤鏁伴噺 + * + * @param deptId 閮ㄩ棬id + * @return 缁撴灉 + */ + @Override + public long countPostByDeptId(Long deptId) { + return baseMapper.selectCount(new LambdaQueryWrapper<SysPost>().eq(SysPost::getDeptId, deptId)); + } + + /** * 鍒犻櫎宀椾綅淇℃伅 * * @param postId 宀椾綅ID diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java index 31f9498..9b8b0ec 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java @@ -293,6 +293,10 @@ @Transactional(rollbackFor = Exception.class) public int updateRole(SysRoleBo bo) { SysRole role = MapstructUtils.convert(bo, SysRole.class); + + if (UserConstants.ROLE_DISABLE.equals(role.getStatus()) && this.countUserRoleByRoleId(role.getRoleId()) > 0) { + throw new ServiceException("瑙掕壊宸插垎閰嶏紝涓嶈兘绂佺敤!"); + } // 淇敼瑙掕壊淇℃伅 baseMapper.updateById(role); // 鍒犻櫎瑙掕壊涓庤彍鍗曞叧鑱� diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java index 5fd04af..d2a72f6 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTenantPackageServiceImpl.java @@ -1,6 +1,7 @@ package org.dromara.system.service.impl; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -117,6 +118,17 @@ } /** + * 鏍¢獙濂楅鍚嶇О鏄惁鍞竴 + */ + @Override + public boolean checkPackageNameUnique(SysTenantPackageBo bo) { + boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysTenantPackage>() + .eq(SysTenantPackage::getPackageName, bo.getPackageName()) + .ne(ObjectUtil.isNotNull(bo.getPackageId()), SysTenantPackage::getPackageId, bo.getPackageId())); + return !exist; + } + + /** * 淇敼濂楅鐘舵�� * * @param bo 濂楅淇℃伅 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index 3cb4159..2540606 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -26,10 +26,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.helper.DataBaseHelper; import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.system.domain.SysDept; -import org.dromara.system.domain.SysUser; -import org.dromara.system.domain.SysUserPost; -import org.dromara.system.domain.SysUserRole; +import org.dromara.system.domain.*; import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.vo.SysPostVo; import org.dromara.system.domain.vo.SysRoleVo; @@ -473,17 +470,14 @@ */ private void insertUserRole(Long userId, Long[] roleIds, boolean clear) { if (ArrayUtil.isNotEmpty(roleIds)) { - // 鍒ゆ柇鏄惁鍏锋湁姝よ鑹茬殑鎿嶄綔鏉冮檺 - List<SysRoleVo> roles = roleMapper.selectRoleList(new LambdaQueryWrapper<>()); - if (CollUtil.isEmpty(roles)) { - throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鐨勬暟鎹�"); - } - List<Long> roleList = StreamUtils.toList(roles, SysRoleVo::getRoleId); + List<Long> roleList = new ArrayList<>(List.of(roleIds)); if (!LoginHelper.isSuperAdmin(userId)) { roleList.remove(UserConstants.SUPER_ADMIN_ID); } - List<Long> canDoRoleList = StreamUtils.filter(List.of(roleIds), roleList::contains); - if (CollUtil.isEmpty(canDoRoleList)) { + // 鍒ゆ柇鏄惁鍏锋湁姝よ鑹茬殑鎿嶄綔鏉冮檺 + List<SysRoleVo> roles = roleMapper.selectRoleList( + new QueryWrapper<SysRole>().in("r.role_id", roleList)); + if (CollUtil.isEmpty(roles)) { throw new ServiceException("娌℃湁鏉冮檺璁块棶瑙掕壊鐨勬暟鎹�"); } if (clear) { @@ -491,7 +485,7 @@ userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId)); } // 鏂板鐢ㄦ埛涓庤鑹茬鐞� - List<SysUserRole> list = StreamUtils.toList(canDoRoleList, roleId -> { + List<SysUserRole> list = StreamUtils.toList(roleList, roleId -> { SysUserRole ur = new SysUserRole(); ur.setUserId(userId); ur.setRoleId(roleId); @@ -640,7 +634,7 @@ return List.of(); } List<SysUserVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<SysUser>() - .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName) + .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber) .eq(SysUser::getStatus, UserConstants.USER_NORMAL) .in(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds)); return BeanUtil.copyToList(list, UserDTO.class); @@ -653,4 +647,26 @@ return StreamUtils.toList(userRoles, SysUserRole::getUserId); } + @Override + public List<UserDTO> selectUsersByRoleIds(List<Long> roleIds) { + if (CollUtil.isEmpty(roleIds)) { + return List.of(); + } + List<SysUserRole> userRoles = userRoleMapper.selectList( + new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getRoleId, roleIds)); + List<Long> userIds = StreamUtils.toList(userRoles, SysUserRole::getUserId); + return selectListByIds(userIds); + } + + @Override + public List<UserDTO> selectUsersByDeptIds(List<Long> deptIds) { + if (CollUtil.isEmpty(deptIds)) { + return List.of(); + } + List<SysUserVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<SysUser>() + .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber) + .eq(SysUser::getStatus, UserConstants.USER_NORMAL) + .in(CollUtil.isNotEmpty(deptIds), SysUser::getDeptId, deptIds)); + return BeanUtil.copyToList(list, UserDTO.class); + } } diff --git a/ruoyi-modules/ruoyi-workflow/pom.xml b/ruoyi-modules/ruoyi-workflow/pom.xml index 9ed4097..e55839e 100644 --- a/ruoyi-modules/ruoyi-workflow/pom.xml +++ b/ruoyi-modules/ruoyi-workflow/pom.xml @@ -57,7 +57,7 @@ <dependency> <groupId>org.apache.xmlgraphics</groupId> <artifactId>batik-all</artifactId> - <version>1.10</version> + <version>1.17</version> <exclusions> <exclusion> <groupId>xalan</groupId> diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java index 3332f86..842d3d6 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActModelController.java @@ -18,6 +18,7 @@ import org.dromara.workflow.service.IActModelService; import org.flowable.engine.RepositoryService; import org.flowable.engine.repository.Model; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -36,8 +37,8 @@ @RequestMapping("/workflow/model") public class ActModelController extends BaseController { - private final RepositoryService repositoryService; - + @Autowired(required = false) + private RepositoryService repositoryService; private final IActModelService actModelService; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java index 75f9d9b..25724b6 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/ActTaskController.java @@ -21,6 +21,7 @@ import org.dromara.workflow.service.IWfTaskBackNodeService; import org.dromara.workflow.utils.QueryUtils; import org.flowable.engine.TaskService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -38,10 +39,9 @@ @RequestMapping("/workflow/task") public class ActTaskController extends BaseController { + @Autowired(required = false) + private TaskService taskService; private final IActTaskService actTaskService; - - private final TaskService taskService; - private final IWfTaskBackNodeService wfTaskBackNodeService; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java index d4f696b..217538e 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActModelServiceImpl.java @@ -39,6 +39,7 @@ import org.flowable.engine.repository.ModelQuery; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.validation.ValidationError; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -65,7 +66,8 @@ @Service public class ActModelServiceImpl implements IActModelService { - private final RepositoryService repositoryService; + @Autowired(required = false) + private RepositoryService repositoryService; private final IWfNodeConfigService wfNodeConfigService; private final IWfDefinitionConfigService wfDefinitionConfigService; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java index 6a17289..77fb257 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessDefinitionServiceImpl.java @@ -37,6 +37,7 @@ import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.impl.bpmn.deployer.ResourceNameUtil; import org.flowable.engine.repository.*; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -61,8 +62,10 @@ @Service public class ActProcessDefinitionServiceImpl implements IActProcessDefinitionService { - private final RepositoryService repositoryService; - private final ProcessMigrationService processMigrationService; + @Autowired(required = false) + private RepositoryService repositoryService; + @Autowired(required = false) + private ProcessMigrationService processMigrationService; private final IWfCategoryService wfCategoryService; private final IWfDefinitionConfigService wfDefinitionConfigService; private final WfDefinitionConfigMapper wfDefinitionConfigMapper; @@ -288,6 +291,7 @@ Model modelData = repositoryService.newModel(); modelData.setKey(pd.getKey()); modelData.setName(pd.getName()); + modelData.setCategory(pd.getCategory()); modelData.setTenantId(pd.getTenantId()); repositoryService.saveModel(modelData); repositoryService.addModelEditorSource(modelData.getId(), IoUtil.readBytes(inputStream)); @@ -350,8 +354,7 @@ initWfDefConfig(); } else { String originalFilename = file.getOriginalFilename(); - String bpmnResourceSuffix = ResourceNameUtil.BPMN_RESOURCE_SUFFIXES[0]; - if (originalFilename.contains(bpmnResourceSuffix)) { + if (StringUtils.containsAny(originalFilename, ResourceNameUtil.BPMN_RESOURCE_SUFFIXES)) { // 鏂囦欢鍚� = 娴佺▼鍚嶇О-娴佺▼key String[] splitFilename = originalFilename.substring(0, originalFilename.lastIndexOf(".")).split("-"); if (splitFilename.length < 2) { diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java index e22e800..8b9b113 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActProcessInstanceServiceImpl.java @@ -48,6 +48,7 @@ import org.flowable.task.api.Task; import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -68,12 +69,17 @@ @Service public class ActProcessInstanceServiceImpl implements IActProcessInstanceService { - private final RepositoryService repositoryService; - private final RuntimeService runtimeService; - private final HistoryService historyService; - private final TaskService taskService; + @Autowired(required = false) + private RepositoryService repositoryService; + @Autowired(required = false) + private RuntimeService runtimeService; + @Autowired(required = false) + private HistoryService historyService; + @Autowired(required = false) + private TaskService taskService; + @Autowired(required = false) + private ManagementService managementService; private final IActHiProcinstService actHiProcinstService; - private final ManagementService managementService; private final IWfTaskBackNodeService wfTaskBackNodeService; private final IWfNodeConfigService wfNodeConfigService; private final FlowProcessEventHandler flowProcessEventHandler; diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java index 32e6aec..5235d12 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/ActTaskServiceImpl.java @@ -52,6 +52,7 @@ import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.flowable.variable.api.persistence.entity.VariableInstance; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -71,11 +72,16 @@ @Service public class ActTaskServiceImpl implements IActTaskService { - private final RuntimeService runtimeService; - private final TaskService taskService; - private final HistoryService historyService; - private final IdentityService identityService; - private final ManagementService managementService; + @Autowired(required = false) + private RuntimeService runtimeService; + @Autowired(required = false) + private TaskService taskService; + @Autowired(required = false) + private HistoryService historyService; + @Autowired(required = false) + private IdentityService identityService; + @Autowired(required = false) + private ManagementService managementService; private final ActTaskMapper actTaskMapper; private final IWfTaskBackNodeService wfTaskBackNodeService; private final ActHiTaskinstMapper actHiTaskinstMapper; @@ -261,7 +267,7 @@ queryWrapper.eq("t.business_status_", BusinessStatusEnum.WAITING.getStatus()); queryWrapper.eq(TenantHelper.isEnable(), "t.tenant_id_", TenantHelper.getTenantId()); String ids = StreamUtils.join(roleIds, x -> "'" + x + "'"); - queryWrapper.and(w1 -> w1.eq("t.assignee_", userId).or(w2 -> w2.isNull("t.assignee_").apply("exists ( select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TASK_ID_ = t.ID_ and LINK.TYPE_ = 'candidate' and (LINK.USER_ID_ = {0} or ( LINK.GROUP_ID_ IN ({1}) ) ))", userId, ids))); + queryWrapper.and(w1 -> w1.eq("t.assignee_", userId).or(w2 -> w2.isNull("t.assignee_").apply("exists ( select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TASK_ID_ = t.ID_ and LINK.TYPE_ = 'candidate' and (LINK.USER_ID_ = {0} or ( LINK.GROUP_ID_ IN (" + ids + ") ) ))", userId))); if (StringUtils.isNotBlank(taskBo.getName())) { queryWrapper.like("t.name_", taskBo.getName()); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java index b498262..e562823 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfCategoryServiceImpl.java @@ -15,6 +15,7 @@ import org.flowable.engine.repository.Deployment; import org.flowable.engine.repository.Model; import org.flowable.engine.repository.ProcessDefinition; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -32,8 +33,8 @@ public class WfCategoryServiceImpl implements IWfCategoryService { private final WfCategoryMapper baseMapper; - - private final RepositoryService repositoryService; + @Autowired(required = false) + private RepositoryService repositoryService; /** * 鏌ヨ娴佺▼鍒嗙被 diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java index 11f6ef1..f75a188 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WorkflowServiceImpl.java @@ -8,6 +8,7 @@ import org.dromara.workflow.service.IActProcessInstanceService; import org.dromara.workflow.utils.WorkflowUtils; import org.flowable.engine.RuntimeService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @@ -22,8 +23,9 @@ @Service public class WorkflowServiceImpl implements WorkflowService { + @Autowired(required = false) + private RuntimeService runtimeService; private final IActProcessInstanceService iActProcessInstanceService; - private final RuntimeService runtimeService; private final IActHiProcinstService iActHiProcinstService; /** * 杩愯涓殑瀹炰緥 鍒犻櫎绋嬪疄渚嬶紝鍒犻櫎鍘嗗彶璁板綍锛屽垹闄や笟鍔′笌娴佺▼鍏宠仈淇℃伅 diff --git a/script/docker/docker-compose.yml b/script/docker/docker-compose.yml index b4f96aa..91d97ae 100644 --- a/script/docker/docker-compose.yml +++ b/script/docker/docker-compose.yml @@ -100,7 +100,7 @@ network_mode: "host" ruoyi-server1: - image: ruoyi/ruoyi-server:5.2.1 + image: ruoyi/ruoyi-server:5.2.2 container_name: ruoyi-server1 environment: # 鏃跺尯涓婃捣 @@ -115,7 +115,7 @@ network_mode: "host" ruoyi-server2: - image: ruoyi/ruoyi-server:5.2.1 + image: ruoyi/ruoyi-server:5.2.2 container_name: ruoyi-server2 environment: # 鏃跺尯涓婃捣 @@ -130,7 +130,7 @@ network_mode: "host" ruoyi-monitor-admin: - image: ruoyi/ruoyi-monitor-admin:5.2.1 + image: ruoyi/ruoyi-monitor-admin:5.2.2 container_name: ruoyi-monitor-admin environment: # 鏃跺尯涓婃捣 @@ -142,7 +142,7 @@ network_mode: "host" ruoyi-snailjob-server: - image: ruoyi/ruoyi-snailjob-server:5.2.1 + image: ruoyi/ruoyi-snailjob-server:5.2.2 container_name: ruoyi-snailjob-server environment: # 鏃跺尯涓婃捣 diff --git a/script/docker/nginx/conf/nginx.conf b/script/docker/nginx/conf/nginx.conf index a6fc073..3c79d97 100644 --- a/script/docker/nginx/conf/nginx.conf +++ b/script/docker/nginx/conf/nginx.conf @@ -78,10 +78,13 @@ proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # websocket鍙傛暟 + proxy_read_timeout 86400s; + # sse 涓� websocket鍙傛暟 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + proxy_buffering off; + proxy_cache off; proxy_pass http://server/; } diff --git a/script/sql/oracle/snail_job_oracle.sql b/script/sql/oracle/snail_job_oracle.sql index 19aa07e..d2e17c1 100644 --- a/script/sql/oracle/snail_job_oracle.sql +++ b/script/sql/oracle/snail_job_oracle.sql @@ -2,7 +2,7 @@ SnailJob Database Transfer Tool Source Server Type : MySQL Target Server Type : Oracle - Date: 2024-05-14 23:36:38 + Date: 2024-07-06 12:49:36 */ @@ -136,7 +136,7 @@ COMMENT ON COLUMN sj_notify_recipient.id IS '涓婚敭'; COMMENT ON COLUMN sj_notify_recipient.namespace_id IS '鍛藉悕绌洪棿id'; COMMENT ON COLUMN sj_notify_recipient.recipient_name IS '鎺ユ敹浜哄悕绉�'; -COMMENT ON COLUMN sj_notify_recipient.notify_type IS '閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功'; +COMMENT ON COLUMN sj_notify_recipient.notify_type IS '閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功 5 webhook'; COMMENT ON COLUMN sj_notify_recipient.notify_attribute IS '閰嶇疆灞炴��'; COMMENT ON COLUMN sj_notify_recipient.description IS '鎻忚堪'; COMMENT ON COLUMN sj_notify_recipient.create_dt IS '鍒涘缓鏃堕棿'; @@ -296,8 +296,8 @@ ALTER TABLE sj_retry_task_log_message ADD CONSTRAINT pk_sj_retry_task_log_message PRIMARY KEY (id); -CREATE INDEX idx_sj_retry_task_log_message_01 ON sj_retry_task_log_message (namespace_id, group_name, unique_id); -CREATE INDEX idx_sj_retry_task_log_message_02 ON sj_retry_task_log_message (create_dt); +CREATE INDEX idx_sj_rt_log_message_01 ON sj_retry_task_log_message (namespace_id, group_name, unique_id); +CREATE INDEX idx_sj_rt_log_message_02 ON sj_retry_task_log_message (create_dt); COMMENT ON COLUMN sj_retry_task_log_message.id IS '涓婚敭'; COMMENT ON COLUMN sj_retry_task_log_message.namespace_id IS '鍛藉悕绌洪棿id'; @@ -389,8 +389,7 @@ -- sj_distributed_lock CREATE TABLE sj_distributed_lock ( - id number GENERATED ALWAYS AS IDENTITY, - name varchar2(64) NULL, + name varchar2(64) NOT NULL, lock_until timestamp(3) DEFAULT CURRENT_TIMESTAMP(3) NOT NULL, locked_at timestamp(3) DEFAULT CURRENT_TIMESTAMP(3) NOT NULL, locked_by varchar2(255) NULL, @@ -399,9 +398,8 @@ ); ALTER TABLE sj_distributed_lock - ADD CONSTRAINT pk_sj_distributed_lock PRIMARY KEY (id); + ADD CONSTRAINT pk_sj_distributed_lock PRIMARY KEY (name); -COMMENT ON COLUMN sj_distributed_lock.id IS '涓婚敭'; COMMENT ON COLUMN sj_distributed_lock.name IS '閿佸悕绉�'; COMMENT ON COLUMN sj_distributed_lock.lock_until IS '閿佸畾鏃堕暱'; COMMENT ON COLUMN sj_distributed_lock.locked_at IS '閿佸畾鏃堕棿'; @@ -449,7 +447,7 @@ ALTER TABLE sj_system_user_permission ADD CONSTRAINT pk_sj_system_user_permission PRIMARY KEY (id); -CREATE UNIQUE INDEX uk_sj_system_user_permission_01 ON sj_system_user_permission (namespace_id, group_name, system_user_id); +CREATE UNIQUE INDEX uk_sj_su_permission_01 ON sj_system_user_permission (namespace_id, group_name, system_user_id); COMMENT ON COLUMN sj_system_user_permission.id IS '涓婚敭'; COMMENT ON COLUMN sj_system_user_permission.group_name IS '缁勫悕绉�'; @@ -598,7 +596,11 @@ parent_id number DEFAULT 0 NOT NULL, task_status smallint DEFAULT 0 NOT NULL, retry_count number DEFAULT 0 NOT NULL, + mr_stage smallint DEFAULT NULL NULL, + leaf smallint DEFAULT '1' NOT NULL, + task_name varchar2(255) DEFAULT '' NULL, client_info varchar2(128) DEFAULT NULL NULL, + wf_context clob DEFAULT NULL NULL, result_message clob NULL, args_str clob DEFAULT NULL NULL, args_type smallint DEFAULT 1 NOT NULL, @@ -622,7 +624,11 @@ COMMENT ON COLUMN sj_job_task.parent_id IS '鐖舵墽琛屽櫒id'; COMMENT ON COLUMN sj_job_task.task_status IS '鎵ц鐨勭姸鎬� 0銆佸け璐� 1銆佹垚鍔�'; COMMENT ON COLUMN sj_job_task.retry_count IS '閲嶈瘯娆℃暟'; +COMMENT ON COLUMN sj_job_task.mr_stage IS '鍔ㄦ�佸垎鐗囨墍澶勯樁娈� 1:map 2:reduce 3:mergeReduce'; +COMMENT ON COLUMN sj_job_task.leaf IS '鍙跺瓙鑺傜偣'; +COMMENT ON COLUMN sj_job_task.task_name IS '浠诲姟鍚嶇О'; COMMENT ON COLUMN sj_job_task.client_info IS '瀹㈡埛绔湴鍧� clientId#ip:port'; +COMMENT ON COLUMN sj_job_task.wf_context IS '宸ヤ綔娴佸叏灞�涓婁笅鏂�'; COMMENT ON COLUMN sj_job_task.result_message IS '鎵ц缁撴灉'; COMMENT ON COLUMN sj_job_task.args_str IS '鎵ц鏂规硶鍙傛暟'; COMMENT ON COLUMN sj_job_task.args_type IS '鍙傛暟绫诲瀷 '; @@ -773,6 +779,7 @@ executor_timeout number DEFAULT 0 NOT NULL, description varchar2(256) DEFAULT '' NULL, flow_info clob DEFAULT NULL NULL, + wf_context clob DEFAULT NULL NULL, bucket_index number DEFAULT 0 NOT NULL, version number NOT NULL, ext_attrs varchar2(256) DEFAULT '' NULL, @@ -799,6 +806,7 @@ COMMENT ON COLUMN sj_workflow.executor_timeout IS '浠诲姟鎵ц瓒呮椂鏃堕棿锛屽崟浣嶇'; COMMENT ON COLUMN sj_workflow.description IS '鎻忚堪'; COMMENT ON COLUMN sj_workflow.flow_info IS '娴佺▼淇℃伅'; +COMMENT ON COLUMN sj_workflow.wf_context IS '涓婁笅鏂�'; COMMENT ON COLUMN sj_workflow.bucket_index IS 'bucket'; COMMENT ON COLUMN sj_workflow.version IS '鐗堟湰鍙�'; COMMENT ON COLUMN sj_workflow.ext_attrs IS '鎵╁睍瀛楁'; @@ -864,8 +872,10 @@ task_batch_status smallint DEFAULT 0 NOT NULL, operation_reason smallint DEFAULT 0 NOT NULL, flow_info clob DEFAULT NULL NULL, + wf_context clob DEFAULT NULL NULL, execution_at number DEFAULT 0 NOT NULL, ext_attrs varchar2(256) DEFAULT '' NULL, + version number DEFAULT 1 NOT NULL, deleted smallint DEFAULT 0 NOT NULL, create_dt date DEFAULT CURRENT_TIMESTAMP NOT NULL, update_dt date DEFAULT CURRENT_TIMESTAMP NOT NULL @@ -885,10 +895,11 @@ COMMENT ON COLUMN sj_workflow_task_batch.task_batch_status IS '浠诲姟鎵规鐘舵�� 0銆佸け璐� 1銆佹垚鍔�'; COMMENT ON COLUMN sj_workflow_task_batch.operation_reason IS '鎿嶄綔鍘熷洜'; COMMENT ON COLUMN sj_workflow_task_batch.flow_info IS '娴佺▼淇℃伅'; +COMMENT ON COLUMN sj_workflow_task_batch.wf_context IS '鍏ㄥ眬涓婁笅鏂�'; COMMENT ON COLUMN sj_workflow_task_batch.execution_at IS '浠诲姟鎵ц鏃堕棿'; COMMENT ON COLUMN sj_workflow_task_batch.ext_attrs IS '鎵╁睍瀛楁'; +COMMENT ON COLUMN sj_workflow_task_batch.version IS '鐗堟湰鍙�'; COMMENT ON COLUMN sj_workflow_task_batch.deleted IS '閫昏緫鍒犻櫎 1銆佸垹闄�'; COMMENT ON COLUMN sj_workflow_task_batch.create_dt IS '鍒涘缓鏃堕棿'; COMMENT ON COLUMN sj_workflow_task_batch.update_dt IS '淇敼鏃堕棿'; COMMENT ON TABLE sj_workflow_task_batch IS '宸ヤ綔娴佹壒娆�'; - diff --git a/script/sql/postgres/snail_job_postgre.sql b/script/sql/postgres/snail_job_postgre.sql index 30a871e..c8abc68 100644 --- a/script/sql/postgres/snail_job_postgre.sql +++ b/script/sql/postgres/snail_job_postgre.sql @@ -2,7 +2,7 @@ SnailJob Database Transfer Tool Source Server Type : MySQL Target Server Type : PostgreSQL - Date: 2024-05-13 22:49:34 + Date: 2024-07-06 11:45:40 */ @@ -124,7 +124,7 @@ COMMENT ON COLUMN sj_notify_recipient.id IS '涓婚敭'; COMMENT ON COLUMN sj_notify_recipient.namespace_id IS '鍛藉悕绌洪棿id'; COMMENT ON COLUMN sj_notify_recipient.recipient_name IS '鎺ユ敹浜哄悕绉�'; -COMMENT ON COLUMN sj_notify_recipient.notify_type IS '閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功'; +COMMENT ON COLUMN sj_notify_recipient.notify_type IS '閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功 5 webhook'; COMMENT ON COLUMN sj_notify_recipient.notify_attribute IS '閰嶇疆灞炴��'; COMMENT ON COLUMN sj_notify_recipient.description IS '鎻忚堪'; COMMENT ON COLUMN sj_notify_recipient.create_dt IS '鍒涘缓鏃堕棿'; @@ -359,8 +359,7 @@ -- sj_distributed_lock CREATE TABLE sj_distributed_lock ( - id bigserial PRIMARY KEY, - name varchar(64) NOT NULL, + name varchar(64) PRIMARY KEY, lock_until timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), locked_at timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), locked_by varchar(255) NOT NULL, @@ -368,7 +367,6 @@ update_dt timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ); -COMMENT ON COLUMN sj_distributed_lock.id IS '涓婚敭'; COMMENT ON COLUMN sj_distributed_lock.name IS '閿佸悕绉�'; COMMENT ON COLUMN sj_distributed_lock.lock_until IS '閿佸畾鏃堕暱'; COMMENT ON COLUMN sj_distributed_lock.locked_at IS '閿佸畾鏃堕棿'; @@ -550,7 +548,11 @@ parent_id bigint NOT NULL DEFAULT 0, task_status smallint NOT NULL DEFAULT 0, retry_count int NOT NULL DEFAULT 0, + mr_stage smallint NULL DEFAULT NULL, + leaf smallint NOT NULL DEFAULT '1', + task_name varchar(255) NOT NULL DEFAULT '', client_info varchar(128) NULL DEFAULT NULL, + wf_context text NULL DEFAULT NULL, result_message text NOT NULL, args_str text NULL DEFAULT NULL, args_type smallint NOT NULL DEFAULT 1, @@ -571,7 +573,11 @@ COMMENT ON COLUMN sj_job_task.parent_id IS '鐖舵墽琛屽櫒id'; COMMENT ON COLUMN sj_job_task.task_status IS '鎵ц鐨勭姸鎬� 0銆佸け璐� 1銆佹垚鍔�'; COMMENT ON COLUMN sj_job_task.retry_count IS '閲嶈瘯娆℃暟'; +COMMENT ON COLUMN sj_job_task.mr_stage IS '鍔ㄦ�佸垎鐗囨墍澶勯樁娈� 1:map 2:reduce 3:mergeReduce'; +COMMENT ON COLUMN sj_job_task.leaf IS '鍙跺瓙鑺傜偣'; +COMMENT ON COLUMN sj_job_task.task_name IS '浠诲姟鍚嶇О'; COMMENT ON COLUMN sj_job_task.client_info IS '瀹㈡埛绔湴鍧� clientId#ip:port'; +COMMENT ON COLUMN sj_job_task.wf_context IS '宸ヤ綔娴佸叏灞�涓婁笅鏂�'; COMMENT ON COLUMN sj_job_task.result_message IS '鎵ц缁撴灉'; COMMENT ON COLUMN sj_job_task.args_str IS '鎵ц鏂规硶鍙傛暟'; COMMENT ON COLUMN sj_job_task.args_type IS '鍙傛暟绫诲瀷 '; @@ -713,6 +719,7 @@ executor_timeout int NOT NULL DEFAULT 0, description varchar(256) NOT NULL DEFAULT '', flow_info text NULL DEFAULT NULL, + wf_context text NULL DEFAULT NULL, bucket_index int NOT NULL DEFAULT 0, version int NOT NULL, ext_attrs varchar(256) NULL DEFAULT '', @@ -736,6 +743,7 @@ COMMENT ON COLUMN sj_workflow.executor_timeout IS '浠诲姟鎵ц瓒呮椂鏃堕棿锛屽崟浣嶇'; COMMENT ON COLUMN sj_workflow.description IS '鎻忚堪'; COMMENT ON COLUMN sj_workflow.flow_info IS '娴佺▼淇℃伅'; +COMMENT ON COLUMN sj_workflow.wf_context IS '涓婁笅鏂�'; COMMENT ON COLUMN sj_workflow.bucket_index IS 'bucket'; COMMENT ON COLUMN sj_workflow.version IS '鐗堟湰鍙�'; COMMENT ON COLUMN sj_workflow.ext_attrs IS '鎵╁睍瀛楁'; @@ -798,8 +806,10 @@ task_batch_status smallint NOT NULL DEFAULT 0, operation_reason smallint NOT NULL DEFAULT 0, flow_info text NULL DEFAULT NULL, + wf_context text NULL DEFAULT NULL, execution_at bigint NOT NULL DEFAULT 0, ext_attrs varchar(256) NULL DEFAULT '', + version int NOT NULL DEFAULT 1, deleted smallint NOT NULL DEFAULT 0, create_dt timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, update_dt timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP @@ -816,10 +826,11 @@ COMMENT ON COLUMN sj_workflow_task_batch.task_batch_status IS '浠诲姟鎵规鐘舵�� 0銆佸け璐� 1銆佹垚鍔�'; COMMENT ON COLUMN sj_workflow_task_batch.operation_reason IS '鎿嶄綔鍘熷洜'; COMMENT ON COLUMN sj_workflow_task_batch.flow_info IS '娴佺▼淇℃伅'; +COMMENT ON COLUMN sj_workflow_task_batch.wf_context IS '鍏ㄥ眬涓婁笅鏂�'; COMMENT ON COLUMN sj_workflow_task_batch.execution_at IS '浠诲姟鎵ц鏃堕棿'; COMMENT ON COLUMN sj_workflow_task_batch.ext_attrs IS '鎵╁睍瀛楁'; +COMMENT ON COLUMN sj_workflow_task_batch.version IS '鐗堟湰鍙�'; COMMENT ON COLUMN sj_workflow_task_batch.deleted IS '閫昏緫鍒犻櫎 1銆佸垹闄�'; COMMENT ON COLUMN sj_workflow_task_batch.create_dt IS '鍒涘缓鏃堕棿'; COMMENT ON COLUMN sj_workflow_task_batch.update_dt IS '淇敼鏃堕棿'; COMMENT ON TABLE sj_workflow_task_batch IS '宸ヤ綔娴佹壒娆�'; - diff --git a/script/sql/snail_job.sql b/script/sql/snail_job.sql index ce93e11..c3aa760 100644 --- a/script/sql/snail_job.sql +++ b/script/sql/snail_job.sql @@ -68,7 +68,7 @@ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '涓婚敭', `namespace_id` varchar(64) NOT NULL DEFAULT '764d604ec6fc45f68cd92514c40e9e1a' COMMENT '鍛藉悕绌洪棿id', `recipient_name` varchar(64) NOT NULL COMMENT '鎺ユ敹浜哄悕绉�', - `notify_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功', + `notify_type` tinyint(4) NOT NULL DEFAULT 0 COMMENT '閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功 5 webhook', `notify_attribute` varchar(512) NOT NULL COMMENT '閰嶇疆灞炴��', `description` varchar(256) NOT NULL DEFAULT '' COMMENT '鎻忚堪', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿', @@ -222,15 +222,13 @@ CREATE TABLE `sj_distributed_lock` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '涓婚敭', `name` varchar(64) NOT NULL COMMENT '閿佸悕绉�', `lock_until` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '閿佸畾鏃堕暱', `locked_at` timestamp(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '閿佸畾鏃堕棿', `locked_by` varchar(255) NOT NULL COMMENT '閿佸畾鑰�', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿', `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿', - PRIMARY KEY (`id`), - UNIQUE KEY `uk_name` (`name`) + PRIMARY KEY (`name`) ) ENGINE = InnoDB AUTO_INCREMENT = 0 DEFAULT CHARSET = utf8mb4 COMMENT ='閿佸畾琛�'; @@ -345,12 +343,16 @@ `job_id` bigint(20) NOT NULL COMMENT '浠诲姟淇℃伅id', `task_batch_id` bigint(20) NOT NULL COMMENT '璋冨害浠诲姟id', `parent_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '鐖舵墽琛屽櫒id', - `task_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '鎵ц鐨勭姸鎬� 0銆佸け璐� 1銆佹垚鍔�', + `task_status` tinyint NOT NULL DEFAULT 0 COMMENT '鎵ц鐨勭姸鎬� 0銆佸け璐� 1銆佹垚鍔�', `retry_count` int(11) NOT NULL DEFAULT 0 COMMENT '閲嶈瘯娆℃暟', + `mr_stage` tinyint DEFAULT NULL COMMENT '鍔ㄦ�佸垎鐗囨墍澶勯樁娈� 1:map 2:reduce 3:mergeReduce', + `leaf` tinyint NOT NULL DEFAULT '1' COMMENT '鍙跺瓙鑺傜偣', + `task_name` varchar(255) NOT NULL DEFAULT '' COMMENT '浠诲姟鍚嶇О', `client_info` varchar(128) DEFAULT NULL COMMENT '瀹㈡埛绔湴鍧� clientId#ip:port', + `wf_context` text DEFAULT NULL COMMENT '宸ヤ綔娴佸叏灞�涓婁笅鏂�', `result_message` text NOT NULL COMMENT '鎵ц缁撴灉', `args_str` text DEFAULT NULL COMMENT '鎵ц鏂规硶鍙傛暟', - `args_type` tinyint(4) NOT NULL DEFAULT 1 COMMENT '鍙傛暟绫诲瀷 ', + `args_type` tinyint NOT NULL DEFAULT 1 COMMENT '鍙傛暟绫诲瀷 ', `ext_attrs` varchar(256) NULL DEFAULT '' COMMENT '鎵╁睍瀛楁', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿', `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿', @@ -447,6 +449,7 @@ `executor_timeout` int(11) NOT NULL DEFAULT 0 COMMENT '浠诲姟鎵ц瓒呮椂鏃堕棿锛屽崟浣嶇', `description` varchar(256) NOT NULL DEFAULT '' COMMENT '鎻忚堪', `flow_info` text DEFAULT NULL COMMENT '娴佺▼淇℃伅', + `wf_context` text DEFAULT NULL COMMENT '涓婁笅鏂�', `bucket_index` int(11) NOT NULL DEFAULT 0 COMMENT 'bucket', `version` int(11) NOT NULL COMMENT '鐗堟湰鍙�', `ext_attrs` varchar(256) NULL DEFAULT '' COMMENT '鎵╁睍瀛楁', @@ -495,8 +498,10 @@ `task_batch_status` tinyint(4) NOT NULL DEFAULT 0 COMMENT '浠诲姟鎵规鐘舵�� 0銆佸け璐� 1銆佹垚鍔�', `operation_reason` tinyint(4) NOT NULL DEFAULT 0 COMMENT '鎿嶄綔鍘熷洜', `flow_info` text DEFAULT NULL COMMENT '娴佺▼淇℃伅', + `wf_context` text DEFAULT NULL COMMENT '鍏ㄥ眬涓婁笅鏂�', `execution_at` bigint(13) NOT NULL DEFAULT 0 COMMENT '浠诲姟鎵ц鏃堕棿', `ext_attrs` varchar(256) NULL DEFAULT '' COMMENT '鎵╁睍瀛楁', + `version` int(11) NOT NULL DEFAULT 1 COMMENT '鐗堟湰鍙�', `deleted` tinyint(4) NOT NULL DEFAULT 0 COMMENT '閫昏緫鍒犻櫎 1銆佸垹闄�', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '鍒涘缓鏃堕棿', `update_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '淇敼鏃堕棿', diff --git a/script/sql/sqlserver/snail_job_sqlserver.sql b/script/sql/sqlserver/snail_job_sqlserver.sql index d6fa1ae..249842b 100644 --- a/script/sql/sqlserver/snail_job_sqlserver.sql +++ b/script/sql/sqlserver/snail_job_sqlserver.sql @@ -2,7 +2,7 @@ SnailJob Database Transfer Tool Source Server Type : MySQL Target Server Type : Microsoft SQL Server - Date: 2024-05-13 23:03:34 + Date: 2024-07-06 12:55:47 */ @@ -370,7 +370,7 @@ GO EXEC sp_addextendedproperty - 'MS_Description', N'閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功', + 'MS_Description', N'閫氱煡绫诲瀷 1銆侀拤閽� 2銆侀偖浠� 3銆佷紒涓氬井淇� 4 椋炰功 5 webhook', 'SCHEMA', N'dbo', 'TABLE', N'sj_notify_recipient', 'COLUMN', N'notify_type' @@ -1142,21 +1142,13 @@ -- sj_distributed_lock CREATE TABLE sj_distributed_lock ( - id bigint NOT NULL PRIMARY KEY IDENTITY, - name nvarchar(64) NOT NULL, + name nvarchar(64) NOT NULL PRIMARY KEY, lock_until datetime2 NOT NULL DEFAULT CURRENT_TIMESTAMP, locked_at datetime2 NOT NULL DEFAULT CURRENT_TIMESTAMP, locked_by nvarchar(255) NOT NULL, create_dt datetime2 NOT NULL DEFAULT CURRENT_TIMESTAMP, update_dt datetime2 NOT NULL DEFAULT CURRENT_TIMESTAMP ) -GO - -EXEC sp_addextendedproperty - 'MS_Description', N'涓婚敭', - 'SCHEMA', N'dbo', - 'TABLE', N'sj_distributed_lock', - 'COLUMN', N'id' GO EXEC sp_addextendedproperty @@ -1745,7 +1737,11 @@ parent_id bigint NOT NULL DEFAULT 0, task_status tinyint NOT NULL DEFAULT 0, retry_count int NOT NULL DEFAULT 0, + mr_stage tinyint NULL DEFAULT NULL, + leaf tinyint NOT NULL DEFAULT '1', + task_name nvarchar(255) NOT NULL DEFAULT '', client_info nvarchar(128) NULL DEFAULT NULL, + wf_context nvarchar(max) NULL DEFAULT NULL, result_message nvarchar(max) NOT NULL, args_str nvarchar(max) NULL DEFAULT NULL, args_type tinyint NOT NULL DEFAULT 1, @@ -1819,10 +1815,38 @@ GO EXEC sp_addextendedproperty + 'MS_Description', N'鍔ㄦ�佸垎鐗囨墍澶勯樁娈� 1:map 2:reduce 3:mergeReduce', + 'SCHEMA', N'dbo', + 'TABLE', N'sj_job_task', + 'COLUMN', N'mr_stage' +GO + +EXEC sp_addextendedproperty + 'MS_Description', N'鍙跺瓙鑺傜偣', + 'SCHEMA', N'dbo', + 'TABLE', N'sj_job_task', + 'COLUMN', N'leaf' +GO + +EXEC sp_addextendedproperty + 'MS_Description', N'浠诲姟鍚嶇О', + 'SCHEMA', N'dbo', + 'TABLE', N'sj_job_task', + 'COLUMN', N'task_name' +GO + +EXEC sp_addextendedproperty 'MS_Description', N'瀹㈡埛绔湴鍧� clientId#ip:port', 'SCHEMA', N'dbo', 'TABLE', N'sj_job_task', 'COLUMN', N'client_info' +GO + +EXEC sp_addextendedproperty + 'MS_Description', N'宸ヤ綔娴佸叏灞�涓婁笅鏂�', + 'SCHEMA', N'dbo', + 'TABLE', N'sj_job_task', + 'COLUMN', N'wf_context' GO EXEC sp_addextendedproperty @@ -2281,6 +2305,7 @@ executor_timeout int NOT NULL DEFAULT 0, description nvarchar(256) NOT NULL DEFAULT '', flow_info nvarchar(max) NULL DEFAULT NULL, + wf_context nvarchar(max) NULL DEFAULT NULL, bucket_index int NOT NULL DEFAULT 0, version int NOT NULL, ext_attrs nvarchar(256) NULL DEFAULT '', @@ -2377,6 +2402,13 @@ 'SCHEMA', N'dbo', 'TABLE', N'sj_workflow', 'COLUMN', N'flow_info' +GO + +EXEC sp_addextendedproperty + 'MS_Description', N'涓婁笅鏂�', + 'SCHEMA', N'dbo', + 'TABLE', N'sj_workflow', + 'COLUMN', N'wf_context' GO EXEC sp_addextendedproperty @@ -2590,8 +2622,10 @@ task_batch_status tinyint NOT NULL DEFAULT 0, operation_reason tinyint NOT NULL DEFAULT 0, flow_info nvarchar(max) NULL DEFAULT NULL, + wf_context nvarchar(max) NULL DEFAULT NULL, execution_at bigint NOT NULL DEFAULT 0, ext_attrs nvarchar(256) NULL DEFAULT '', + version int NOT NULL DEFAULT 1, deleted tinyint NOT NULL DEFAULT 0, create_dt datetime2 NOT NULL DEFAULT CURRENT_TIMESTAMP, update_dt datetime2 NOT NULL DEFAULT CURRENT_TIMESTAMP @@ -2655,6 +2689,13 @@ GO EXEC sp_addextendedproperty + 'MS_Description', N'鍏ㄥ眬涓婁笅鏂�', + 'SCHEMA', N'dbo', + 'TABLE', N'sj_workflow_task_batch', + 'COLUMN', N'wf_context' +GO + +EXEC sp_addextendedproperty 'MS_Description', N'浠诲姟鎵ц鏃堕棿', 'SCHEMA', N'dbo', 'TABLE', N'sj_workflow_task_batch', @@ -2669,6 +2710,13 @@ GO EXEC sp_addextendedproperty + 'MS_Description', N'鐗堟湰鍙�', + 'SCHEMA', N'dbo', + 'TABLE', N'sj_workflow_task_batch', + 'COLUMN', N'version' +GO + +EXEC sp_addextendedproperty 'MS_Description', N'閫昏緫鍒犻櫎 1銆佸垹闄�', 'SCHEMA', N'dbo', 'TABLE', N'sj_workflow_task_batch', -- Gitblit v1.9.3