Kaynağa Gözat

定时任务模块独立fs-task,总后台做统一管理调度中心

zyp 1 hafta önce
ebeveyn
işleme
e39dbb1af0
100 değiştirilmiş dosya ile 7467 ekleme ve 11073 silme
  1. 77 0
      docs/fs-task模块说明.md
  2. 6936 0
      effective-fs-service.xml
  3. 3 5
      fs-admin-saas/pom.xml
  4. 0 2
      fs-admin-saas/src/main/java/com/fs/FsSaasAdminApplication.java
  5. 0 20
      fs-admin-saas/src/main/java/com/fs/hisStore/task/CrmTask.java
  6. 0 110
      fs-admin-saas/src/main/java/com/fs/hisStore/task/ErpTask.java
  7. 0 30
      fs-admin-saas/src/main/java/com/fs/hisStore/task/ExpressTask.java
  8. 0 677
      fs-admin-saas/src/main/java/com/fs/hisStore/task/LiveTask.java
  9. 0 723
      fs-admin-saas/src/main/java/com/fs/hisStore/task/MallStoreTask.java
  10. 0 19
      fs-admin-saas/src/main/java/com/fs/hisStore/task/stats/FsStatsMemberDailyTask.java
  11. 0 50
      fs-admin-saas/src/main/java/com/fs/task/SgTestController.java
  12. 14 1
      fs-admin/pom.xml
  13. 0 2
      fs-admin/src/main/java/com/fs/FSApplication.java
  14. 113 0
      fs-admin/src/main/java/com/fs/admin/controller/monitor/TenantJobController.java
  15. 85 28
      fs-framework/src/main/java/com/fs/framework/task/TenantTaskRunner.java
  16. 13 8
      fs-quartz/src/main/java/com/fs/quartz/mapper/SysJobMapper.java
  17. 19 13
      fs-quartz/src/main/java/com/fs/quartz/service/impl/SysJobServiceImpl.java
  18. 15 11
      fs-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml
  19. 0 14
      fs-qw-task/src/main/java/com/fs/FSServletInitializer.java
  20. 0 24
      fs-qw-task/src/main/java/com/fs/FsQwTaskApplication.java
  21. 0 19
      fs-qw-task/src/main/java/com/fs/app/controller/VoiceController.java
  22. 0 51
      fs-qw-task/src/main/java/com/fs/app/exception/FSException.java
  23. 0 81
      fs-qw-task/src/main/java/com/fs/app/exception/FSExceptionHandler.java
  24. 0 199
      fs-qw-task/src/main/java/com/fs/app/task/TenantTaskRunner.java
  25. 0 55
      fs-qw-task/src/main/java/com/fs/app/task/UserCourseWatchCountTask.java
  26. 0 171
      fs-qw-task/src/main/java/com/fs/framework/aspectj/DataScopeAspect.java
  27. 0 73
      fs-qw-task/src/main/java/com/fs/framework/aspectj/DataSourceAspect.java
  28. 0 219
      fs-qw-task/src/main/java/com/fs/framework/aspectj/LogAspect.java
  29. 0 117
      fs-qw-task/src/main/java/com/fs/framework/aspectj/RateLimiterAspect.java
  30. 0 31
      fs-qw-task/src/main/java/com/fs/framework/config/ApplicationConfig.java
  31. 0 58
      fs-qw-task/src/main/java/com/fs/framework/config/ArrayStringTypeHandler.java
  32. 0 85
      fs-qw-task/src/main/java/com/fs/framework/config/CaptchaConfig.java
  33. 0 89
      fs-qw-task/src/main/java/com/fs/framework/config/DataSourceConfig.java
  34. 0 123
      fs-qw-task/src/main/java/com/fs/framework/config/DruidConfig.java
  35. 0 72
      fs-qw-task/src/main/java/com/fs/framework/config/FastJson2JsonRedisSerializer.java
  36. 0 59
      fs-qw-task/src/main/java/com/fs/framework/config/FilterConfig.java
  37. 0 76
      fs-qw-task/src/main/java/com/fs/framework/config/KaptchaTextCreator.java
  38. 0 150
      fs-qw-task/src/main/java/com/fs/framework/config/MyBatisConfig.java
  39. 0 76
      fs-qw-task/src/main/java/com/fs/framework/config/ResourcesConfig.java
  40. 0 11
      fs-qw-task/src/main/java/com/fs/framework/config/RetryConfig.java
  41. 0 157
      fs-qw-task/src/main/java/com/fs/framework/config/SecurityConfig.java
  42. 0 33
      fs-qw-task/src/main/java/com/fs/framework/config/ServerConfig.java
  43. 0 121
      fs-qw-task/src/main/java/com/fs/framework/config/SwaggerConfig.java
  44. 0 10
      fs-qw-task/src/main/java/com/fs/framework/config/TenantPrincipal.java
  45. 0 115
      fs-qw-task/src/main/java/com/fs/framework/config/ThreadPoolConfig.java
  46. 0 77
      fs-qw-task/src/main/java/com/fs/framework/config/properties/DruidProperties.java
  47. 0 27
      fs-qw-task/src/main/java/com/fs/framework/datasource/DynamicDataSource.java
  48. 0 45
      fs-qw-task/src/main/java/com/fs/framework/datasource/DynamicDataSourceContextHolder.java
  49. 0 71
      fs-qw-task/src/main/java/com/fs/framework/datasource/TenantDataSourceManager.java
  50. 0 115
      fs-qw-task/src/main/java/com/fs/framework/exception/GlobalExceptionHandler.java
  51. 0 56
      fs-qw-task/src/main/java/com/fs/framework/interceptor/RepeatSubmitInterceptor.java
  52. 0 126
      fs-qw-task/src/main/java/com/fs/framework/interceptor/impl/SameUrlDataInterceptor.java
  53. 0 56
      fs-qw-task/src/main/java/com/fs/framework/manager/AsyncManager.java
  54. 0 40
      fs-qw-task/src/main/java/com/fs/framework/manager/ShutdownManager.java
  55. 0 106
      fs-qw-task/src/main/java/com/fs/framework/manager/factory/AsyncFactory.java
  56. 0 69
      fs-qw-task/src/main/java/com/fs/framework/security/LoginBody.java
  57. 0 255
      fs-qw-task/src/main/java/com/fs/framework/security/LoginUser.java
  58. 0 89
      fs-qw-task/src/main/java/com/fs/framework/security/SecurityUtils.java
  59. 0 47
      fs-qw-task/src/main/java/com/fs/framework/security/filter/JwtAuthenticationTokenFilter.java
  60. 0 35
      fs-qw-task/src/main/java/com/fs/framework/security/handle/AuthenticationEntryPointImpl.java
  61. 0 54
      fs-qw-task/src/main/java/com/fs/framework/security/handle/LogoutSuccessHandlerImpl.java
  62. 0 93
      fs-qw-task/src/main/java/com/fs/framework/service/CompanyLoginService.java
  63. 0 66
      fs-qw-task/src/main/java/com/fs/framework/service/CompanyPermissionService.java
  64. 0 170
      fs-qw-task/src/main/java/com/fs/framework/service/PermissionService.java
  65. 0 236
      fs-qw-task/src/main/java/com/fs/framework/service/TokenService.java
  66. 0 75
      fs-qw-task/src/main/java/com/fs/framework/service/UserDetailsServiceImpl.java
  67. 0 1
      fs-qw-task/src/main/resources/META-INF/spring-devtools.properties
  68. 0 21
      fs-qw-task/src/main/resources/application.yml
  69. 0 2
      fs-qw-task/src/main/resources/banner.txt
  70. 0 37
      fs-qw-task/src/main/resources/i18n/messages.properties
  71. 0 19
      fs-qw-task/src/main/resources/mybatis/mybatis-config.xml
  72. 0 26
      fs-service/src/main/java/com/fs/ad/controller/task/BaiduTask.java
  73. 0 2
      fs-service/src/main/java/com/fs/company/service/workflow/event/UserEventMonitor.java
  74. 1 3
      fs-service/src/main/java/com/fs/company/service/workflow/evolution/impl/EvolutionSchedulerImpl.java
  75. 0 2
      fs-service/src/main/java/com/fs/company/service/workflow/heartbeat/impl/HeartbeatSchedulerImpl.java
  76. 0 17
      fs-service/src/main/java/com/fs/course/task/CourseStatisticsTask.java
  77. 0 37
      fs-service/src/main/java/com/fs/course/task/RedPacketLogsTask.java
  78. 0 257
      fs-service/src/main/java/com/fs/course/task/VideoTask.java
  79. 0 2
      fs-service/src/main/java/com/fs/erp/service/impl/JstTokenService.java
  80. 0 3
      fs-service/src/main/java/com/fs/fastgptApi/util/EventLogUtils.java
  81. 24 27
      fs-service/src/main/java/com/fs/framework/datasource/DynamicDataSource.java
  82. 42 44
      fs-service/src/main/java/com/fs/framework/datasource/DynamicDataSourceContextHolder.java
  83. 122 144
      fs-service/src/main/java/com/fs/framework/datasource/TenantDataSourceManager.java
  84. 0 127
      fs-service/src/main/java/com/fs/his/task/BillTask.java
  85. 0 135
      fs-service/src/main/java/com/fs/his/task/CompanyBalanceTask.java
  86. 0 62
      fs-service/src/main/java/com/fs/his/task/FsCourseTask.java
  87. 0 480
      fs-service/src/main/java/com/fs/his/task/NetMedicalService.java
  88. 0 29
      fs-service/src/main/java/com/fs/his/task/PeriodTask.java
  89. 0 21
      fs-service/src/main/java/com/fs/his/task/SendRedPacketTask.java
  90. 0 1902
      fs-service/src/main/java/com/fs/his/task/Task.java
  91. 0 56
      fs-service/src/main/java/com/fs/his/task/WatchCourseTask.java
  92. 0 20
      fs-service/src/main/java/com/fs/his/task/trafficlog/TrafficlogTask.java
  93. 0 20
      fs-service/src/main/java/com/fs/hisStore/task/CrmTask.java
  94. 0 110
      fs-service/src/main/java/com/fs/hisStore/task/ErpTask.java
  95. 0 30
      fs-service/src/main/java/com/fs/hisStore/task/ExpressTask.java
  96. 0 667
      fs-service/src/main/java/com/fs/hisStore/task/LiveTask.java
  97. 0 713
      fs-service/src/main/java/com/fs/hisStore/task/MallStoreTask.java
  98. 0 19
      fs-service/src/main/java/com/fs/hisStore/task/stats/FsStatsMemberDailyTask.java
  99. 3 7
      fs-service/src/main/java/com/fs/proxy/service/impl/PlatformStatisticsServiceImpl.java
  100. 0 135
      fs-service/src/main/java/com/fs/proxy/task/AccountFeeTask.java

+ 77 - 0
docs/fs-task模块说明.md

@@ -0,0 +1,77 @@
+# fs-task 定时任务模块说明
+
+## 架构
+
+| 模块 | 职责 |
+|------|------|
+| **fs-quartz** | Quartz 框架、sys_job CRUD、ScheduleConfig |
+| **fs-task** | 所有 Task Bean(原 admin-saas / fs-qw-task / fs-service 任务类) |
+| **fs-admin** | 唯一调度入口:引入 fs-quartz + fs-task,无 @EnableScheduling |
+| **fs-admin-saas** | 纯 API:引入 fs-task 仅用于 Controller 手动触发,无 fs-quartz、无 @Scheduled |
+
+## 迁移内容
+
+- fs-admin-saas/src/.../task/** 迁移到 fs-task
+- fs-qw-task/src/.../app/task/**、taskService/** 迁移到 fs-task
+- fs-service 内 com.fs.*.task 包已删除(避免与 fs-task 类重复)
+- 所有 @Scheduled 已移除,改由 sys_job + Quartz 调度
+
+## 部署步骤
+
+1. 编译:mvn -pl fs-admin -am package -DskipTests
+2. 执行菜单 SQL:sql/admin_sys_menu_job.sql(总后台 sys_menu)
+3. 执行任务种子 SQL:sql/fs_task_sys_job_seed.sql(通用任务,按需将 status 改为 0 启用)
+4. 执行企微任务 SQL:sql/fs_qw_task_sys_job_seed.sql(28 条,job_group=QW_TASK)
+5. 在 adminUI 系统监控 - 定时任务 管理任务;新增时可点 Bean注册表 选用 invoke_target
+
+## 调用方式
+
+Quartz 通过 sys_job.invoke_target 调用 Spring Bean 方法,格式示例:
+
+``
+qwTask.addTag()
+task.deleteUserOperationLog()
+lobsterBridgeDataSyncService.syncLobsterBridgeData()
+platformStatisticsServiceImpl.executeHourlyStats()
+``
+
+在 adminUI 定时任务页面点击 Bean注册表,可查看 fs-task 中所有可调度方法。
+
+## 注意事项
+
+- 原 @Scheduled(fixedDelay=...) 需在 sys_job 中改用近似 cron 表达式
+- EventLogUtils 200ms 轮询类任务建议保留独立线程或单独评估,不宜直接配 Quartz
+- fs-qw-task 独立进程已去除 @EnableScheduling,任务统一由 fs-admin 调度
+- seed SQL 中任务默认 status=1(暂停),确认无误后改为 0 才会执行
+
+## 相关文件
+
+| 文件 | 说明 |
+|------|------|
+| fs-task/pom.xml | 任务模块依赖 |
+| fs-task/.../TaskModuleConfiguration.java | Task Bean 包扫描配置 |
+| fs-task/.../TaskRegistryController.java | Bean 注册表 API |
+| sql/admin_sys_menu_job.sql | 总后台定时任务菜单 |
+| sql/fs_task_sys_job_seed.sql | 通用任务 sys_job 种子数据 |
+| sql/fs_qw_task_sys_job_seed.sql | 企微 fs-qw-task 迁移任务(28 条) |
+| sql/generate_qw_task_sys_job_seed.py | 重新生成企微任务 SQL |
+
+## 独立运行 fs-task(可选,用于手动触发任务调试)
+```bash
+cd fs-task
+mvn clean package -DskipTests
+java -jar target/fs-task.jar
+# 默认端口 8018,可通过 application.yml 修改
+# 访问 http://localhost:8018/app/common/test 等手动接口
+```
+
+## 集成到 fs-admin
+fs-admin 的 pom 依赖 fs-task(任务 Bean 由 TaskModuleConfiguration 自动扫描注册,Bean 注册表 /monitor/taskRegistry 和 /app/common 手动调试接口可用)。
+
+fs-admin-saas 已移除对 fs-task 的直接依赖(原 SgTestController 等测试入口已随任务类迁移到 fs-task 模块内部;如需保留特定测试端点,可在 fs-task 内添加或通过 HTTP 远程调用旧 taskApi)。
+
+相关文件:
+- FsTaskApplication.java (启动类,支持独立调试运行)
+- TaskPackages.java + TaskModuleConfiguration + TaskRegistryService (统一任务包扫描列表,避免不一致)
+- 标准配置文件(application*.yml, logback.xml 等,参考其他模块完善)
+- META-INF/spring/.../AutoConfiguration.imports (自动加载配置)

+ 6936 - 0
effective-fs-service.xml

@@ -0,0 +1,6936 @@
+[INFO] Scanning for projects...
+[WARNING] 
+[WARNING] Some problems were encountered while building the effective model for com.fs:fs-service:jar:1.1.0
+[WARNING] 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: org.mapstruct:mapstruct:jar -> duplicate declaration of version ${org.mapstruct.version} @ line 313, column 21
+[WARNING] 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: org.mapstruct:mapstruct-processor:jar -> duplicate declaration of version ${org.mapstruct.version} @ line 318, column 21
+[WARNING] 
+[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
+[WARNING] 
+[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
+[WARNING] 
+[INFO] 
+[INFO] -------------------------< com.fs:fs-service >--------------------------
+[INFO] Building fs-service 1.1.0
+[INFO] --------------------------------[ jar ]---------------------------------
+[INFO] 
+[INFO] --- maven-help-plugin:3.5.1:effective-pom (default-cli) @ fs-service ---
+[INFO] 
+Effective POMs, after inheritance, interpolation, and profiles are applied:
+
+<?xml version="1.0" encoding="GBK"?>
+<!-- ====================================================================== -->
+<!--                                                                        -->
+<!-- Generated by Maven Help Plugin                                         -->
+<!-- See: https://maven.apache.org/plugins/maven-help-plugin/               -->
+<!--                                                                        -->
+<!-- ====================================================================== -->
+<!-- ====================================================================== -->
+<!--                                                                        -->
+<!-- Effective POM for project 'com.fs:fs-service:jar:1.1.0'                -->
+<!--                                                                        -->
+<!-- ====================================================================== -->
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.fs</groupId>
+    <artifactId>fs</artifactId>
+    <version>1.1.0</version>
+  </parent>
+  <groupId>com.fs</groupId>
+  <artifactId>fs-service</artifactId>
+  <version>1.1.0</version>
+  <description>service模块</description>
+  <properties>
+    <bitwalker.version>1.21</bitwalker.version>
+    <commons.collections.version>3.2.2</commons.collections.version>
+    <commons.fileupload.version>1.4</commons.fileupload.version>
+    <commons.io.version>2.11.0</commons.io.version>
+    <druid.version>1.2.6</druid.version>
+    <fastjson.version>1.2.76</fastjson.version>
+    <fs.version>1.1.0</fs.version>
+    <gson-version>2.10</gson-version>
+    <ijpay-version>2.7.8</ijpay-version>
+    <java.version>17</java.version>
+    <jna.version>5.8.0</jna.version>
+    <jwt.version>0.9.1</jwt.version>
+    <kaptcha.version>2.3.2</kaptcha.version>
+    <lombok.version>1.18.32</lombok.version>
+    <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
+    <mybatis-spring-boot.version>2.3.2</mybatis-spring-boot.version>
+    <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
+    <oshi.version>5.8.0</oshi.version>
+    <pagehelper.boot.version>1.4.7</pagehelper.boot.version>
+    <poi.version>4.1.2</poi.version>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <swagger.version>2.9.2</swagger.version>
+    <velocity.version>1.7</velocity.version>
+    <weixin-java-cp.version>4.7.0</weixin-java-cp.version>
+    <weixin-java-miniapp.version>4.7.0</weixin-java-miniapp.version>
+    <weixin-java-mp.version>4.7.0</weixin-java-mp.version>
+  </properties>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>com.google.code.gson</groupId>
+        <artifactId>gson</artifactId>
+        <version>2.10</version>
+      </dependency>
+      <dependency>
+        <groupId>mysql</groupId>
+        <artifactId>mysql-connector-java</artifactId>
+        <version>8.0.33</version>
+      </dependency>
+      <dependency>
+        <groupId>com.alibaba</groupId>
+        <artifactId>druid-spring-boot-starter</artifactId>
+        <version>1.2.6</version>
+      </dependency>
+      <dependency>
+        <groupId>eu.bitwalker</groupId>
+        <artifactId>UserAgentUtils</artifactId>
+        <version>1.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mybatis.spring.boot</groupId>
+        <artifactId>mybatis-spring-boot-starter</artifactId>
+        <version>2.3.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.pagehelper</groupId>
+        <artifactId>pagehelper-spring-boot-starter</artifactId>
+        <version>1.4.7</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.oshi</groupId>
+        <artifactId>oshi-core</artifactId>
+        <version>5.8.0</version>
+      </dependency>
+      <dependency>
+        <groupId>net.java.dev.jna</groupId>
+        <artifactId>jna</artifactId>
+        <version>5.8.0</version>
+      </dependency>
+      <dependency>
+        <groupId>net.java.dev.jna</groupId>
+        <artifactId>jna-platform</artifactId>
+        <version>5.8.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.springfox</groupId>
+        <artifactId>springfox-swagger2</artifactId>
+        <version>2.9.2</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>swagger-annotations</artifactId>
+            <groupId>io.swagger</groupId>
+          </exclusion>
+          <exclusion>
+            <artifactId>swagger-models</artifactId>
+            <groupId>io.swagger</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>io.springfox</groupId>
+        <artifactId>springfox-swagger-ui</artifactId>
+        <version>2.9.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.xiaoymin</groupId>
+        <artifactId>swagger-bootstrap-ui</artifactId>
+        <version>1.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <version>2.11.0</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-fileupload</groupId>
+        <artifactId>commons-fileupload</artifactId>
+        <version>1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.poi</groupId>
+        <artifactId>poi-ooxml</artifactId>
+        <version>4.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.velocity</groupId>
+        <artifactId>velocity</artifactId>
+        <version>1.7</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-collections</artifactId>
+            <groupId>commons-collections</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>commons-collections</groupId>
+        <artifactId>commons-collections</artifactId>
+        <version>3.2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.alibaba</groupId>
+        <artifactId>fastjson</artifactId>
+        <version>1.2.76</version>
+      </dependency>
+      <dependency>
+        <groupId>io.jsonwebtoken</groupId>
+        <artifactId>jjwt</artifactId>
+        <version>0.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.penggle</groupId>
+        <artifactId>kaptcha</artifactId>
+        <version>2.3.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-quartz</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-task</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-generator</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-framework</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-service</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-wx-ipad-task</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-common</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-repeat-api</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-ipad-task</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fs</groupId>
+        <artifactId>fs-websocket</artifactId>
+        <version>1.1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.javen205</groupId>
+        <artifactId>IJPay-All</artifactId>
+        <version>2.7.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.retry</groupId>
+        <artifactId>spring-retry</artifactId>
+        <version>1.3.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-amqp</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-blueprint</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-broker</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-camel</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-client</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-console</artifactId>
+        <version>5.16.7</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-http</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-jaas</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-jdbc-store</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-jms-pool</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-kahadb-store</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-karaf</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-leveldb-store</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-log4j-appender</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-mqtt</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-openwire-generator</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-openwire-legacy</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-osgi</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-partition</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-pool</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-ra</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-run</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-runtime-config</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-shiro</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-spring</artifactId>
+        <version>5.16.7</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-stomp</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>activemq-web</artifactId>
+        <version>5.16.7</version>
+      </dependency>
+      <dependency>
+        <groupId>antlr</groupId>
+        <artifactId>antlr</artifactId>
+        <version>2.7.7</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.appengine</groupId>
+        <artifactId>appengine-api-1.0-sdk</artifactId>
+        <version>1.9.98</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-amqp-protocol</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-commons</artifactId>
+        <version>2.19.1</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-core-client</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-jdbc-store</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-jms-client</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-jms-server</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-journal</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-quorum-api</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-selector</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-server</artifactId>
+        <version>2.19.1</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.activemq</groupId>
+        <artifactId>artemis-service-extensions</artifactId>
+        <version>2.19.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.aspectj</groupId>
+        <artifactId>aspectjrt</artifactId>
+        <version>1.9.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.aspectj</groupId>
+        <artifactId>aspectjtools</artifactId>
+        <version>1.9.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.aspectj</groupId>
+        <artifactId>aspectjweaver</artifactId>
+        <version>1.9.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.assertj</groupId>
+        <artifactId>assertj-core</artifactId>
+        <version>3.22.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.atomikos</groupId>
+        <artifactId>transactions-jdbc</artifactId>
+        <version>4.0.6</version>
+      </dependency>
+      <dependency>
+        <groupId>com.atomikos</groupId>
+        <artifactId>transactions-jms</artifactId>
+        <version>4.0.6</version>
+      </dependency>
+      <dependency>
+        <groupId>com.atomikos</groupId>
+        <artifactId>transactions-jta</artifactId>
+        <version>4.0.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.awaitility</groupId>
+        <artifactId>awaitility</artifactId>
+        <version>4.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.awaitility</groupId>
+        <artifactId>awaitility-groovy</artifactId>
+        <version>4.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.awaitility</groupId>
+        <artifactId>awaitility-kotlin</artifactId>
+        <version>4.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.awaitility</groupId>
+        <artifactId>awaitility-scala</artifactId>
+        <version>4.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>net.bytebuddy</groupId>
+        <artifactId>byte-buddy</artifactId>
+        <version>1.12.23</version>
+      </dependency>
+      <dependency>
+        <groupId>net.bytebuddy</groupId>
+        <artifactId>byte-buddy-agent</artifactId>
+        <version>1.12.23</version>
+      </dependency>
+      <dependency>
+        <groupId>org.cache2k</groupId>
+        <artifactId>cache2k-api</artifactId>
+        <version>2.6.1.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.cache2k</groupId>
+        <artifactId>cache2k-config</artifactId>
+        <version>2.6.1.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.cache2k</groupId>
+        <artifactId>cache2k-core</artifactId>
+        <version>2.6.1.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.cache2k</groupId>
+        <artifactId>cache2k-jcache</artifactId>
+        <version>2.6.1.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.cache2k</groupId>
+        <artifactId>cache2k-micrometer</artifactId>
+        <version>2.6.1.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.cache2k</groupId>
+        <artifactId>cache2k-spring</artifactId>
+        <version>2.6.1.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.ben-manes.caffeine</groupId>
+        <artifactId>caffeine</artifactId>
+        <version>2.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.ben-manes.caffeine</groupId>
+        <artifactId>guava</artifactId>
+        <version>2.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.ben-manes.caffeine</groupId>
+        <artifactId>jcache</artifactId>
+        <version>2.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.ben-manes.caffeine</groupId>
+        <artifactId>simulator</artifactId>
+        <version>2.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-core</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml</groupId>
+        <artifactId>classmate</artifactId>
+        <version>1.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-codec</groupId>
+        <artifactId>commons-codec</artifactId>
+        <version>1.15</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-dbcp2</artifactId>
+        <version>2.9.0</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-lang3</artifactId>
+        <version>3.12.0</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-pool</groupId>
+        <artifactId>commons-pool</artifactId>
+        <version>1.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-pool2</artifactId>
+        <version>2.11.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.couchbase.client</groupId>
+        <artifactId>java-client</artifactId>
+        <version>3.3.4</version>
+      </dependency>
+      <dependency>
+        <groupId>com.ibm.db2</groupId>
+        <artifactId>jcc</artifactId>
+        <version>11.5.9.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.spring.gradle</groupId>
+        <artifactId>dependency-management-plugin</artifactId>
+        <version>1.0.15.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.derby</groupId>
+        <artifactId>derby</artifactId>
+        <version>10.14.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.derby</groupId>
+        <artifactId>derbyclient</artifactId>
+        <version>10.14.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.derby</groupId>
+        <artifactId>derbynet</artifactId>
+        <version>10.14.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.derby</groupId>
+        <artifactId>derbyoptionaltools</artifactId>
+        <version>10.14.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.derby</groupId>
+        <artifactId>derbytools</artifactId>
+        <version>10.14.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>net.sf.ehcache</groupId>
+        <artifactId>ehcache</artifactId>
+        <version>2.10.9.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.ehcache</groupId>
+        <artifactId>ehcache</artifactId>
+        <version>3.10.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.ehcache</groupId>
+        <artifactId>ehcache-clustered</artifactId>
+        <version>3.10.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.ehcache</groupId>
+        <artifactId>ehcache-transactions</artifactId>
+        <version>3.10.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.elasticsearch</groupId>
+        <artifactId>elasticsearch</artifactId>
+        <version>7.17.15</version>
+      </dependency>
+      <dependency>
+        <groupId>org.elasticsearch.client</groupId>
+        <artifactId>transport</artifactId>
+        <version>7.17.15</version>
+      </dependency>
+      <dependency>
+        <groupId>org.elasticsearch.client</groupId>
+        <artifactId>elasticsearch-rest-client</artifactId>
+        <version>7.17.15</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.elasticsearch.client</groupId>
+        <artifactId>elasticsearch-rest-client-sniffer</artifactId>
+        <version>7.17.15</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.elasticsearch.client</groupId>
+        <artifactId>elasticsearch-rest-high-level-client</artifactId>
+        <version>7.17.15</version>
+      </dependency>
+      <dependency>
+        <groupId>org.elasticsearch.distribution.integ-test-zip</groupId>
+        <artifactId>elasticsearch</artifactId>
+        <version>7.17.15</version>
+        <type>zip</type>
+      </dependency>
+      <dependency>
+        <groupId>org.elasticsearch.plugin</groupId>
+        <artifactId>transport-netty4-client</artifactId>
+        <version>7.17.15</version>
+      </dependency>
+      <dependency>
+        <groupId>de.flapdoodle.embed</groupId>
+        <artifactId>de.flapdoodle.embed.mongo</artifactId>
+        <version>3.4.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.flywaydb</groupId>
+        <artifactId>flyway-core</artifactId>
+        <version>8.5.13</version>
+      </dependency>
+      <dependency>
+        <groupId>org.flywaydb</groupId>
+        <artifactId>flyway-firebird</artifactId>
+        <version>8.5.13</version>
+      </dependency>
+      <dependency>
+        <groupId>org.flywaydb</groupId>
+        <artifactId>flyway-mysql</artifactId>
+        <version>8.5.13</version>
+      </dependency>
+      <dependency>
+        <groupId>org.flywaydb</groupId>
+        <artifactId>flyway-sqlserver</artifactId>
+        <version>8.5.13</version>
+      </dependency>
+      <dependency>
+        <groupId>org.freemarker</groupId>
+        <artifactId>freemarker</artifactId>
+        <version>2.3.32</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish</groupId>
+        <artifactId>jakarta.el</artifactId>
+        <version>3.0.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>codemodel</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>codemodel-annotation-compiler</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>jaxb-jxc</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>jaxb-runtime</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>jaxb-xjc</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>txw2</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>txwc2</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jaxb</groupId>
+        <artifactId>xsom</artifactId>
+        <version>2.3.9</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.web</groupId>
+        <artifactId>jakarta.servlet.jsp.jstl</artifactId>
+        <version>1.2.6</version>
+      </dependency>
+      <dependency>
+        <groupId>com.graphql-java</groupId>
+        <artifactId>graphql-java</artifactId>
+        <version>18.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.h2database</groupId>
+        <artifactId>h2</artifactId>
+        <version>2.1.214</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest</artifactId>
+        <version>2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-core</artifactId>
+        <version>2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hamcrest</groupId>
+        <artifactId>hamcrest-library</artifactId>
+        <version>2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.hazelcast</groupId>
+        <artifactId>hazelcast</artifactId>
+        <version>5.1.7</version>
+      </dependency>
+      <dependency>
+        <groupId>com.hazelcast</groupId>
+        <artifactId>hazelcast-spring</artifactId>
+        <version>5.1.7</version>
+      </dependency>
+      <dependency>
+        <groupId>com.hazelcast</groupId>
+        <artifactId>hazelcast-hibernate52</artifactId>
+        <version>2.2.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.hazelcast</groupId>
+        <artifactId>hazelcast-hibernate53</artifactId>
+        <version>2.2.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-c3p0</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-core</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-ehcache</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-entitymanager</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-envers</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-hikaricp</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-java8</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-jcache</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-jpamodelgen</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-micrometer</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-proxool</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-spatial</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-testing</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-vibur</artifactId>
+        <version>5.6.15.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate.validator</groupId>
+        <artifactId>hibernate-validator</artifactId>
+        <version>6.2.5.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hibernate.validator</groupId>
+        <artifactId>hibernate-validator-annotation-processor</artifactId>
+        <version>6.2.5.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>com.zaxxer</groupId>
+        <artifactId>HikariCP</artifactId>
+        <version>4.0.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.hsqldb</groupId>
+        <artifactId>hsqldb</artifactId>
+        <version>2.5.2</version>
+      </dependency>
+      <dependency>
+        <groupId>net.sourceforge.htmlunit</groupId>
+        <artifactId>htmlunit</artifactId>
+        <version>2.60.0</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpasyncclient</artifactId>
+        <version>4.1.5</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>fluent-hc</artifactId>
+        <version>4.5.14</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>4.5.14</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>commons-logging</artifactId>
+            <groupId>commons-logging</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient-cache</artifactId>
+        <version>4.5.14</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient-osgi</artifactId>
+        <version>4.5.14</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient-win</artifactId>
+        <version>4.5.14</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpmime</artifactId>
+        <version>4.5.14</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents.client5</groupId>
+        <artifactId>httpclient5</artifactId>
+        <version>5.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents.client5</groupId>
+        <artifactId>httpclient5-cache</artifactId>
+        <version>5.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents.client5</groupId>
+        <artifactId>httpclient5-fluent</artifactId>
+        <version>5.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents.client5</groupId>
+        <artifactId>httpclient5-win</artifactId>
+        <version>5.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpcore</artifactId>
+        <version>4.4.16</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpcore-nio</artifactId>
+        <version>4.4.16</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents.core5</groupId>
+        <artifactId>httpcore5</artifactId>
+        <version>5.1.5</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents.core5</groupId>
+        <artifactId>httpcore5-h2</artifactId>
+        <version>5.1.5</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents.core5</groupId>
+        <artifactId>httpcore5-reactive</artifactId>
+        <version>5.1.5</version>
+      </dependency>
+      <dependency>
+        <groupId>org.influxdb</groupId>
+        <artifactId>influxdb-java</artifactId>
+        <version>2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>com.sun.activation</groupId>
+        <artifactId>jakarta.activation</artifactId>
+        <version>1.2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.activation</groupId>
+        <artifactId>jakarta.activation-api</artifactId>
+        <version>1.2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.annotation</groupId>
+        <artifactId>jakarta.annotation-api</artifactId>
+        <version>1.3.5</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.jms</groupId>
+        <artifactId>jakarta.jms-api</artifactId>
+        <version>2.0.3</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.json</groupId>
+        <artifactId>jakarta.json-api</artifactId>
+        <version>1.1.6</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.json.bind</groupId>
+        <artifactId>jakarta.json.bind-api</artifactId>
+        <version>1.0.2</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.mail</groupId>
+        <artifactId>jakarta.mail-api</artifactId>
+        <version>1.6.7</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.management.j2ee</groupId>
+        <artifactId>jakarta.management.j2ee-api</artifactId>
+        <version>1.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.persistence</groupId>
+        <artifactId>jakarta.persistence-api</artifactId>
+        <version>2.2.3</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.servlet</groupId>
+        <artifactId>jakarta.servlet-api</artifactId>
+        <version>4.0.4</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.servlet.jsp.jstl</groupId>
+        <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
+        <version>1.2.7</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.transaction</groupId>
+        <artifactId>jakarta.transaction-api</artifactId>
+        <version>1.3.3</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.validation</groupId>
+        <artifactId>jakarta.validation-api</artifactId>
+        <version>2.0.2</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.websocket</groupId>
+        <artifactId>jakarta.websocket-api</artifactId>
+        <version>1.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.ws.rs</groupId>
+        <artifactId>jakarta.ws.rs-api</artifactId>
+        <version>2.1.6</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.xml.bind</groupId>
+        <artifactId>jakarta.xml.bind-api</artifactId>
+        <version>2.3.3</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.xml.soap</groupId>
+        <artifactId>jakarta.xml.soap-api</artifactId>
+        <version>1.4.2</version>
+      </dependency>
+      <dependency>
+        <groupId>jakarta.xml.ws</groupId>
+        <artifactId>jakarta.xml.ws-api</artifactId>
+        <version>2.3.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.janino</groupId>
+        <artifactId>commons-compiler</artifactId>
+        <version>3.1.10</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.janino</groupId>
+        <artifactId>commons-compiler-jdk</artifactId>
+        <version>3.1.10</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.janino</groupId>
+        <artifactId>janino</artifactId>
+        <version>3.1.10</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.activation</groupId>
+        <artifactId>javax.activation-api</artifactId>
+        <version>1.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.annotation</groupId>
+        <artifactId>javax.annotation-api</artifactId>
+        <version>1.3.2</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.cache</groupId>
+        <artifactId>cache-api</artifactId>
+        <version>1.1.1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.xml.bind</groupId>
+        <artifactId>jaxb-api</artifactId>
+        <version>2.3.1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.xml.ws</groupId>
+        <artifactId>jaxws-api</artifactId>
+        <version>2.3.1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.jms</groupId>
+        <artifactId>javax.jms-api</artifactId>
+        <version>2.0.1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.json</groupId>
+        <artifactId>javax.json-api</artifactId>
+        <version>1.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.json.bind</groupId>
+        <artifactId>javax.json.bind-api</artifactId>
+        <version>1.0</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.mail</groupId>
+        <artifactId>javax.mail-api</artifactId>
+        <version>1.6.2</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.money</groupId>
+        <artifactId>money-api</artifactId>
+        <version>1.1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.persistence</groupId>
+        <artifactId>javax.persistence-api</artifactId>
+        <version>2.2</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.transaction</groupId>
+        <artifactId>javax.transaction-api</artifactId>
+        <version>1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.validation</groupId>
+        <artifactId>validation-api</artifactId>
+        <version>2.0.1.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.websocket</groupId>
+        <artifactId>javax.websocket-api</artifactId>
+        <version>1.1</version>
+      </dependency>
+      <dependency>
+        <groupId>jaxen</groupId>
+        <artifactId>jaxen</artifactId>
+        <version>1.2.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.firebirdsql.jdbc</groupId>
+        <artifactId>jaybird</artifactId>
+        <version>4.0.9.java8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.firebirdsql.jdbc</groupId>
+        <artifactId>jaybird-jdk18</artifactId>
+        <version>4.0.9.java8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jboss.logging</groupId>
+        <artifactId>jboss-logging</artifactId>
+        <version>3.4.3.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jdom</groupId>
+        <artifactId>jdom2</artifactId>
+        <version>2.0.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>redis.clients</groupId>
+        <artifactId>jedis</artifactId>
+        <version>3.8.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mortbay.jasper</groupId>
+        <artifactId>apache-el</artifactId>
+        <version>9.0.52</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.orbit</groupId>
+        <artifactId>javax.servlet.jsp</artifactId>
+        <version>2.2.0.v201112011158</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-reactive-httpclient</artifactId>
+        <version>1.1.15</version>
+      </dependency>
+      <dependency>
+        <groupId>com.samskivert</groupId>
+        <artifactId>jmustache</artifactId>
+        <version>1.15</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.johnzon</groupId>
+        <artifactId>johnzon-core</artifactId>
+        <version>1.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.johnzon</groupId>
+        <artifactId>johnzon-jaxrs</artifactId>
+        <version>1.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.johnzon</groupId>
+        <artifactId>johnzon-jsonb</artifactId>
+        <version>1.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.johnzon</groupId>
+        <artifactId>johnzon-jsonb-extras</artifactId>
+        <version>1.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.johnzon</groupId>
+        <artifactId>johnzon-jsonschema</artifactId>
+        <version>1.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.johnzon</groupId>
+        <artifactId>johnzon-mapper</artifactId>
+        <version>1.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.johnzon</groupId>
+        <artifactId>johnzon-websocket</artifactId>
+        <version>1.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jolokia</groupId>
+        <artifactId>jolokia-core</artifactId>
+        <version>1.7.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jooq</groupId>
+        <artifactId>jooq</artifactId>
+        <version>3.14.16</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jooq</groupId>
+        <artifactId>jooq-codegen</artifactId>
+        <version>3.14.16</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jooq</groupId>
+        <artifactId>jooq-kotlin</artifactId>
+        <version>3.14.16</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jooq</groupId>
+        <artifactId>jooq-meta</artifactId>
+        <version>3.14.16</version>
+      </dependency>
+      <dependency>
+        <groupId>com.jayway.jsonpath</groupId>
+        <artifactId>json-path</artifactId>
+        <version>2.7.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.jayway.jsonpath</groupId>
+        <artifactId>json-path-assert</artifactId>
+        <version>2.7.0</version>
+      </dependency>
+      <dependency>
+        <groupId>net.minidev</groupId>
+        <artifactId>json-smart</artifactId>
+        <version>2.4.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.skyscreamer</groupId>
+        <artifactId>jsonassert</artifactId>
+        <version>1.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>jstl</artifactId>
+        <version>1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>net.sourceforge.jtds</groupId>
+        <artifactId>jtds</artifactId>
+        <version>1.3.1</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.13.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-api</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-basic-auth-extension</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-file</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-json</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-mirror</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-mirror-client</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-runtime</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>connect-transforms</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>generator</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-clients</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-clients</artifactId>
+        <version>3.1.2</version>
+        <classifier>test</classifier>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-log4j-appender</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-metadata</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-raft</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-server-common</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-server-common</artifactId>
+        <version>3.1.2</version>
+        <classifier>test</classifier>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-shell</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-storage</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-storage-api</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-streams</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-streams-scala_2.12</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-streams-scala_2.13</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-streams-test-utils</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka-tools</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka_2.12</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka_2.12</artifactId>
+        <version>3.1.2</version>
+        <classifier>test</classifier>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka_2.13</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>kafka_2.13</artifactId>
+        <version>3.1.2</version>
+        <classifier>test</classifier>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.kafka</groupId>
+        <artifactId>trogdor</artifactId>
+        <version>3.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>io.lettuce</groupId>
+        <artifactId>lettuce-core</artifactId>
+        <version>6.1.10.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.liquibase</groupId>
+        <artifactId>liquibase-cdi</artifactId>
+        <version>4.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.liquibase</groupId>
+        <artifactId>liquibase-core</artifactId>
+        <version>4.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>ch.qos.logback</groupId>
+        <artifactId>logback-access</artifactId>
+        <version>1.2.12</version>
+      </dependency>
+      <dependency>
+        <groupId>ch.qos.logback</groupId>
+        <artifactId>logback-classic</artifactId>
+        <version>1.2.12</version>
+      </dependency>
+      <dependency>
+        <groupId>ch.qos.logback</groupId>
+        <artifactId>logback-core</artifactId>
+        <version>1.2.12</version>
+      </dependency>
+      <dependency>
+        <groupId>org.projectlombok</groupId>
+        <artifactId>lombok</artifactId>
+        <version>1.18.30</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mariadb.jdbc</groupId>
+        <artifactId>mariadb-java-client</artifactId>
+        <version>3.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-stackdriver</artifactId>
+        <version>1.9.17</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>javax.annotation-api</artifactId>
+            <groupId>javax.annotation</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.mongodb</groupId>
+        <artifactId>bson</artifactId>
+        <version>4.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mongodb</groupId>
+        <artifactId>bson-record-codec</artifactId>
+        <version>4.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mongodb</groupId>
+        <artifactId>mongodb-driver-core</artifactId>
+        <version>4.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mongodb</groupId>
+        <artifactId>mongodb-driver-legacy</artifactId>
+        <version>4.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mongodb</groupId>
+        <artifactId>mongodb-driver-reactivestreams</artifactId>
+        <version>4.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mongodb</groupId>
+        <artifactId>mongodb-driver-sync</artifactId>
+        <version>4.6.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.microsoft.sqlserver</groupId>
+        <artifactId>mssql-jdbc</artifactId>
+        <version>10.2.3.jre8</version>
+      </dependency>
+      <dependency>
+        <groupId>com.mysql</groupId>
+        <artifactId>mysql-connector-j</artifactId>
+        <version>8.0.33</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>protobuf-java</artifactId>
+            <groupId>com.google.protobuf</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>net.sourceforge.nekohtml</groupId>
+        <artifactId>nekohtml</artifactId>
+        <version>1.9.22</version>
+      </dependency>
+      <dependency>
+        <groupId>org.neo4j.driver</groupId>
+        <artifactId>neo4j-java-driver</artifactId>
+        <version>4.4.12</version>
+      </dependency>
+      <dependency>
+        <groupId>org.messaginghub</groupId>
+        <artifactId>pooled-jms</artifactId>
+        <version>1.2.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.postgresql</groupId>
+        <artifactId>postgresql</artifactId>
+        <version>42.3.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.quartz-scheduler</groupId>
+        <artifactId>quartz</artifactId>
+        <version>2.3.2</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>c3p0</artifactId>
+            <groupId>com.mchange</groupId>
+          </exclusion>
+          <exclusion>
+            <artifactId>*</artifactId>
+            <groupId>com.zaxxer</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.quartz-scheduler</groupId>
+        <artifactId>quartz-jobs</artifactId>
+        <version>2.3.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.rabbitmq</groupId>
+        <artifactId>amqp-client</artifactId>
+        <version>5.14.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.rabbitmq</groupId>
+        <artifactId>stream-client</artifactId>
+        <version>0.5.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.reactivestreams</groupId>
+        <artifactId>reactive-streams</artifactId>
+        <version>1.0.4</version>
+      </dependency>
+      <dependency>
+        <groupId>io.reactivex</groupId>
+        <artifactId>rxjava</artifactId>
+        <version>1.3.8</version>
+      </dependency>
+      <dependency>
+        <groupId>io.reactivex</groupId>
+        <artifactId>rxjava-reactive-streams</artifactId>
+        <version>1.2.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.reactivex.rxjava2</groupId>
+        <artifactId>rxjava</artifactId>
+        <version>2.2.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-test</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-test-autoconfigure</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-actuator</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-actuator-autoconfigure</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-autoconfigure</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-autoconfigure-processor</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-buildpack-platform</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-configuration-metadata</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-configuration-processor</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-devtools</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-jarmode-layertools</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-loader</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-loader-tools</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-properties-migrator</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-activemq</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-actuator</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-amqp</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-aop</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-artemis</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-batch</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-cache</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-cassandra</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-cassandra-reactive</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-couchbase</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-couchbase-reactive</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-jdbc</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-jpa</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-ldap</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-mongodb</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-r2dbc</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-redis</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-neo4j</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-rest</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-freemarker</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-graphql</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-groovy-templates</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-hateoas</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-integration</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-jdbc</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-jersey</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-jetty</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-jooq</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-json</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-jta-atomikos</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-log4j2</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-logging</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-mail</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-mustache</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-oauth2-client</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-quartz</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-reactor-netty</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-rsocket</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-security</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-test</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-tomcat</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-undertow</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-validation</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-web</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-webflux</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-websocket</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-web-services</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>com.sun.xml.messaging.saaj</groupId>
+        <artifactId>saaj-impl</artifactId>
+        <version>1.5.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>lift</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-api</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-chrome-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-chromium-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-devtools-v100</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-devtools-v101</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-devtools-v85</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-devtools-v99</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-edge-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-firefox-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-grid</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-http</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-ie-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-java</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-json</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-opera-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-remote-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-safari-driver</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-session-map-jdbc</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-session-map-redis</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>selenium-support</artifactId>
+        <version>4.1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.seleniumhq.selenium</groupId>
+        <artifactId>htmlunit-driver</artifactId>
+        <version>3.61.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.sendgrid</groupId>
+        <artifactId>sendgrid-java</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>javax.servlet-api</artifactId>
+        <version>4.0.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>jcl-over-slf4j</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>jul-to-slf4j</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>log4j-over-slf4j</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-api</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-ext</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-jcl</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-jdk14</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-log4j12</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-nop</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-simple</artifactId>
+        <version>1.7.36</version>
+      </dependency>
+      <dependency>
+        <groupId>org.yaml</groupId>
+        <artifactId>snakeyaml</artifactId>
+        <version>1.30</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-analysis-extras</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-analytics</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-cell</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-core</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-dataimporthandler</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-dataimporthandler-extras</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-gcs-repository</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-jaegertracer-configurator</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-langid</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-ltr</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-prometheus-exporter</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-s3-repository</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-solrj</artifactId>
+        <version>8.11.2</version>
+        <exclusions>
+          <exclusion>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <groupId>org.slf4j</groupId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-test-framework</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.solr</groupId>
+        <artifactId>solr-velocity</artifactId>
+        <version>8.11.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.amqp</groupId>
+        <artifactId>spring-amqp</artifactId>
+        <version>2.4.17</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.amqp</groupId>
+        <artifactId>spring-rabbit</artifactId>
+        <version>2.4.17</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.amqp</groupId>
+        <artifactId>spring-rabbit-stream</artifactId>
+        <version>2.4.17</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.amqp</groupId>
+        <artifactId>spring-rabbit-junit</artifactId>
+        <version>2.4.17</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.amqp</groupId>
+        <artifactId>spring-rabbit-test</artifactId>
+        <version>2.4.17</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.batch</groupId>
+        <artifactId>spring-batch-core</artifactId>
+        <version>4.3.10</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.batch</groupId>
+        <artifactId>spring-batch-infrastructure</artifactId>
+        <version>4.3.10</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.batch</groupId>
+        <artifactId>spring-batch-integration</artifactId>
+        <version>4.3.10</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.batch</groupId>
+        <artifactId>spring-batch-test</artifactId>
+        <version>4.3.10</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.graphql</groupId>
+        <artifactId>spring-graphql</artifactId>
+        <version>1.0.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.graphql</groupId>
+        <artifactId>spring-graphql-test</artifactId>
+        <version>1.0.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.hateoas</groupId>
+        <artifactId>spring-hateoas</artifactId>
+        <version>1.5.6</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.kafka</groupId>
+        <artifactId>spring-kafka</artifactId>
+        <version>2.8.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.kafka</groupId>
+        <artifactId>spring-kafka-test</artifactId>
+        <version>2.8.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ldap</groupId>
+        <artifactId>spring-ldap-core</artifactId>
+        <version>2.4.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ldap</groupId>
+        <artifactId>spring-ldap-core-tiger</artifactId>
+        <version>2.4.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ldap</groupId>
+        <artifactId>spring-ldap-ldif-core</artifactId>
+        <version>2.4.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ldap</groupId>
+        <artifactId>spring-ldap-odm</artifactId>
+        <version>2.4.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ldap</groupId>
+        <artifactId>spring-ldap-test</artifactId>
+        <version>2.4.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.restdocs</groupId>
+        <artifactId>spring-restdocs-asciidoctor</artifactId>
+        <version>2.0.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.restdocs</groupId>
+        <artifactId>spring-restdocs-core</artifactId>
+        <version>2.0.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.restdocs</groupId>
+        <artifactId>spring-restdocs-mockmvc</artifactId>
+        <version>2.0.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.restdocs</groupId>
+        <artifactId>spring-restdocs-restassured</artifactId>
+        <version>2.0.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.restdocs</groupId>
+        <artifactId>spring-restdocs-webtestclient</artifactId>
+        <version>2.0.8.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ws</groupId>
+        <artifactId>spring-ws-core</artifactId>
+        <version>3.1.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ws</groupId>
+        <artifactId>spring-ws-security</artifactId>
+        <version>3.1.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ws</groupId>
+        <artifactId>spring-ws-support</artifactId>
+        <version>3.1.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ws</groupId>
+        <artifactId>spring-ws-test</artifactId>
+        <version>3.1.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.ws</groupId>
+        <artifactId>spring-xml</artifactId>
+        <version>3.1.8</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xerial</groupId>
+        <artifactId>sqlite-jdbc</artifactId>
+        <version>3.36.0.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.sun.mail</groupId>
+        <artifactId>jakarta.mail</artifactId>
+        <version>1.6.7</version>
+      </dependency>
+      <dependency>
+        <groupId>org.thymeleaf</groupId>
+        <artifactId>thymeleaf</artifactId>
+        <version>3.0.15.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.thymeleaf</groupId>
+        <artifactId>thymeleaf-spring5</artifactId>
+        <version>3.0.15.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>com.github.mxab.thymeleaf.extras</groupId>
+        <artifactId>thymeleaf-extras-data-attribute</artifactId>
+        <version>2.0.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.thymeleaf.extras</groupId>
+        <artifactId>thymeleaf-extras-java8time</artifactId>
+        <version>3.0.4.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.thymeleaf.extras</groupId>
+        <artifactId>thymeleaf-extras-springsecurity5</artifactId>
+        <version>3.0.5.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>nz.net.ultraq.thymeleaf</groupId>
+        <artifactId>thymeleaf-layout-dialect</artifactId>
+        <version>3.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat</groupId>
+        <artifactId>tomcat-annotations-api</artifactId>
+        <version>9.0.83</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat</groupId>
+        <artifactId>tomcat-jdbc</artifactId>
+        <version>9.0.83</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat</groupId>
+        <artifactId>tomcat-jsp-api</artifactId>
+        <version>9.0.83</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat.embed</groupId>
+        <artifactId>tomcat-embed-core</artifactId>
+        <version>9.0.83</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat.embed</groupId>
+        <artifactId>tomcat-embed-el</artifactId>
+        <version>9.0.83</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat.embed</groupId>
+        <artifactId>tomcat-embed-jasper</artifactId>
+        <version>9.0.83</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.tomcat.embed</groupId>
+        <artifactId>tomcat-embed-websocket</artifactId>
+        <version>9.0.83</version>
+      </dependency>
+      <dependency>
+        <groupId>com.unboundid</groupId>
+        <artifactId>unboundid-ldapsdk</artifactId>
+        <version>6.0.10</version>
+      </dependency>
+      <dependency>
+        <groupId>io.undertow</groupId>
+        <artifactId>undertow-core</artifactId>
+        <version>2.2.28.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.undertow</groupId>
+        <artifactId>undertow-servlet</artifactId>
+        <version>2.2.28.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.undertow</groupId>
+        <artifactId>undertow-websockets-jsr</artifactId>
+        <version>2.2.28.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.webjars</groupId>
+        <artifactId>webjars-locator-core</artifactId>
+        <version>0.50</version>
+      </dependency>
+      <dependency>
+        <groupId>wsdl4j</groupId>
+        <artifactId>wsdl4j</artifactId>
+        <version>1.6.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-assertj</artifactId>
+        <version>2.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-assertj3</artifactId>
+        <version>2.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-core</artifactId>
+        <version>2.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-legacy</artifactId>
+        <version>2.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-matchers</artifactId>
+        <version>2.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.xmlunit</groupId>
+        <artifactId>xmlunit-placeholders</artifactId>
+        <version>2.9.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-core-shaded</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-mapper-processor</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-mapper-runtime</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-query-builder</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-test-infra</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-metrics-micrometer</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-metrics-microprofile</artifactId>
+        <version>4.14.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>native-protocol</artifactId>
+        <version>1.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>com.datastax.oss</groupId>
+        <artifactId>java-driver-shaded-guava</artifactId>
+        <version>25.1-jre-graal-sub-1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-annotation</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-caffeine</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-caffeine3</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-core</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-collectd</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-ehcache</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-graphite</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-healthchecks</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-httpclient</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-httpclient5</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-httpasyncclient</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jakarta-servlet</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jakarta-servlet6</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jakarta-servlets</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jcache</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jdbi</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jdbi3</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jersey2</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jersey3</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jersey31</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jetty9</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jetty10</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jetty11</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jetty12</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jetty12-ee10</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jmx</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-json</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-jvm</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-log4j2</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-logback</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-logback13</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-logback14</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-servlet</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.dropwizard.metrics</groupId>
+        <artifactId>metrics-servlets</artifactId>
+        <version>4.2.22</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-ant</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-astbuilder</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-bsf</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-cli-commons</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-cli-picocli</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-console</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-datetime</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-dateutil</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-docgenerator</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-groovydoc</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-groovysh</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-jaxb</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-jmx</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-json</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-jsr223</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-macro</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-nio</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-servlet</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-sql</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-swing</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-templates</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-test</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-test-junit5</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-testng</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-xml</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.codehaus.groovy</groupId>
+        <artifactId>groovy-yaml</artifactId>
+        <version>3.0.19</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-api</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cachestore-jdbc</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cachestore-sql</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cachestore-jpa</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cachestore-remote</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cachestore-rocksdb</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cdi-common</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cdi-embedded</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cdi-remote</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-checkstyle</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cli-client</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-client-hotrod</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-client-rest</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-key-value-store-client</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-clustered-counter</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-clustered-lock</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-commons</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-commons-test</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-component-annotations</artifactId>
+        <version>13.0.20.Final</version>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-component-processor</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-core</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-jboss-marshalling</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-extended-statistics</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-hibernate-cache-commons</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-hibernate-cache-spi</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-hibernate-cache-v53</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-jcache-commons</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-jcache</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-jcache-remote</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-console</artifactId>
+        <version>0.15.5.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-multimap</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-objectfilter</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-query-core</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-query</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-query-dsl</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-remote-query-client</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-remote-query-server</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-scripting</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-core</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-hotrod</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-memcached</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-rest</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-router</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-runtime</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-testdriver-core</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-testdriver-junit4</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-server-testdriver-junit5</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-spring5-common</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-spring5-embedded</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-spring5-remote</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-spring-boot-starter-embedded</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-spring-boot-starter-remote</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-tasks</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-tasks-api</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-tools</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-anchored-keys</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan.protostream</groupId>
+        <artifactId>protostream</artifactId>
+        <version>4.4.4.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan.protostream</groupId>
+        <artifactId>protostream-types</artifactId>
+        <version>4.4.4.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan.protostream</groupId>
+        <artifactId>protostream-processor</artifactId>
+        <version>4.4.4.Final</version>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-cloudevents-integration</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-marshaller-kryo</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-marshaller-kryo-bundle</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-marshaller-protostuff</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>org.infinispan</groupId>
+        <artifactId>infinispan-marshaller-protostuff-bundle</artifactId>
+        <version>13.0.20.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-annotations</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-core</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.core</groupId>
+        <artifactId>jackson-databind</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-avro</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-cbor</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-csv</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-ion</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-properties</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-protobuf</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-smile</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-toml</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-xml</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.dataformat</groupId>
+        <artifactId>jackson-dataformat-yaml</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-eclipse-collections</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-guava</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-hibernate4</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-hibernate5</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-hibernate5-jakarta</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-hppc</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-jakarta-jsonp</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-jaxrs</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-joda</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-joda-money</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-jdk8</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-json-org</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-jsr310</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-jsr353</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.datatype</groupId>
+        <artifactId>jackson-datatype-pcollections</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-base</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-cbor-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-json-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-smile-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-xml-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jaxrs</groupId>
+        <artifactId>jackson-jaxrs-yaml-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
+        <artifactId>jackson-jakarta-rs-base</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
+        <artifactId>jackson-jakarta-rs-cbor-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
+        <artifactId>jackson-jakarta-rs-json-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
+        <artifactId>jackson-jakarta-rs-smile-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
+        <artifactId>jackson-jakarta-rs-xml-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
+        <artifactId>jackson-jakarta-rs-yaml-provider</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jr</groupId>
+        <artifactId>jackson-jr-all</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jr</groupId>
+        <artifactId>jackson-jr-annotation-support</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jr</groupId>
+        <artifactId>jackson-jr-objects</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jr</groupId>
+        <artifactId>jackson-jr-retrofit2</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.jr</groupId>
+        <artifactId>jackson-jr-stree</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-afterburner</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-blackbird</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-guice</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-jaxb-annotations</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-jsonSchema</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-kotlin</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-mrbean</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-no-ctor-deser</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-osgi</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-parameter-names</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-paranamer</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-scala_2.11</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-scala_2.12</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-scala_2.13</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>com.fasterxml.jackson.module</groupId>
+        <artifactId>jackson-module-scala_3</artifactId>
+        <version>2.13.5</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.core</groupId>
+        <artifactId>jersey-common</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.core</groupId>
+        <artifactId>jersey-client</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.core</groupId>
+        <artifactId>jersey-server</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.bundles</groupId>
+        <artifactId>jaxrs-ri</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>jersey-apache-connector</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>jersey-helidon-connector</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>jersey-grizzly-connector</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>jersey-jetty-connector</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>jersey-jdk-connector</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>jersey-netty-connector</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-jetty-http</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-grizzly2-http</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-grizzly2-servlet</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-jetty-servlet</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-jdk-http</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-netty-http</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-servlet</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-servlet-core</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-simple-http</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers.glassfish</groupId>
+        <artifactId>jersey-gf-ejb</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-bean-validation</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-entity-filtering</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-metainf-services</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.microprofile</groupId>
+        <artifactId>jersey-mp-config</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-mvc</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-mvc-bean-validation</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-mvc-freemarker</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-mvc-jsp</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-mvc-mustache</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-proxy-client</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-servlet-portability</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-spring4</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-spring5</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-declarative-linking</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>jersey-wadl-doclet</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.cdi</groupId>
+        <artifactId>jersey-weld2-se</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.cdi</groupId>
+        <artifactId>jersey-cdi1x</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.cdi</groupId>
+        <artifactId>jersey-cdi1x-transaction</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.cdi</groupId>
+        <artifactId>jersey-cdi1x-validation</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.cdi</groupId>
+        <artifactId>jersey-cdi1x-servlet</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.cdi</groupId>
+        <artifactId>jersey-cdi1x-ban-custom-hk2-binding</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.cdi</groupId>
+        <artifactId>jersey-cdi-rs-inject</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.rx</groupId>
+        <artifactId>jersey-rx-client-guava</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.rx</groupId>
+        <artifactId>jersey-rx-client-rxjava</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.rx</groupId>
+        <artifactId>jersey-rx-client-rxjava2</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.ext.microprofile</groupId>
+        <artifactId>jersey-mp-rest-client</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-jaxb</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-json-jackson</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-json-jettison</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-json-processing</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-json-binding</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-kryo</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-moxy</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-multipart</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.media</groupId>
+        <artifactId>jersey-media-sse</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.security</groupId>
+        <artifactId>oauth1-client</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.security</groupId>
+        <artifactId>oauth1-server</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.security</groupId>
+        <artifactId>oauth1-signature</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.security</groupId>
+        <artifactId>oauth2-client</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.inject</groupId>
+        <artifactId>jersey-hk2</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.inject</groupId>
+        <artifactId>jersey-cdi2-se</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework</groupId>
+        <artifactId>jersey-test-framework-core</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <artifactId>jersey-test-framework-provider-bundle</artifactId>
+        <version>2.35</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <artifactId>jersey-test-framework-provider-external</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <artifactId>jersey-test-framework-provider-inmemory</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <artifactId>jersey-test-framework-provider-jdk-http</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <artifactId>jersey-test-framework-provider-simple</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+        <artifactId>jersey-test-framework-provider-jetty</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.glassfish.jersey.test-framework</groupId>
+        <artifactId>jersey-test-framework-util</artifactId>
+        <version>2.35</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>apache-jsp</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>apache-jstl</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-java-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-java-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-openjdk8-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-openjdk8-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-conscrypt-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-conscrypt-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-alpn-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-annotations</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-ant</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-continuation</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-deploy</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-distribution</artifactId>
+        <version>9.4.53.v20231009</version>
+        <type>zip</type>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-distribution</artifactId>
+        <version>9.4.53.v20231009</version>
+        <type>tar.gz</type>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.fcgi</groupId>
+        <artifactId>fcgi-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.fcgi</groupId>
+        <artifactId>fcgi-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.gcloud</groupId>
+        <artifactId>jetty-gcloud-session-manager</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-home</artifactId>
+        <version>9.4.53.v20231009</version>
+        <type>zip</type>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-home</artifactId>
+        <version>9.4.53.v20231009</version>
+        <type>tar.gz</type>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-http</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.http2</groupId>
+        <artifactId>http2-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.http2</groupId>
+        <artifactId>http2-common</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.http2</groupId>
+        <artifactId>http2-hpack</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.http2</groupId>
+        <artifactId>http2-http-client-transport</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.http2</groupId>
+        <artifactId>http2-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-http-spi</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>infinispan-common</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>infinispan-remote-query</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>infinispan-embedded-query</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-hazelcast</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-io</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-jaas</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-jaspi</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-jmx</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-jndi</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.memcached</groupId>
+        <artifactId>jetty-memcached-sessions</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-nosql</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.osgi</groupId>
+        <artifactId>jetty-osgi-boot</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.osgi</groupId>
+        <artifactId>jetty-osgi-boot-jsp</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.osgi</groupId>
+        <artifactId>jetty-osgi-boot-warurl</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.osgi</groupId>
+        <artifactId>jetty-httpservice</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-plus</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-proxy</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-quickstart</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-rewrite</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-security</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-openid</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-servlet</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-servlets</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-spring</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-unixsocket</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-util</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-util-ajax</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-webapp</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.websocket</groupId>
+        <artifactId>javax-websocket-client-impl</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.websocket</groupId>
+        <artifactId>javax-websocket-server-impl</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.websocket</groupId>
+        <artifactId>websocket-api</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.websocket</groupId>
+        <artifactId>websocket-client</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.websocket</groupId>
+        <artifactId>websocket-common</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.websocket</groupId>
+        <artifactId>websocket-server</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty.websocket</groupId>
+        <artifactId>websocket-servlet</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.jetty</groupId>
+        <artifactId>jetty-xml</artifactId>
+        <version>9.4.53.v20231009</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter</artifactId>
+        <version>5.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-engine</artifactId>
+        <version>5.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-migrationsupport</artifactId>
+        <version>5.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-params</artifactId>
+        <version>5.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-commons</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-console</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-engine</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-jfr</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-launcher</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-reporting</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-runner</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-suite</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-suite-api</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-suite-commons</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-suite-engine</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.platform</groupId>
+        <artifactId>junit-platform-testkit</artifactId>
+        <version>1.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.junit.vintage</groupId>
+        <artifactId>junit-vintage-engine</artifactId>
+        <version>5.8.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-stdlib</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-stdlib-jdk7</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-stdlib-jdk8</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-stdlib-js</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-stdlib-common</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-reflect</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-osgi-bundle</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-test</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-test-junit</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-test-junit5</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-test-testng</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-test-js</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-test-common</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-test-annotations-common</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-main-kts</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-script-runtime</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-script-util</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-scripting-common</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-scripting-jvm</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-scripting-jvm-host</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-scripting-ide-services</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-compiler</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-compiler-embeddable</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlin</groupId>
+        <artifactId>kotlin-daemon-client</artifactId>
+        <version>1.6.21</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-android</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-core-jvm</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-core</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-debug</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-guava</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-javafx</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-jdk8</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-jdk9</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-play-services</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-reactive</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-reactor</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-rx2</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-rx3</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-slf4j</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-swing</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-test-jvm</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.jetbrains.kotlinx</groupId>
+        <artifactId>kotlinx-coroutines-test</artifactId>
+        <version>1.6.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-api</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-core</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-layout-template-json</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-1.2-api</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-jcl</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-flume-ng</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-taglib</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-jmx-gui</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-slf4j-impl</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-slf4j18-impl</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-to-slf4j</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-appserver</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-web</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-couchdb</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-mongodb4</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-mongodb3</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-cassandra</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-jpa</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-iostreams</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-jul</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-jpl</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-liquibase</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-docker</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-kubernetes</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-spring-boot</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.logging.log4j</groupId>
+        <artifactId>log4j-spring-cloud-config-client</artifactId>
+        <version>2.17.2</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-core</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-appoptics</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-atlas</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-azure-monitor</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-cloudwatch</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-cloudwatch2</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-datadog</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-dynatrace</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-elastic</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-ganglia</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-graphite</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-health</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-humio</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-influx</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-jmx</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-kairos</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-new-relic</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-opentsdb</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-otlp</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-prometheus</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-signalfx</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-statsd</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-registry-wavefront</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>io.micrometer</groupId>
+        <artifactId>micrometer-test</artifactId>
+        <version>1.9.17</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-core</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-android</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-errorprone</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-inline</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-junit-jupiter</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-proxy</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-buffer</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-dns</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-haproxy</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-http</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-http2</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-memcache</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-mqtt</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-redis</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-smtp</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-socks</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-stomp</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-codec-xml</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-common</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-dev-tools</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-handler</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-handler-proxy</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-handler-ssl-ocsp</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-resolver</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-resolver-dns</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-rxtx</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-sctp</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-udt</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-example</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-all</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-resolver-dns-classes-macos</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-resolver-dns-native-macos</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-resolver-dns-native-macos</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>osx-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-resolver-dns-native-macos</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>osx-aarch_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-unix-common</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-unix-common</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>linux-aarch_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-unix-common</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>linux-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-unix-common</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>osx-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-unix-common</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>osx-aarch_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-classes-epoll</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-epoll</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-epoll</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>linux-aarch_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-epoll</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>linux-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-classes-kqueue</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-kqueue</artifactId>
+        <version>4.1.101.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-kqueue</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>osx-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-transport-native-kqueue</artifactId>
+        <version>4.1.101.Final</version>
+        <classifier>osx-aarch_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative-classes</artifactId>
+        <version>2.0.61.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>linux-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>linux-x86_64-fedora</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>linux-aarch_64-fedora</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>osx-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative-boringssl-static</artifactId>
+        <version>2.0.61.Final</version>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative-boringssl-static</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>linux-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative-boringssl-static</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>linux-aarch_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative-boringssl-static</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>osx-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative-boringssl-static</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>osx-aarch_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>io.netty</groupId>
+        <artifactId>netty-tcnative-boringssl-static</artifactId>
+        <version>2.0.61.Final</version>
+        <classifier>windows-x86_64</classifier>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>mockwebserver</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okcurl</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okhttp</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okhttp-brotli</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okhttp-dnsoverhttps</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>logging-interceptor</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okhttp-sse</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okhttp-tls</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup.okhttp3</groupId>
+        <artifactId>okhttp-urlconnection</artifactId>
+        <version>4.9.3</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>ojdbc11</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>ojdbc8</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>ucp</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>ucp11</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>rsi</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.security</groupId>
+        <artifactId>oraclepki</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.security</groupId>
+        <artifactId>osdt_core</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.security</groupId>
+        <artifactId>osdt_cert</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.ha</groupId>
+        <artifactId>simplefan</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.ha</groupId>
+        <artifactId>ons</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.nls</groupId>
+        <artifactId>orai18n</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.xml</groupId>
+        <artifactId>xdb</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.xml</groupId>
+        <artifactId>xmlparserv2</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc11_g</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc8_g</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc8dms_g</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc11dms_g</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.observability</groupId>
+        <artifactId>dms</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.observability</groupId>
+        <artifactId>ojdbc11dms</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.observability</groupId>
+        <artifactId>ojdbc8dms</artifactId>
+        <version>21.5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>ojdbc11-production</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc</groupId>
+        <artifactId>ojdbc8-production</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.observability</groupId>
+        <artifactId>ojdbc8-observability</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.observability</groupId>
+        <artifactId>ojdbc11-observability</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc8-debug</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc11-debug</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc8-observability-debug</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.jdbc.debug</groupId>
+        <artifactId>ojdbc11-observability-debug</artifactId>
+        <version>21.5.0.0</version>
+        <type>pom</type>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_caffeine</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_common</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_dropwizard</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_graphite_bridge</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_guava</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_hibernate</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_hotspot</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_httpserver</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_jetty</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_jetty_jdk8</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_log4j</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_log4j2</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_logback</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_pushgateway</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_servlet</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_servlet_jakarta</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_spring_boot</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_spring_web</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_tracer_otel</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_tracer_otel_agent</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.prometheus</groupId>
+        <artifactId>simpleclient_vertx</artifactId>
+        <version>0.15.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-core</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-codegen</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-codegen-utils</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-spatial</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-apt</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-collections</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-guava</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-sql</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-sql-spatial</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-sql-codegen</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-sql-spring</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-jpa</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-jpa-codegen</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-jdo</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-kotlin-codegen</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-lucene3</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-lucene4</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-lucene5</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-hibernate-search</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-mongodb</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-scala</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.querydsl</groupId>
+        <artifactId>querydsl-kotlin</artifactId>
+        <version>5.0.0</version>
+      </dependency>
+      <dependency>
+        <groupId>com.oracle.database.r2dbc</groupId>
+        <artifactId>oracle-r2dbc</artifactId>
+        <version>0.4.0</version>
+      </dependency>
+      <dependency>
+        <groupId>io.r2dbc</groupId>
+        <artifactId>r2dbc-h2</artifactId>
+        <version>0.9.1.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.mariadb</groupId>
+        <artifactId>r2dbc-mariadb</artifactId>
+        <version>1.1.2</version>
+      </dependency>
+      <dependency>
+        <groupId>io.r2dbc</groupId>
+        <artifactId>r2dbc-mssql</artifactId>
+        <version>0.9.0.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>org.postgresql</groupId>
+        <artifactId>r2dbc-postgresql</artifactId>
+        <version>0.9.2.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>io.r2dbc</groupId>
+        <artifactId>r2dbc-pool</artifactId>
+        <version>0.9.2.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>io.r2dbc</groupId>
+        <artifactId>r2dbc-proxy</artifactId>
+        <version>0.9.1.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>io.r2dbc</groupId>
+        <artifactId>r2dbc-spi</artifactId>
+        <version>0.9.1.RELEASE</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor</groupId>
+        <artifactId>reactor-core</artifactId>
+        <version>3.4.34</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor</groupId>
+        <artifactId>reactor-test</artifactId>
+        <version>3.4.34</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor</groupId>
+        <artifactId>reactor-tools</artifactId>
+        <version>3.4.34</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.addons</groupId>
+        <artifactId>reactor-extra</artifactId>
+        <version>3.4.10</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.addons</groupId>
+        <artifactId>reactor-adapter</artifactId>
+        <version>3.4.10</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.netty</groupId>
+        <artifactId>reactor-netty</artifactId>
+        <version>1.0.39</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.netty</groupId>
+        <artifactId>reactor-netty-core</artifactId>
+        <version>1.0.39</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.netty</groupId>
+        <artifactId>reactor-netty-http</artifactId>
+        <version>1.0.39</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.netty</groupId>
+        <artifactId>reactor-netty-http-brave</artifactId>
+        <version>1.0.39</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.addons</groupId>
+        <artifactId>reactor-pool</artifactId>
+        <version>0.2.12</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.kafka</groupId>
+        <artifactId>reactor-kafka</artifactId>
+        <version>1.3.22</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.rabbitmq</groupId>
+        <artifactId>reactor-rabbitmq</artifactId>
+        <version>1.5.6</version>
+      </dependency>
+      <dependency>
+        <groupId>io.projectreactor.kotlin</groupId>
+        <artifactId>reactor-kotlin-extensions</artifactId>
+        <version>1.1.10</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>json-schema-validator</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>rest-assured-common</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>json-path</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>xml-path</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>rest-assured</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>spring-commons</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>spring-mock-mvc</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>scala-support</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>spring-web-test-client</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>kotlin-extensions</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>spring-mock-mvc-kotlin-extensions</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured</groupId>
+        <artifactId>rest-assured-all</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured.examples</groupId>
+        <artifactId>scalatra-example</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured.examples</groupId>
+        <artifactId>scalatra-webapp</artifactId>
+        <version>4.5.1</version>
+        <type>war</type>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured.examples</groupId>
+        <artifactId>rest-assured-itest-java</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured.examples</groupId>
+        <artifactId>spring-mvc-webapp</artifactId>
+        <version>4.5.1</version>
+        <type>war</type>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured.examples</groupId>
+        <artifactId>scala-example</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured.examples</groupId>
+        <artifactId>scala-mock-mvc-example</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rest-assured.examples</groupId>
+        <artifactId>kotlin-example</artifactId>
+        <version>4.5.1</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rsocket</groupId>
+        <artifactId>rsocket-core</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rsocket</groupId>
+        <artifactId>rsocket-load-balancer</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rsocket</groupId>
+        <artifactId>rsocket-micrometer</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rsocket</groupId>
+        <artifactId>rsocket-test</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rsocket</groupId>
+        <artifactId>rsocket-transport-local</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>io.rsocket</groupId>
+        <artifactId>rsocket-transport-netty</artifactId>
+        <version>1.1.3</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-cassandra</artifactId>
+        <version>3.4.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-commons</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-couchbase</artifactId>
+        <version>4.4.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-elasticsearch</artifactId>
+        <version>4.4.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-geode</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-jdbc</artifactId>
+        <version>2.4.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-relational</artifactId>
+        <version>2.4.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-jpa</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-mongodb</artifactId>
+        <version>3.4.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-neo4j</artifactId>
+        <version>6.3.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-r2dbc</artifactId>
+        <version>1.5.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-redis</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-rest-webmvc</artifactId>
+        <version>3.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-rest-core</artifactId>
+        <version>3.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-rest-hal-explorer</artifactId>
+        <version>3.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-keyvalue</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-envers</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.data</groupId>
+        <artifactId>spring-data-ldap</artifactId>
+        <version>2.7.18</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-aop</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-aspects</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-beans</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-context</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-context-indexer</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-context-support</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-core</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-expression</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-instrument</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-jcl</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-jdbc</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-jms</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-messaging</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-orm</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-oxm</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-r2dbc</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-test</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-tx</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-web</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-webflux</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-webmvc</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-websocket</artifactId>
+        <version>5.3.31</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-amqp</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-core</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-event</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-feed</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-file</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-ftp</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-gemfire</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-groovy</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-http</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-ip</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-jdbc</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-jms</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-jmx</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-jpa</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-kafka</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-mail</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-mongodb</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-mqtt</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-r2dbc</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-redis</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-rmi</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-rsocket</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-scripting</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-security</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-sftp</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-stomp</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-stream</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-syslog</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-test</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-test-support</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-webflux</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-websocket</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-ws</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-xml</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-xmpp</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-zeromq</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.integration</groupId>
+        <artifactId>spring-integration-zookeeper</artifactId>
+        <version>5.5.20</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-acl</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-aspects</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-cas</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-config</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-core</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-crypto</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-data</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-ldap</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-messaging</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-oauth2-client</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-oauth2-core</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-oauth2-jose</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-oauth2-resource-server</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-openid</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-remoting</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-rsocket</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-saml2-service-provider</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-taglibs</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-test</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.security</groupId>
+        <artifactId>spring-security-web</artifactId>
+        <version>5.7.11</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.session</groupId>
+        <artifactId>spring-session-core</artifactId>
+        <version>2.7.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.session</groupId>
+        <artifactId>spring-session-data-geode</artifactId>
+        <version>2.7.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.session</groupId>
+        <artifactId>spring-session-data-mongodb</artifactId>
+        <version>2.7.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.session</groupId>
+        <artifactId>spring-session-data-redis</artifactId>
+        <version>2.7.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.session</groupId>
+        <artifactId>spring-session-hazelcast</artifactId>
+        <version>2.7.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework.session</groupId>
+        <artifactId>spring-session-jdbc</artifactId>
+        <version>2.7.4</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger2</artifactId>
+      <version>2.9.2</version>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>swagger-annotations</artifactId>
+          <groupId>io.swagger</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>swagger-models</artifactId>
+          <groupId>io.swagger</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>io.springfox</groupId>
+      <artifactId>springfox-swagger-ui</artifactId>
+      <version>2.9.2</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.xiaoymin</groupId>
+      <artifactId>swagger-bootstrap-ui</artifactId>
+      <version>1.9.3</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.javen205</groupId>
+      <artifactId>IJPay-All</artifactId>
+      <version>2.7.8</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fs</groupId>
+      <artifactId>fs-quartz</artifactId>
+      <version>1.1.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>cn.jpush.api</groupId>
+      <artifactId>jpush-client</artifactId>
+      <version>3.4.3</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.alipay.sdk</groupId>
+      <artifactId>alipay-sdk-java</artifactId>
+      <version>4.8.62.ALL</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>8.0.33</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup.okhttp3</groupId>
+      <artifactId>okhttp</artifactId>
+      <version>4.9.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>cn.jpush.api</groupId>
+      <artifactId>jiguang-common</artifactId>
+      <version>1.1.7</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.fs</groupId>
+      <artifactId>fs-common</artifactId>
+      <version>1.1.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>1.18.30</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.baidu.dev2</groupId>
+      <artifactId>baiduads-sdk</artifactId>
+      <version>2023.1.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.tzbank</groupId>
+      <artifactId>tzbClient</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.zxing</groupId>
+      <artifactId>core</artifactId>
+      <version>3.3.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.zxing</groupId>
+      <artifactId>javase</artifactId>
+      <version>3.3.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.coobird</groupId>
+      <artifactId>thumbnailator</artifactId>
+      <version>0.4.8</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.qcloud</groupId>
+      <artifactId>cos-sts_api</artifactId>
+      <version>3.1.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.qiniu</groupId>
+      <artifactId>qiniu-java-sdk</artifactId>
+      <version>[7.2.0, 7.2.99]</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.aliyun.oss</groupId>
+      <artifactId>aliyun-sdk-oss</artifactId>
+      <version>3.5.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.qcloud</groupId>
+      <artifactId>cos_api</artifactId>
+      <version>5.6.3</version>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <artifactId>slf4j-log4j12</artifactId>
+          <groupId>org.slf4j</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>com.tencentcloudapi</groupId>
+      <artifactId>tencentcloud-sdk-java</artifactId>
+      <version>3.1.322</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hibernate.validator</groupId>
+      <artifactId>hibernate-validator</artifactId>
+      <version>6.2.5.Final</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.binarywang</groupId>
+      <artifactId>weixin-java-miniapp</artifactId>
+      <version>4.7.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.binarywang</groupId>
+      <artifactId>weixin-java-pay</artifactId>
+      <version>4.7.2.B</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.binarywang</groupId>
+      <artifactId>weixin-java-mp</artifactId>
+      <version>4.7.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.binarywang</groupId>
+      <artifactId>weixin-java-cp</artifactId>
+      <version>4.7.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.swagger</groupId>
+      <artifactId>swagger-annotations</artifactId>
+      <version>1.5.21</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.swagger</groupId>
+      <artifactId>swagger-models</artifactId>
+      <version>1.5.21</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.vdurmont</groupId>
+      <artifactId>emoji-java</artifactId>
+      <version>4.0.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.tencentyun</groupId>
+      <artifactId>tls-sig-api-v2</artifactId>
+      <version>2.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.httpcomponents.client5</groupId>
+      <artifactId>httpclient5</artifactId>
+      <version>5.2.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.baidubce</groupId>
+      <artifactId>appbuilder</artifactId>
+      <version>0.6.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-test</artifactId>
+      <version>5.2.12.RELEASE</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.huaweicloud.sdk</groupId>
+      <artifactId>huaweicloud-sdk-vod</artifactId>
+      <version>3.1.103</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.huaweicloud.sdk</groupId>
+      <artifactId>huaweicloud-sdk-mpc</artifactId>
+      <version>3.1.88</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.huaweicloud.sdk</groupId>
+      <artifactId>huaweicloud-sdk-cdn</artifactId>
+      <version>3.1.54</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.huaweicloud</groupId>
+      <artifactId>esdk-obs-java-bundle</artifactId>
+      <version>3.23.9</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>ws.schild</groupId>
+      <artifactId>jave-core</artifactId>
+      <version>3.0.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.protobuf</groupId>
+      <artifactId>protobuf-java</artifactId>
+      <version>3.11.4</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.redisson</groupId>
+      <artifactId>redisson-spring-boot-starter</artifactId>
+      <version>3.13.6</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.rocketmq</groupId>
+      <artifactId>rocketmq-spring-boot-starter</artifactId>
+      <version>2.2.3</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.baomidou</groupId>
+      <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
+      <version>3.1.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-text</artifactId>
+      <version>1.10.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.wechatpay-apiv3</groupId>
+      <artifactId>wechatpay-java</artifactId>
+      <version>0.2.16</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.ben-manes.caffeine</groupId>
+      <artifactId>caffeine</artifactId>
+      <version>2.9.3</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mapstruct</groupId>
+      <artifactId>mapstruct</artifactId>
+      <version>1.5.5.Final</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mapstruct</groupId>
+      <artifactId>mapstruct-processor</artifactId>
+      <version>1.5.5.Final</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.hc</groupId>
+      <artifactId>openapi</artifactId>
+      <version>1.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.volcengine</groupId>
+      <artifactId>volc-sdk-java</artifactId>
+      <version>1.0.250</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.retry</groupId>
+      <artifactId>spring-retry</artifactId>
+      <version>1.3.1</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>druid-spring-boot-starter</artifactId>
+      <version>1.2.6</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.penggle</groupId>
+      <artifactId>kaptcha</artifactId>
+      <version>2.3.2</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.oshi</groupId>
+      <artifactId>oshi-core</artifactId>
+      <version>5.8.0</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.hankcs</groupId>
+      <artifactId>aho-corasick-double-array-trie</artifactId>
+      <version>1.2.3</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+  <repositories>
+    <repository>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+      <id>public</id>
+      <name>aliyun nexus</name>
+      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+    </repository>
+    <repository>
+      <id>OceanengineOpenApi</id>
+      <name>ad_open_sdk_java</name>
+      <url>https://artifact.bytedance.com/repository/releases/</url>
+    </repository>
+    <repository>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>https://repo.maven.apache.org/maven2</url>
+    </repository>
+  </repositories>
+  <pluginRepositories>
+    <pluginRepository>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+      <id>public</id>
+      <name>aliyun nexus</name>
+      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+    </pluginRepository>
+    <pluginRepository>
+      <releases>
+        <updatePolicy>never</updatePolicy>
+      </releases>
+      <snapshots>
+        <enabled>false</enabled>
+      </snapshots>
+      <id>central</id>
+      <name>Central Repository</name>
+      <url>https://repo.maven.apache.org/maven2</url>
+    </pluginRepository>
+  </pluginRepositories>
+  <build>
+    <sourceDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\src\main\java</sourceDirectory>
+    <scriptSourceDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\src\main\scripts</scriptSourceDirectory>
+    <testSourceDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\src\test\java</testSourceDirectory>
+    <outputDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\target\classes</outputDirectory>
+    <testOutputDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\target\test-classes</testOutputDirectory>
+    <resources>
+      <resource>
+        <directory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\src\main\resources</directory>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\src\test\resources</directory>
+      </testResource>
+    </testResources>
+    <directory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\target</directory>
+    <finalName>fs-service-1.1.0</finalName>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-antrun-plugin</artifactId>
+          <version>1.3</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <version>2.2-beta-5</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-dependency-plugin</artifactId>
+          <version>2.8</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-release-plugin</artifactId>
+          <version>2.5.3</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.11.0</version>
+        <executions>
+          <execution>
+            <id>default-compile</id>
+            <phase>compile</phase>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+            <configuration>
+              <source>17</source>
+              <target>17</target>
+              <encoding>UTF-8</encoding>
+              <annotationProcessorPaths>
+                <path>
+                  <groupId>org.projectlombok</groupId>
+                  <artifactId>lombok</artifactId>
+                  <version>1.18.32</version>
+                </path>
+                <path>
+                  <groupId>org.mapstruct</groupId>
+                  <artifactId>mapstruct-processor</artifactId>
+                  <version>1.5.5.Final</version>
+                </path>
+                <path>
+                  <groupId>org.projectlombok</groupId>
+                  <artifactId>lombok-mapstruct-binding</artifactId>
+                  <version>0.2.0</version>
+                </path>
+              </annotationProcessorPaths>
+            </configuration>
+          </execution>
+          <execution>
+            <id>default-testCompile</id>
+            <phase>test-compile</phase>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+            <configuration>
+              <source>17</source>
+              <target>17</target>
+              <encoding>UTF-8</encoding>
+              <annotationProcessorPaths>
+                <path>
+                  <groupId>org.projectlombok</groupId>
+                  <artifactId>lombok</artifactId>
+                  <version>1.18.32</version>
+                </path>
+                <path>
+                  <groupId>org.mapstruct</groupId>
+                  <artifactId>mapstruct-processor</artifactId>
+                  <version>1.5.5.Final</version>
+                </path>
+                <path>
+                  <groupId>org.projectlombok</groupId>
+                  <artifactId>lombok-mapstruct-binding</artifactId>
+                  <version>0.2.0</version>
+                </path>
+              </annotationProcessorPaths>
+            </configuration>
+          </execution>
+        </executions>
+        <configuration>
+          <source>17</source>
+          <target>17</target>
+          <encoding>UTF-8</encoding>
+          <annotationProcessorPaths>
+            <path>
+              <groupId>org.projectlombok</groupId>
+              <artifactId>lombok</artifactId>
+              <version>1.18.32</version>
+            </path>
+            <path>
+              <groupId>org.mapstruct</groupId>
+              <artifactId>mapstruct-processor</artifactId>
+              <version>1.5.5.Final</version>
+            </path>
+            <path>
+              <groupId>org.projectlombok</groupId>
+              <artifactId>lombok-mapstruct-binding</artifactId>
+              <version>0.2.0</version>
+            </path>
+          </annotationProcessorPaths>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-clean-plugin</artifactId>
+        <version>2.5</version>
+        <executions>
+          <execution>
+            <id>default-clean</id>
+            <phase>clean</phase>
+            <goals>
+              <goal>clean</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>2.6</version>
+        <executions>
+          <execution>
+            <id>default-testResources</id>
+            <phase>process-test-resources</phase>
+            <goals>
+              <goal>testResources</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>default-resources</id>
+            <phase>process-resources</phase>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>default-jar</id>
+            <phase>package</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.12.4</version>
+        <executions>
+          <execution>
+            <id>default-test</id>
+            <phase>test</phase>
+            <goals>
+              <goal>test</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-install-plugin</artifactId>
+        <version>2.4</version>
+        <executions>
+          <execution>
+            <id>default-install</id>
+            <phase>install</phase>
+            <goals>
+              <goal>install</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <version>2.7</version>
+        <executions>
+          <execution>
+            <id>default-deploy</id>
+            <phase>deploy</phase>
+            <goals>
+              <goal>deploy</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-site-plugin</artifactId>
+        <version>3.3</version>
+        <executions>
+          <execution>
+            <id>default-site</id>
+            <phase>site</phase>
+            <goals>
+              <goal>site</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\target\site</outputDirectory>
+              <reportPlugins>
+                <reportPlugin>
+                  <groupId>org.apache.maven.plugins</groupId>
+                  <artifactId>maven-project-info-reports-plugin</artifactId>
+                </reportPlugin>
+              </reportPlugins>
+            </configuration>
+          </execution>
+          <execution>
+            <id>default-deploy</id>
+            <phase>site-deploy</phase>
+            <goals>
+              <goal>deploy</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\target\site</outputDirectory>
+              <reportPlugins>
+                <reportPlugin>
+                  <groupId>org.apache.maven.plugins</groupId>
+                  <artifactId>maven-project-info-reports-plugin</artifactId>
+                </reportPlugin>
+              </reportPlugins>
+            </configuration>
+          </execution>
+        </executions>
+        <configuration>
+          <outputDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\target\site</outputDirectory>
+          <reportPlugins>
+            <reportPlugin>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-project-info-reports-plugin</artifactId>
+            </reportPlugin>
+          </reportPlugins>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <reporting>
+    <outputDirectory>F:\project\Saas\ylrz_saas_his_scrm\fs-service\target\site</outputDirectory>
+  </reporting>
+</project>
+
+
+[INFO] ------------------------------------------------------------------------
+[INFO] BUILD SUCCESS
+[INFO] ------------------------------------------------------------------------
+[INFO] Total time:  0.920 s
+[INFO] Finished at: 2026-06-01T15:07:35+08:00
+[INFO] ------------------------------------------------------------------------

+ 3 - 5
fs-admin-saas/pom.xml

@@ -87,13 +87,10 @@
                 </exclusion>
             </exclusions>
         </dependency>
-
-
-
-        <!-- 定时任务-->
+        <!-- 直接依赖 fs-service 以确保 his 领域模型、hisStore 任务等对 saasadmin 可见(某些控制器直接引用) -->
         <dependency>
             <groupId>com.fs</groupId>
-            <artifactId>fs-quartz</artifactId>
+            <artifactId>fs-service</artifactId>
             <exclusions>
                 <exclusion>
                     <groupId>org.apache.tomcat</groupId>
@@ -101,6 +98,7 @@
                 </exclusion>
             </exclusions>
         </dependency>
+
         <!-- lombok -->
         <dependency>
             <groupId>org.projectlombok</groupId>

+ 0 - 2
fs-admin-saas/src/main/java/com/fs/FsSaasAdminApplication.java

@@ -7,7 +7,6 @@ import org.redisson.spring.starter.RedissonAutoConfiguration;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.FilterType;
 import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -16,7 +15,6 @@ import org.springframework.transaction.annotation.Transactional;
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, RedissonAutoConfiguration.class})
 @Transactional
 @EnableAsync
-@EnableScheduling
 public class FsSaasAdminApplication {
     public static void main(String[] args) {
         SpringApplication.run(FsSaasAdminApplication.class, args);

+ 0 - 20
fs-admin-saas/src/main/java/com/fs/hisStore/task/CrmTask.java

@@ -1,20 +0,0 @@
-package com.fs.hisStore.task;
-
-import com.fs.crm.service.ICrmCustomerService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-@Service("crmTask")
-public class CrmTask {
-    private static final Logger log = LoggerFactory.getLogger(CrmTask.class);
-    @Autowired
-    private ICrmCustomerService crmCustomerService;
-    /**
-     * 汇总crm订单成交总额
-     */
-    public void computePayMoney(){
-        crmCustomerService.computePayMoney();
-    }
-}

+ 0 - 110
fs-admin-saas/src/main/java/com/fs/hisStore/task/ErpTask.java

@@ -1,110 +0,0 @@
-package com.fs.hisStore.task;
-
-import com.fs.erp.domain.ErpOrder;
-import com.fs.erp.domain.FsErpFinishPush;
-import com.fs.erp.dto.ErpOrderResponse;
-import com.fs.erp.mapper.FsErpFinishPushMapper;
-import com.fs.erp.service.IErpOrderService;
-import com.fs.hisStore.domain.FsStoreOrderScrm;
-import com.fs.hisStore.service.IFsStoreOrderScrmService;
-import com.fs.live.domain.LiveOrder;
-import com.fs.live.service.ILiveOrderService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.Date;
-import java.util.List;
-
-@Service("erpTask")
-public class ErpTask {
-    private static final Logger log = LoggerFactory.getLogger(ErpTask.class);
-
-    @Autowired
-    private FsErpFinishPushMapper fsErpFinishPushMapper;
-    @Autowired
-    private IErpOrderService erpOrderService;
-
-    @Autowired
-    private IFsStoreOrderScrmService fsStoreOrderService;
-
-    @Autowired
-    private ILiveOrderService liveOrderService;
-
-
-    /**
-     * 推送完成订单到ERP
-     */
-    public void pushFinishOrderToErp(){
-        List<FsErpFinishPush> fsErpFinishPushes = fsErpFinishPushMapper.queryPenddingOrder();
-        for (FsErpFinishPush fsErpFinishPush : fsErpFinishPushes) {
-            FsStoreOrderScrm fsStoreOrder = fsStoreOrderService.selectFsStoreOrderById(fsErpFinishPush.getOrderId());
-            if (fsStoreOrder != null) {
-                try {
-
-                    ErpOrder erpOrder = fsStoreOrderService.getErpOrder(fsStoreOrder);
-
-                    ErpOrderResponse erpOrderResponse = erpOrderService.finishOrder(erpOrder);
-
-                    fsErpFinishPush.setParams(erpOrderResponse.getRequestRawData());
-                    fsErpFinishPush.setResult(erpOrderResponse.getResponseRawData());
-                    fsErpFinishPush.setUpdateTime(new Date());
-
-                    if(erpOrderResponse.getSuccess()!= null && erpOrderResponse.getSuccess()){
-                        fsErpFinishPush.setTaskStatus(1);
-
-                        log.error("推送完成订单到ERP成功! 订单号: {}",fsErpFinishPush.getOrderId());
-                    } else {
-                        fsErpFinishPush.setTaskStatus(2);
-                        fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount()+1);
-                        log.error("推送完成订单到ERP失败! 订单号: {}",fsErpFinishPush.getOrderId());
-                    }
-                } catch (Throwable e) {
-                    fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount()+1);
-                    fsErpFinishPush.setErrorMessage(ExceptionUtils.getStackTrace(e));
-                    fsErpFinishPush.setTaskStatus(2);
-                    log.error("订单推送失败!原因: {}", ExceptionUtils.getStackTrace(e),e);
-                    continue;
-                }
-            } else {
-                LiveOrder liveOrder = liveOrderService.selectLiveOrderByOrderId(String.valueOf(fsErpFinishPush.getOrderId()));
-                if (liveOrder != null) {
-                    try {
-                        ErpOrder erpOrder = liveOrderService.getErpOrder(liveOrder);
-
-                        ErpOrderResponse erpOrderResponse = erpOrderService.finishOrder(erpOrder);
-
-                        fsErpFinishPush.setParams(erpOrderResponse.getRequestRawData());
-                        fsErpFinishPush.setResult(erpOrderResponse.getResponseRawData());
-                        fsErpFinishPush.setUpdateTime(new Date());
-
-                        if (erpOrderResponse.getSuccess() != null && erpOrderResponse.getSuccess()) {
-                            fsErpFinishPush.setTaskStatus(1);
-
-                            log.error("推送完成订单到ERP成功! 订单号: {}", fsErpFinishPush.getOrderId());
-                        } else {
-                            fsErpFinishPush.setTaskStatus(2);
-                            fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount() + 1);
-                            log.error("推送完成订单到ERP失败! 订单号: {}", fsErpFinishPush.getOrderId());
-                        }
-                    } catch (Throwable e) {
-                        fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount() + 1);
-                        fsErpFinishPush.setErrorMessage(ExceptionUtils.getStackTrace(e));
-                        fsErpFinishPush.setTaskStatus(2);
-                        log.error("订单推送失败!原因: {}", ExceptionUtils.getStackTrace(e), e);
-                        continue;
-                    }
-                } else {
-                    log.error("订单不存在! 订单号: {}",fsErpFinishPush.getOrderId());
-                    continue;
-                }
-            }
-
-            fsErpFinishPushMapper.updateById(fsErpFinishPush);
-        }
-
-    }
-
-}

+ 0 - 30
fs-admin-saas/src/main/java/com/fs/hisStore/task/ExpressTask.java

@@ -1,30 +0,0 @@
-package com.fs.hisStore.task;
-
-
-import com.fs.hisStore.service.IFsStoreOrderScrmService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-/**
- * 物流信息定时任务
- */
-@Component("expressTask")
-public class ExpressTask {
-    private static final Logger log = LoggerFactory.getLogger(ExpressTask.class);
-
-    @Autowired
-    private IFsStoreOrderScrmService fsStoreOrderScrmService;
-
-    public void syncExpressToWx(){
-        fsStoreOrderScrmService.syncExpressToWx();
-    }
-
-
-    //定时任务刷新订单结算状态
-    public void refreshOrderSettlementStatus(){
-        fsStoreOrderScrmService.refreshOrderSettlementStatus();
-    }
-
-}

+ 0 - 677
fs-admin-saas/src/main/java/com/fs/hisStore/task/LiveTask.java

@@ -1,677 +0,0 @@
-package com.fs.hisStore.task;
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
-import com.fs.common.core.domain.R;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.utils.DateUtils;
-import com.fs.common.utils.sql.SqlUtil;
-import com.fs.company.service.ICompanyService;
-import com.fs.company.vo.RedPacketMoneyVO;
-import com.fs.course.mapper.FsCourseRedPacketLogMapper;
-import com.fs.erp.domain.ErpDeliverys;
-import com.fs.erp.domain.ErpOrderQuery;
-import com.fs.erp.dto.ErpOrderQueryRequert;
-import com.fs.erp.dto.ErpOrderQueryResponse;
-import com.fs.erp.service.FsJstAftersalePushScrmService;
-import com.fs.erp.service.IErpOrderService;
-import com.fs.his.config.FsSysConfig;
-import com.fs.his.dto.ExpressInfoDTO;
-import com.fs.his.service.IFsExpressService;
-import com.fs.his.service.IFsUserService;
-import com.fs.his.utils.ConfigUtil;
-import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
-import com.fs.hisStore.dto.DateComparisonConfigDTO;
-import com.fs.hisStore.enums.ShipperCodeEnum;
-import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
-import com.fs.hisStore.param.FsStoreOrderAddTuiMoneyParam;
-import com.fs.hisStore.service.IFsStoreOrderScrmService;
-import com.fs.hisStore.service.IFsStoreProductScrmService;
-import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
-import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
-import com.fs.huifuPay.service.HuiFuService;
-import com.fs.live.domain.LiveAfterSales;
-import com.fs.live.domain.LiveOrder;
-import com.fs.live.domain.LiveOrderItem;
-import com.fs.live.domain.LiveOrderPayment;
-import com.fs.live.mapper.LiveOrderItemMapper;
-import com.fs.live.mapper.LiveOrderMapper;
-import com.fs.live.mapper.LiveOrderPaymentMapper;
-import com.fs.live.param.LiveAfterSalesAudit1Param;
-import com.fs.live.param.LiveAfterSalesParam;
-import com.fs.live.param.LiveAfterSalesProductParam;
-import com.fs.live.service.*;
-import com.fs.pay.pay.dto.OrderQueryDTO;
-import com.fs.pay.service.IPayService;
-import com.fs.store.config.StoreConfig;
-import com.fs.system.service.ISysConfigService;
-import com.fs.ybPay.domain.OrderResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Component;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-import static com.fs.hisStore.constants.StoreConstants.DELIVERY;
-
-/**
- * 定时任务调度测试
- *
- * @author fs
- */
-@Component("liveTask")
-public class LiveTask {
-    private static final Logger log = LoggerFactory.getLogger(LiveTask.class);
-    @Autowired
-    private RedisTemplate redisTemplate;
-    @Autowired
-    private RedisCache redisCache;
-    @Autowired
-    private ILiveOrderService liveOrderService;
-
-    @Autowired
-    private ILiveCouponService liveCouponService;
-
-    @Autowired
-    private ILiveCouponIssueService liveCouponIssueService;
-    @Autowired
-    private IFsStoreProductScrmService fsStoreProductScrmService;
-
-    @Autowired
-    private ILiveAfterSalesService liveAfterSalesService;
-
-    @Autowired
-    private ILiveOrderItemService liveOrderItemService;
-
-    @Autowired
-    private ILiveOrderPaymentService liveOrderPaymentService;
-
-    @Autowired
-    private ICompanyService companyService;
-
-    @Autowired
-    @Qualifier("erpOrderServiceImpl")
-    private IErpOrderService gyOrderService;
-
-    @Autowired
-    @Qualifier("wdtErpOrderServiceImpl")
-    private IErpOrderService wdtOrderService;
-
-    @Autowired
-    @Qualifier("hzOMSErpOrderServiceImpl")
-    private IErpOrderService hzOMSOrderService;
-
-    @Autowired
-    @Qualifier("dfOrderServiceImpl")
-    private IErpOrderService dfOrderService;
-
-    @Autowired
-    @Qualifier("JSTErpOrderServiceImpl")
-    private IErpOrderService jSTOrderService;
-
-    @Autowired
-    @Qualifier("k9OrderScrmServiceImpl")
-    private IErpOrderService k9OrderService;
-
-    @Autowired
-    private ConfigUtil configUtil;
-
-    @Autowired
-    IErpOrderService erpOrderService;
-
-    @Autowired
-    private LiveOrderMapper liveOrderMapper;
-
-    @Autowired
-    private LiveOrderItemMapper liveOrderItemMapper;
-
-    @Autowired
-    private LiveOrderPaymentMapper liveOrderPaymentMapper;
-
-    @Autowired
-    private IPayService ybPayService;
-
-    @Autowired
-    private ISysConfigService configService;
-
-    @Autowired
-    private IFsExpressService expressService;
-
-    @Autowired
-    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
-
-    @Autowired
-    private JdbcTemplate jdbcTemplate;
-
-    @Autowired
-    private HuiFuService huiFuService;
-
-    @Autowired
-    private IFsStoreOrderScrmService orderService;
-
-    @Autowired
-    private FsJstAftersalePushScrmService fsJstAftersalePushScrmService;
-
-    /**
-     * 查询被拆分的订单,然后查询拆分订单的物流信息
-     */
-    public void querySplitOrderDelivery() {
-        try {
-            // 查询状态为6(被拆分)的订单
-            List<LiveOrder> splitOrders = liveOrderMapper.selectSplitOrders();
-            if (splitOrders == null || splitOrders.isEmpty()) {
-                log.debug("没有找到被拆分的订单");
-                return;
-            }
-
-            log.info("找到 {} 个被拆分的订单,开始查询拆分订单的物流信息", splitOrders.size());
-
-            IErpOrderService erpOrderService = getErpOrderService();
-            if (erpOrderService == null) {
-                log.warn("ERP服务未配置,无法查询拆分订单物流信息");
-                return;
-            }
-
-            for (LiveOrder splitOrder : splitOrders) {
-                try {
-                    // 查询该订单的所有拆分订单(通过原订单号查询)
-                    List<LiveOrder> childOrders = liveOrderMapper.selectChildOrdersByParentOrderCode(splitOrder.getOrderCode());
-                    if (childOrders == null || childOrders.isEmpty()) {
-                        log.debug("订单 {} 没有找到拆分订单", splitOrder.getOrderCode());
-                        continue;
-                    }
-
-                    // 遍历拆分订单,查询物流信息
-                    for (LiveOrder childOrder : childOrders) {
-                        if (StringUtils.isEmpty(childOrder.getExtendOrderId())) {
-                            log.debug("拆分订单 {} 没有扩展订单ID,跳过", childOrder.getOrderCode());
-                            continue;
-                        }
-
-                        // 查询ERP订单信息
-                        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-                        request.setCode(childOrder.getExtendOrderId());
-                        ErpOrderQueryResponse response = erpOrderService.getLiveOrder(request);
-
-                        if (!response.getSuccess()) {
-                            if ("429".equals(response.getCode())) {
-                                log.warn("ERP接口限流,停止查询");
-                                break;
-                            }
-                            log.warn("查询拆分订单物流信息失败, orderCode={}, error={}", childOrder.getOrderCode(), response.getCode());
-                            continue;
-                        }
-
-                        // 更新物流信息
-                        if (response.getOrders() != null && !response.getOrders().isEmpty()) {
-                            for (ErpOrderQuery orderQuery : response.getOrders()) {
-                                if (orderQuery.getDeliverys() != null && !orderQuery.getDeliverys().isEmpty()) {
-                                    for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                                        if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-                                            // 更新订单物流信息
-                                            childOrder.setDeliverySn(delivery.getMail_no());
-                                            childOrder.setDeliveryCode(delivery.getExpress_code());
-                                            childOrder.setDeliveryName(delivery.getExpress_name());
-                                            if (childOrder.getStatus() == 2) { // 待发货状态
-                                                childOrder.setStatus(3); // 更新为待收货
-                                            }
-                                            childOrder.setUpdateTime(new Date());
-                                            liveOrderMapper.updateLiveOrder(childOrder);
-                                            log.info("拆分订单物流信息已更新, orderCode={}, deliverySn={}, expressName={}",
-                                                    childOrder.getOrderCode(), delivery.getMail_no(), delivery.getExpress_name());
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } catch (Exception e) {
-                    log.error("处理拆分订单物流信息异常, orderCode={}", splitOrder.getOrderCode(), e);
-                }
-            }
-
-            log.info("拆分订单物流信息查询完成");
-        } catch (Exception e) {
-            log.error("查询拆分订单物流信息任务异常", e);
-        }
-    }
-
-    // 聚水潭 推送售后信息
-    public void pushJst(){
-        fsJstAftersalePushScrmService.pushJst();
-    }
-
-
-    // 订单银行回调数据丢失补偿
-    public void recoveryBankOrder() {
-        // 查询出来最近15分钟的订单 待支付 未退款
-        List<LiveOrder> list = liveOrderService.selectBankOrder();
-        if(list == null || list.isEmpty()) return;
-        for (LiveOrder liveOrder : list) {
-            List<LiveOrderPayment> liveOrderPayments = liveOrderPaymentMapper.selectLiveOrderPaymentByOrderId(liveOrder.getOrderId());
-            if(liveOrderPayments == null || liveOrderPayments.isEmpty()) continue;
-            for (LiveOrderPayment payment : liveOrderPayments) {
-                V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
-                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-                request.setOrgHfSeqId(payment.getTradeNo());
-                request.setAppId(payment.getAppId());
-                HuiFuQueryOrderResult o = null;
-                try {
-                    o = huiFuService.queryOrder(request);
-                } catch (Exception e) {
-                    log.error("查询失败:"+e.getMessage());
-                    continue;
-                }
-                log.info("汇付返回"+o);
-                if ("00000000".equals(o.getResp_code()) && "S".equals(o.getTrans_stat())) {
-                    String[] order=o.getOrg_req_seq_id().split("-");
-                    if ("live".equals(order[0])) {
-                        liveOrderService.payConfirm(1, null, order[1], o.getOrg_hf_seq_id(), o.getOut_trans_id(), o.getParty_order_id());
-                    }
-                }
-            }
-        }
-    }
-
-
-    public void PushErp() throws ParseException {
-        List<Long> ids = liveOrderMapper.selectOrderIdByNoErp();
-        if(ids == null) return;
-        if (ids.size() > 50) {
-            ids = ids.subList(0, 50);
-        }
-//        liveOrderService.batchUpdateTimeIds(ids);
-        // 单个异常影响全部,跳过异常单子
-        for (Long id : ids) {
-            try {
-                liveOrderService.createOmsOrder(id);
-            } catch (Exception e) {
-                log.error("创建直播oms订单失败:"+id);
-                log.error("创建直播oms订单失败:"+e.getMessage());
-            }
-
-        }
-    }
-
-    public void redPacketSubMoney() throws Exception {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-    public void redPacketAddMoney() throws Exception {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-
-    //定时任务刷新微信订单结算状态
-    public void refreshOrderSettlementStatus(){
-        liveOrderService.refreshOrderSettlementStatus();
-    }
-
-
-
-    //每5分钟执行一次
-    public void deliveryOp() {
-        List<LiveOrder> list = liveOrderService.selectUpdateExpress();
-        if(list == null || list.isEmpty()) return;
-        Date now = new Date();
-        for (LiveOrder order : list) {
-            order.setUpdateTime(now);
-            liveOrderService.updateTime(order);
-            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-            request.setCode(order.getExtendOrderId());
-            IErpOrderService erpOrderService = getErpOrderService();
-            ErpOrderQueryResponse response = erpOrderService.getLiveOrder(request);
-            if (erpOrderService != dfOrderService) {
-                if (response.getOrders() != null && !response.getOrders().isEmpty()) {
-                    for (ErpOrderQuery orderQuery : response.getOrders()) {
-                        if (orderQuery.getDeliverys() != null && !orderQuery.getDeliverys().isEmpty()) {
-                            for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                                if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-                                    //更新商订单状态 删除REDIS
-                                    liveOrderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(), delivery.getExpress_code(), delivery.getExpress_name());
-                                    redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
-    public void couponOp() {
-        // 直播优惠券过期处理,如果有对应方法则调用
-        // liveCouponService.updateFsCouponByExpire();
-    }
-
-    //退款自动处理 24小时未审核自动审核通过 每小时执行一次
-    public void refundOp() {
-        //获取所有退款申请
-        List<LiveAfterSales> list = liveAfterSalesService.selectLiveAfterSalesByDoAudit();
-        if (list != null) {
-            for (LiveAfterSales afterSales : list) {
-                //仅退款
-                if (afterSales.getRefundType().equals(0)) {
-                    LiveAfterSalesAudit1Param audit1Param = new LiveAfterSalesAudit1Param();
-                    audit1Param.setSalesId(afterSales.getId());
-                    audit1Param.setOperator("平台");
-                    liveAfterSalesService.audit1(audit1Param);
-                }
-            }
-        }
-    }
-
-    //每天执行一次
-    public void userMoneyOp() {
-        // 直播订单完成7天后给用户返现,如果有对应方法则调用
-        // List<LiveOrder> list = liveOrderService.selectLiveOrderListByFinish7Day();
-        // if (list != null) {
-        //     for (LiveOrder order : list) {
-        //         userService.addMoney(order);
-        //     }
-        // }
-    }
-
-    //每30秒执行一次
-    public void orderItemSyncOp() {
-//         同步订单项JSON,如果有对应方法则调用
-         List<LiveOrder> list = liveOrderService.selectLiveOrderItemJson();
-         for (LiveOrder storeOrder : list) {
-             LiveOrderItem parmOrderItem = new LiveOrderItem();
-             parmOrderItem.setOrderId(storeOrder.getOrderId());
-             List<LiveOrderItem> listOrderItem = liveOrderItemService.selectLiveOrderItemList(parmOrderItem);
-             if (listOrderItem.size() > 0) {
-                 String itemJson = JSONUtil.toJsonStr(listOrderItem);
-                 storeOrder.setItemJson(itemJson);
-                 liveOrderMapper.updateLiveOrderItemJson(storeOrder);
-             }
-         }
-    }
-
-    public void returnDeliveryId() {
-        IErpOrderService erpOrderService = getErpOrderService();
-        // 获取ERP订单号列表,如果有对应方法则调用
-        // List<String> list = liveOrderMapper.selectErpCode();
-        // for (String s : list) {
-        //     ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-        //     request.setCode(s);
-        //     ErpOrderQueryResponse response = erpOrderService.getOrder(request);
-        //     if (response.getOrders() != null && response.getOrders().size() > 0) {
-        //         for (ErpOrderQuery orderQuery : response.getOrders()) {
-        //             if (orderQuery.getDeliverys() != null && orderQuery.getDeliverys().size() > 0) {
-        //                 for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-        //                     if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-        //                         LiveOrder order = new LiveOrder();
-        //                         order.setExtendOrderId(s);
-        //                         order.setDeliverySn(delivery.getMail_no());
-        //                         order.setStatus(2);
-        //                         liveOrderMapper.updateDelivery(order);
-        //                     }
-        //                 }
-        //             }
-        //         }
-        //     }
-        // }
-    }
-
-    public void changeStatus() {
-//         获取需要更新物流状态的订单ID列表,如果有对应方法则调用
-//         List<Long> list = liveOrderMapper.selectOrderId();
-//         for (Long orderId : list) {
-//             LiveOrder order = liveOrderMapper.selectLiveOrderByOrderId(String.valueOf(orderId));
-//             String lastFourNumber = "";
-//             if (order.getDeliverySn() != null && order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
-//                 lastFourNumber = order.getUserPhone();
-//                 if (lastFourNumber != null && lastFourNumber.length() == 11) {
-//                     lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
-//                 }
-//             }
-//             ExpressInfoDTO dto = expressService.getExpressInfo(order.getOrderCode(), order.getDeliverySn(), order.getDeliverySn(), lastFourNumber);
-//             LiveOrder map = new LiveOrder();
-//             map.setDeliveryStatus(Integer.parseInt(dto.getState()));
-//             map.setOrderId(orderId);
-//             map.setDeliveryType(dto.getStateEx());
-//             liveOrderMapper.updateLiveOrder(map);
-//         }
-    }
-
-    public void subCompanyMoney() {
-        // 获取需要扣减公司金额的支付ID列表,如果有对应方法则调用
-        // List<Long> list = liveOrderPaymentMapper.selectPaymentIds();
-        // for (Long paymentId : list) {
-        //     LiveOrderPayment payment = liveOrderPaymentService.selectLiveOrderPaymentByPaymentId(paymentId);
-        //     if (payment.getCompanyId() != null && payment.getCompanyId() > 0) {
-        //         companyService.subCompanyPaymentMoney(payment);
-        //     }
-        // }
-    }
-
-    public void updateOrderItem() throws ParseException {
-//        List<Long> ids = liveOrderService.selectOrderIdByNoErp();
-//        for (Long id : ids) {
-//            liveOrderService.createOmsOrder(id);
-//        }
-    }
-
-    //每天执行一次
-    public void syncExpress() {
-        List<Long> ids = liveOrderService.selectSyncExpressIds();
-        for (Long id : ids) {
-            liveOrderService.syncExpress(id);
-        }
-    }
-
-    public void returnPayStatus() {
-        // 获取需要查询支付状态的支付ID列表,如果有对应方法则调用
-        // List<String> ids = liveOrderPaymentMapper.selectPayStatusIds();
-        // for (String id : ids) {
-        //     OrderQueryDTO o = new OrderQueryDTO();
-        //     o.setUpOrderId(id);
-        //     OrderResult orderResult = ybPayService.getOrder(o);
-        //     if ("0".equals(orderResult.getState())) {
-        //         String[] order = orderResult.getLowOrderId().split("-");
-        //         if (orderResult.getStatus().equals("100")) {
-        //             switch (order[0]) {
-        //                 case "live":
-        //                     liveOrderService.payConfirm(1, null, order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
-        //                 case "live_remain":
-        //                     liveOrderService.payConfirm(1, null, order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
-        //                 case "payment":
-        //                     liveOrderPaymentService.payConfirm(order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
-        //             }
-        //         }
-        //     }
-        // }
-    }
-
-    public void AddTuiMoney() {
-        // 获取需要添加推荐金额的订单ID列表,如果有对应方法则调用
-        // List<Long> ids = liveOrderMapper.selectAddTuiMoney();
-        // for (Long id : ids) {
-        //     FsStoreOrderAddTuiMoneyParam param = new FsStoreOrderAddTuiMoneyParam();
-        //     param.setOrderId(id);
-        //     liveOrderService.addTuiMoney(param);
-        // }
-    }
-
-    public void selectPayMoneyLessOne() {
-        // 获取支付金额小于1的订单列表,如果有对应方法则调用
-        // List<LiveOrder> list = liveOrderMapper.selectPayMoneyLessOne();
-        // for (LiveOrder order : list) {
-        //     LiveAfterSalesParam param = new LiveAfterSalesParam();
-        //     param.setOrderCode(order.getOrderCode());
-        //     param.setServiceType(0);
-        //     param.setRefundAmount(order.getPayMoney());
-        //     param.setReasons("超时未处理,自动申请退款");
-        //     List<LiveAfterSalesProductParam> productParams = new ArrayList<>();
-        //     List<LiveOrderItem> items = liveOrderItemMapper.selectLiveOrderItemByOrderId(order.getOrderId());
-        //     for (LiveOrderItem item : items) {
-        //         LiveAfterSalesProductParam param1 = new LiveAfterSalesProductParam();
-        //         param1.setProductId(item.getProductId());
-        //         param1.setNum(item.getNum());
-        //         productParams.add(param1);
-        //     }
-        //     param.setProductList(productParams);
-        //     liveAfterSalesService.applyForAfterSales(order.getUserId(), param);
-        // }
-    }
-
-    public void deleteCustomer() {
-        // 删除客户逻辑
-    }
-
-    private IErpOrderService getErpOrderService() {
-        //判断是否开启erp
-        IErpOrderService erpOrderService = null;
-        FsSysConfig erpConfig = configUtil.getSysConfig();
-        Integer erpOpen = erpConfig.getErpOpen();
-        if (erpOpen != null && erpOpen == 1) {
-            //判断erp类型
-            Integer erpType = erpConfig.getErpType();
-            if (erpType != null) {
-                if (erpType == 1) {
-                    //管易
-                    erpOrderService = gyOrderService;
-                } else if (erpType == 2) {
-                    //旺店通
-                    erpOrderService = wdtOrderService;
-                } else if (erpType == 3) {
-                    //代服
-                    erpOrderService = hzOMSOrderService;
-                } else if (erpType == 4) {
-                    //瀚智
-                    erpOrderService = dfOrderService;
-                } else if (erpType == 5) {
-                    erpOrderService = jSTOrderService;
-                } else if (erpType == 6) {
-                    erpOrderService = k9OrderService;
-                }
-            }
-        }
-        return erpOrderService;
-    }
-
-    /**
-     * 提醒证件到期任务
-     */
-    public void remindCertValidation() {
-        log.info("提醒店铺证件到期任务执行... 当前时间: {}", LocalTime.now());
-
-        // 从配置表获取需要比较的表和字段
-        List<DateComparisonConfigDTO> tablesToCheck = jdbcTemplate.query(
-                "SELECT table_name, date_column,in_advance,user_column,phone_column,remind_words,platform,cert_type" +
-                        " FROM date_comparison_config", (rs, rowNum) -> {
-                    return DateComparisonConfigDTO.builder()
-                            .tableName(rs.getString("table_name"))//表名
-                            .certType(rs.getString("cert_type"))//证件类型
-                            .dateColumn(rs.getString("date_column"))//日期字段
-                            .userColumn(rs.getString("user_column"))//用户字段
-                            .remindWords(rs.getString("remindWords"))//提醒内容
-                            .phoneColumn(rs.getString("phone_column"))//提醒手机
-                            .inAdvance(rs.getInt("inAdvance"))//提前天数
-                            .platform(rs.getString("platform")).build();//平台
-                });
-
-        tablesToCheck.forEach(dto -> {
-            // 校验SQL标识符安全
-            SqlUtil.validateIdentifier(dto.getTableName());
-            SqlUtil.validateIdentifier(dto.getUserColumn());
-            SqlUtil.validateIdentifier(dto.getPhoneColumn());
-            SqlUtil.validateIdentifier(dto.getDateColumn());
-            //获取证件失效日期字段小于当前时间加提前天数的用户和电话号码
-            String sql = String.format("SELECT %s , %s " +
-                            "FROM %s " +
-                            "WHERE %s >= DATE_SUB(CURDATE(), INTERVAL %d DAY)",
-                    dto.getUserColumn(),
-                    dto.getPhoneColumn(),
-                    dto.getTableName(),
-                    dto.getDateColumn(),
-                    dto.getInAdvance()
-            );
-            List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
-            users.forEach(user -> {
-                String userName = (String) user.get(dto.getUserColumn());
-                String phone = (String) user.get(dto.getPhoneColumn());
-                String remindWords = String.format("【%s平台提示】尊敬的%s用户,店铺%s证件即将到期,请及时处理!",
-                        dto.getPlatform(),
-                        userName,
-                        dto.getCertType());
-                // 使用phone发送remindWords短信
-                // TODO 发送通知
-            });
-        });
-    }
-
-    /**
-     * 禁用店铺
-     */
-    public void disable() {
-        log.info("禁用店铺任务执行... 当前时间: {}", LocalTime.now());
-        // 从配置表获取需要禁用的表和字段
-        List<DateComparisonConfigDTO> toDisable = jdbcTemplate.query(
-                "SELECT table_name, date_column,invalid_expression,status_column" +
-                        " FROM date_comparison_config " +
-                        " WHERE is_do_invalid = '1'", (rs, rowNum) -> DateComparisonConfigDTO.builder()
-                        .tableName(rs.getString("table_name"))//表名
-                        .dateColumn(rs.getString("date_column"))//日期字段
-                        .invalidExpression(rs.getString("invalid_expression"))//失效表达式
-                        .statusColumn(rs.getString("status_column"))//状态字段
-                        .build());
-
-        toDisable.forEach(dto -> {
-            // 校验SQL标识符安全
-            SqlUtil.validateIdentifier(dto.getTableName());
-            SqlUtil.validateIdentifier(dto.getDateColumn());
-            SqlUtil.validateIdentifier(dto.getStatusColumn());
-            //更新证件失效日期字段小于当前时间的数据
-            String sql = String.format("UPDATE %s " +
-                            "SET %s = %s " +
-                            "WHERE %s < CURDATE()",
-                    dto.getTableName(),
-                    dto.getStatusColumn(),
-                    dto.getInvalidExpression(),
-                    dto.getDateColumn());
-            jdbcTemplate.update(sql);
-        });
-    }
-
-    public void getOrderDeliveryStatus() {
-        IErpOrderService erpOrderService = getErpOrderService();
-        List<LiveOrder> orders = null;
-        if (erpOrderService != null && erpOrderService == dfOrderService) {
-            // 获取已发货订单列表,如果有对应方法则调用
-             orders = liveOrderMapper.selectShippedOrder();
-             if (orders != null && !orders.isEmpty()) {
-                 List<CompletableFuture<Void>> futures = new ArrayList<>();
-                 for (LiveOrder order : orders) {
-                     CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
-                         erpOrderService.getOrderLiveDeliveryStatus(order);
-                     });
-                     futures.add(future);
-                 }
-                 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
-             }
-        }
-    }
-}

+ 0 - 723
fs-admin-saas/src/main/java/com/fs/hisStore/task/MallStoreTask.java

@@ -1,723 +0,0 @@
-package com.fs.hisStore.task;
-
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
-import com.fs.common.core.domain.R;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.utils.DateUtils;
-import com.fs.common.utils.sql.SqlUtil;
-import com.fs.company.service.ICompanyService;
-import com.fs.company.vo.RedPacketMoneyVO;
-import com.fs.course.mapper.FsCourseRedPacketLogMapper;
-import com.fs.erp.domain.ErpDeliverys;
-import com.fs.erp.domain.ErpGoods;
-import com.fs.erp.domain.ErpOrderQuery;
-import com.fs.erp.dto.ErpGoodsQueryRequert;
-import com.fs.erp.dto.ErpGoodsQueryResponse;
-import com.fs.erp.dto.ErpOrderQueryRequert;
-import com.fs.erp.dto.ErpOrderQueryResponse;
-import com.fs.erp.service.IErpGoodsService;
-import com.fs.erp.service.IErpOrderService;
-import com.fs.his.config.FsSysConfig;
-import com.fs.his.domain.FsStoreProductAttrValue;
-import com.fs.his.dto.ExpressInfoDTO;
-import com.fs.his.mapper.FsStoreProductAttrValueMapper;
-import com.fs.his.service.IFsExpressService;
-import com.fs.his.service.IFsUserService;
-import com.fs.his.utils.ConfigUtil;
-import com.fs.hisStore.domain.*;
-import com.fs.hisStore.dto.DateComparisonConfigDTO;
-import com.fs.hisStore.enums.ShipperCodeEnum;
-import com.fs.hisStore.mapper.FsStoreOrderItemScrmMapper;
-import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
-import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
-import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
-import com.fs.hisStore.param.*;
-import com.fs.hisStore.service.*;
-import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
-import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
-import com.fs.huifuPay.service.HuiFuService;
-import com.fs.live.domain.LiveOrder;
-import com.fs.live.domain.LiveOrderPayment;
-import com.fs.pay.pay.dto.OrderQueryDTO;
-import com.fs.pay.service.IPayService;
-import com.fs.store.config.StoreConfig;
-import com.fs.system.service.ISysConfigService;
-import com.fs.ybPay.domain.OrderResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Component;
-
-import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-import static com.fs.hisStore.constants.StoreConstants.DELIVERY;
-
-/**
- * 定时任务调度测试
- *
- * @author fs
- */
-@Component("mallStoreTask")
-public class MallStoreTask
-{
-    private static final Logger log = LoggerFactory.getLogger(MallStoreTask.class);
-    @Autowired
-    private RedisTemplate redisTemplate;
-    @Autowired
-    private RedisCache redisCache;
-    @Autowired
-    private IFsStoreOrderScrmService orderService;
-    @Autowired
-    private IFsStoreCouponUserScrmService couponUserService;
-    @Autowired
-    private IFsStoreAfterSalesScrmService afterSalesService;
-    @Autowired
-    private IFsUserService userService;
-    @Autowired
-    private IPayService ybPayService;
-    @Autowired
-    private FsStoreOrderScrmMapper fsStoreOrderMapper;
-
-    @Autowired
-    private IFsStoreOrderScrmService fsStoreOrderService;
-
-    @Autowired
-    private IFsStoreOrderItemScrmService storeOrderItemService;
-
-    @Autowired
-    private FsStorePaymentScrmMapper fsStorePaymentMapper;
-
-
-    @Autowired
-    private IErpGoodsService erpGoodsService;
-    @Autowired
-    private ISysConfigService configService;
-    @Autowired
-    private FsStoreProductAttrValueMapper fsStoreProductAttrValueMapper;
-    @Autowired
-    private FsStorePaymentScrmMapper paymentMapper;
-    @Autowired
-    private IFsStorePaymentScrmService fsStorePaymentService;
-    @Autowired
-    private ICompanyService companyService;
-
-
-    @Autowired
-    private IFsExpressService expressService;
-
-    @Autowired
-    private FsStoreOrderItemScrmMapper itemMapper;
-
-    @Autowired
-    private IFsStoreAfterSalesScrmService fsStoreAfterSalesService;
-
-    @Autowired
-    @Qualifier("erpOrderServiceImpl")
-    private IErpOrderService gyOrderService;
-
-    @Autowired
-    @Qualifier("wdtErpOrderServiceImpl")
-    private IErpOrderService wdtOrderService;
-
-    @Autowired
-    @Qualifier("hzOMSErpOrderServiceImpl")
-    private IErpOrderService hzOMSOrderService;
-
-    @Autowired
-    @Qualifier("dfOrderServiceImpl")
-    private IErpOrderService dfOrderService;
-
-    @Autowired
-    @Qualifier("JSTErpOrderServiceImpl")
-    private IErpOrderService jSTOrderService;
-
-    @Autowired
-    @Qualifier("k9OrderScrmServiceImpl")
-    private IErpOrderService k9OrderService;
-
-    @Autowired
-    private ConfigUtil configUtil;
-
-    @Autowired
-    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
-
-
-    @Autowired
-    IErpOrderService erpOrderService;
-
-    //@Autowired
-    //private IFsUserWatchCourseStatisticsService fsUserWatchCourseStatisticsService;
-
-    //@Autowired
-    //private IFsUserWatchStatisticsService fsUserWatchStatisticsService;
-
-    //@Autowired
-    //private IFsUserOnlineStateService fsUserOnlineStateService;
-    @Autowired
-    private HuiFuService huiFuService;
-
-    // 订单银行回调数据丢失补偿
-    public void recoveryBankOrder() {
-        // 查询出来最近30分钟的订单 待支付 未退款
-        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectBankOrder();
-        if(list == null || list.isEmpty()) return;
-        for (FsStoreOrderScrm order : list) {
-            List<FsStorePaymentScrm> orderPayments = fsStorePaymentMapper.selectNoPayByOrderId(order.getId());
-            if(orderPayments == null || orderPayments.isEmpty()) continue;
-            for (FsStorePaymentScrm payment : orderPayments) {
-                V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
-                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-                request.setOrgHfSeqId(payment.getTradeNo());
-                request.setAppId(payment.getAppId());
-                HuiFuQueryOrderResult o = null;
-                try {
-                    o = huiFuService.queryOrder(request);
-                } catch (Exception e) {
-                    log.error("查询失败:"+e.getMessage());
-                    continue;
-                }
-                log.info("汇付返回"+o);
-                if ("00000000".equals(o.getResp_code()) && "S".equals(o.getTrans_stat())) {
-                    String[] orderSpilt=o.getOrg_req_seq_id().split("-");
-                    if ("store".equals(orderSpilt[0])) {
-                        orderService.payConfirm(1, null, orderSpilt[1], o.getOrg_hf_seq_id(), o.getOut_trans_id(), o.getParty_order_id());
-                    }
-                }
-            }
-        }
-    }
-
-    public void PushErp() throws ParseException {
-        List<Long> ids;
-        // 开启审核
-        if (getAuditSwitch()) {
-            ids = fsStoreOrderMapper.selectFsStoreOrderNoCreateOmsAndReviewed();
-        } else {
-            ids = fsStoreOrderMapper.selectFsStoreOrderNoCreateOms();
-        }
-        if (!ids.isEmpty() && ids.size() > 50) {
-            ids = ids.subList(0, 50);
-        }
-        // 单个异常影响全部,跳过异常单子
-        for (Long id : ids) {
-            try {
-                R omsOrder = fsStoreOrderService.createOmsOrder(id);
-                if ("500".equals(omsOrder.get("code"))) {
-
-                }
-            } catch (Exception e) {
-                log.error("创建商城oms订单失败:"+id);
-                log.error("创建商城oms订单失败:"+e.getMessage());
-            }
-
-        }
-    }
-
-    /**
-     * 获取是否需要订单审核
-     * @return boolean
-     */
-    private boolean getAuditSwitch() {
-        try {
-            String json = configService.selectConfigByKey("store.config");
-            StoreConfig config = JSONUtil.toBean(json,StoreConfig.class);
-            return config.getAuditSwitch() == 1;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    public void redPacketSubMoney() throws Exception
-    {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-    public void redPacketAddMoney() throws Exception
-    {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-    //每5分钟执行一次
-    public void deliveryOp()
-    {
-        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectUpdateExpress();
-        Date nowDate = DateUtils.getNowDate();
-        for (FsStoreOrderScrm order : list){
-            order.setUpdateTime(new Date());
-            orderService.updateFsStoreOrderDb(order);
-            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-            request.setCode(order.getExtendOrderId());
-            IErpOrderService erpOrderService = getErpOrderService();
-            ErpOrderQueryResponse response = erpOrderService.getScrmOrder(request);
-            if (erpOrderService != dfOrderService) {
-                if(response.getOrders()!=null && !response.getOrders().isEmpty()){
-                    for(ErpOrderQuery orderQuery : response.getOrders()){
-                        if (orderQuery.getDeliverys() != null && !orderQuery.getDeliverys().isEmpty()) {
-                            for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                                if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-                                    //更新商订单状态 删除REDIS
-                                    orderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(), delivery.getExpress_code(), delivery.getExpress_name());
-                                    redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
-                                }
-                            }
-
-                        }
-                    }
-
-                }
-            }
-        }
-
-    }
-
-
-    //定时任务刷新微信订单结算状态
-    public void refreshOrderSettlementStatus(){
-        fsStoreOrderService.refreshOrderSettlementStatus();
-    }
-
-
-    public void storeProdUpdateCostPrice()
-    {
-        String json=configService.selectConfigByKey("store.config");
-        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
-
-        List<FsStoreProductAttrValue> values = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueList(new FsStoreProductAttrValue());
-        for (FsStoreProductAttrValue value : values) {
-            ErpGoodsQueryRequert query = new ErpGoodsQueryRequert();
-            query.setCode(value.getBarCode());
-            ErpGoodsQueryResponse goods = erpGoodsService.getGoods(query);
-            List<ErpGoods> items = goods.getItems();
-
-            if (items!=null&&items.size()>0){
-                ErpGoods erpGoods = items.get(0);
-                BigDecimal salesPrice = erpGoods.getSales_price();
-                if (salesPrice!=null&&salesPrice.compareTo(BigDecimal.ZERO) != 0){
-                    BigDecimal divide = salesPrice.multiply(new BigDecimal(config.getSalesPriceRate())).divide(new BigDecimal("100"));
-                    System.out.println("代理价格"+divide);
-                    System.out.println("成本价"+salesPrice);
-                    FsStoreProductAttrValue va = new FsStoreProductAttrValue();
-                    va.setCost(salesPrice);
-                    va.setAgentPrice(divide);
-                    va.setId(value.getId());
-                    fsStoreProductAttrValueMapper.updateFsStoreProductAttrValue(va);
-                }
-            }
-            System.out.println(goods);
-        }
-    }
-
-
-    @Autowired
-    private FsStoreProductAttrValueScrmMapper fsStoreProductAttrValueScrmMapper;
-
-    public void storeProdUpdateCostPriceScrm()
-    {
-        String json=configService.selectConfigByKey("store.config");
-        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
-
-        List<FsStoreProductAttrValueScrm> values = fsStoreProductAttrValueScrmMapper.selectFsStoreProductAttrValueList(new FsStoreProductAttrValueScrm());
-        for (FsStoreProductAttrValueScrm value : values) {
-            ErpGoodsQueryRequert query = new ErpGoodsQueryRequert();
-            query.setCode(value.getBarCode());
-            ErpGoodsQueryResponse goods = erpGoodsService.getGoodsScrm(query);
-            List<ErpGoods> items = goods.getItems();
-
-            if (items!=null&&items.size()>0){
-                ErpGoods erpGoods = items.get(0);
-                BigDecimal salesPrice = erpGoods.getSales_price();
-                if (salesPrice!=null&&salesPrice.compareTo(BigDecimal.ZERO) != 0){
-                    BigDecimal divide = salesPrice.multiply(new BigDecimal(config.getSalesPriceRate())).divide(new BigDecimal("100"));
-                    System.out.println("代理价格"+divide);
-                    System.out.println("成本价"+salesPrice);
-                    FsStoreProductAttrValueScrm va = new FsStoreProductAttrValueScrm();
-                    va.setCost(salesPrice);
-                    va.setAgentPrice(divide);
-                    va.setId(value.getId());
-                    fsStoreProductAttrValueScrmMapper.updateFsStoreProductAttrValue(va);
-                }
-            }
-            System.out.println(goods);
-        }
-    }
-    public void couponOp()
-    {
-        couponUserService.updateFsCouponByExpire();
-
-    }
-
-
-    //退款自动处理 24小时未审核自动审核通过 每小时执行一次
-    public void refundOp()
-    {
-        //获取所有退款申请
-        List<FsStoreAfterSalesScrm> list=afterSalesService.selectFsStoreAfterSalesByDoAudit();
-        if(list!=null){
-            for(FsStoreAfterSalesScrm afterSales:list){
-                //仅退款
-                if(afterSales.getServiceType().equals(0)){
-                    FsStoreAfterSalesAudit1Param audit1Param=new FsStoreAfterSalesAudit1Param();
-                    audit1Param.setSalesId(afterSales.getId());
-                    audit1Param.setOperator("平台");
-                    afterSalesService.audit1(audit1Param);
-                }
-            }
-        }
-    }
-
-
-    //每天执行一次
-    public void userMoneyOp()
-    {
-        List<FsStoreOrderScrm> list=orderService.selectFsStoreOrderListByFinish7Day();
-        if(list!=null){
-            for(FsStoreOrderScrm order:list){
-                userService.addMoney(order);
-            }
-        }
-    }
-
-
-    //每30秒执行一次
-    public void orderItemSyncOp(){
-        List<FsStoreOrderScrm> list = fsStoreOrderService.selectFsStoreOrderItemJson();
-        for(FsStoreOrderScrm storeOrder:list){
-            FsStoreOrderItemScrm parmOrderItem=new FsStoreOrderItemScrm();
-            parmOrderItem.setOrderId(storeOrder.getId());
-            List<FsStoreOrderItemScrm> listOrderItem=storeOrderItemService.selectFsStoreOrderItemList(parmOrderItem);
-            if(listOrderItem.size()>0){
-                String itemJson= JSONUtil.toJsonStr(listOrderItem);
-                storeOrder.setItemJson(itemJson);
-                fsStoreOrderMapper.uploadItemJson(storeOrder);
-            }
-        }
-    }
-
-    public void returnDeliveryId(){
-        IErpOrderService erpOrderService = getErpOrderService();
-        List<String> list = fsStoreOrderMapper.selectErpCode();
-        for (String s : list) {
-            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-            request.setCode(s);
-            ErpOrderQueryResponse response = erpOrderService.getOrder(request);
-            if(response.getOrders()!=null&&response.getOrders().size()>0){
-                    for(ErpOrderQuery orderQuery : response.getOrders()){
-                        if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
-                            for(ErpDeliverys delivery:orderQuery.getDeliverys()){
-                                if(delivery.getDelivery()&&StringUtils.isNotEmpty(delivery.getMail_no())){
-                                    FsStoreOrderScrm order = new FsStoreOrderScrm();
-                                    order.setExtendOrderId(s);
-                                    order.setDeliveryId(delivery.getMail_no());
-                                    order.setStatus(2);
-                                    fsStoreOrderMapper.updateDelivery(order);
-                                }
-                            }
-                        }
-                    }
-                }
-
-
-        }
-
-    }
-
-    public void changeStatus(){
-        List<Long> list  = fsStoreOrderMapper.selectOrderId();
-        for (Long orderId : list){
-            FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
-            String lastFourNumber = "";
-            if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())  || order.getDeliverySn().equals(ShipperCodeEnum.ZTO.getValue())) {
-                lastFourNumber = order.getUserPhone();
-                if (lastFourNumber.length() == 11) {
-                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
-                }
-            }
-            ExpressInfoDTO dto=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
-            FsStoreOrderScrm map=new FsStoreOrderScrm();
-            map.setDeliveryStatus(Integer.parseInt(dto.getState()));
-            map.setId(order.getId());
-            map.setDeliveryType(dto.getStateEx());
-            fsStoreOrderMapper.updateFsStoreOrder(map);
-        }
-    }
-
-
-
-    public void subCompanyMoney(){
-        List<Long> list = paymentMapper.selectPaymentIds();
-        for (Long paymentId : list){
-            FsStorePaymentScrm payment=fsStorePaymentService.selectFsStorePaymentById(paymentId);
-            if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
-                companyService.subCompanyPaymentMoney(payment);
-            }
-        }
-    }
-
-
-    public void updateOrderItem() throws ParseException {
-        List <Long> ids = itemMapper.selectOrderIdByNoErp();
-        for (Long id:ids){
-            fsStoreOrderService.createOmsOrder(id);
-        }
-    }
-
-
-
-    //每天执行一次
-    public void syncExpress()
-    {
-        List<Long> ids =fsStoreOrderMapper.selectSyncExpressIdsNoDate();
-
-        for (Long id : ids) {
-            FsStoreOrderExpressEditParam param =new FsStoreOrderExpressEditParam();
-            param.setOrderId(id);
-            fsStoreOrderService.syncExpress(param);
-        }
-
-    }
-
-    public void returnPayStatus() {
-        List<String> ids =fsStorePaymentMapper.selectPayStatusIds();
-        for (String id : ids) {
-            OrderQueryDTO o = new OrderQueryDTO();
-            o.setUpOrderId(id);
-            OrderResult orderResult = ybPayService.getOrder(o);
-            if ("0".equals(orderResult.getState())){
-                String[] order=orderResult.getLowOrderId().split("-");
-                if(orderResult.getStatus().equals("100")){
-                    switch (order[0]) {
-                        case "store":
-                            orderService.payConfirm(1,null,order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
-                        case "store_remain":
-                            orderService.payRemainConfirm( order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
-                        case "payment":
-                            fsStorePaymentService.payConfirm(order[1],o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
-                    }
-
-                }
-            }
-
-        }
-
-    }
-
-    public void AddTuiMoney()
-    {
-        List<Long> ids =fsStoreOrderMapper.selectAddTuiMoney();
-        for (Long id : ids) {
-            FsStoreOrderAddTuiMoneyParam param = new FsStoreOrderAddTuiMoneyParam();
-            param.setOrderId(id);
-            fsStoreOrderService.addTuiMoney(param);
-        }
-
-    }
-
-
-    public void selectPayMoneyLessOne(){
-        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectPayMoneyLessOne();
-        for (FsStoreOrderScrm order : list){
-            FsStoreAfterSalesParam param = new FsStoreAfterSalesParam();
-            param.setOrderCode(order.getOrderCode());
-            param.setServiceType(0);
-            param.setRefundAmount(order.getPayMoney());
-            param.setReasons("超时未处理,自动申请退款");
-            List<FsStoreAfterSalesProductParam> productParams = new ArrayList<>();
-            List <FsStoreOrderItemScrm> items = fsStoreOrderMapper.selectOrderItem(order.getId());
-            for (FsStoreOrderItemScrm item : items){
-                FsStoreAfterSalesProductParam param1 = new FsStoreAfterSalesProductParam();
-                param1.setProductId(item.getProductId());
-                param1.setNum(item.getNum());
-                productParams.add(param1);
-            }
-            param.setProductList(productParams);
-            fsStoreAfterSalesService.autoApplyForAfterSales(order.getUserId(),param);
-        }
-    }
-
-    public  void deleteCustomer(){
-
-    }
-
-    private IErpOrderService getErpOrderService(){
-        //判断是否开启erp
-        IErpOrderService erpOrderService = null;
-        FsSysConfig erpConfig = configUtil.getSysConfig();
-        Integer erpOpen = erpConfig.getErpOpen();
-        if (erpOpen != null && erpOpen == 1) {
-            //判断erp类型
-            Integer erpType = erpConfig.getErpType();
-            if (erpType != null) {
-                if (erpType == 1) {
-                    //管易
-                    erpOrderService = gyOrderService;
-                } else if (erpType == 2) {
-                    //旺店通
-                    erpOrderService = wdtOrderService;
-                } else if (erpType == 3) {
-                    //代服
-                    erpOrderService = hzOMSOrderService;
-                } else if (erpType == 4) {
-                    //瀚智
-                    erpOrderService = dfOrderService;
-                } else if (erpType == 5) {
-                    erpOrderService = jSTOrderService;
-                }else if (erpType == 6) {
-                    erpOrderService = k9OrderService;
-                }
-            }
-        }
-        return erpOrderService;
-    }
-
-    /**
-     * 添加看课汇总统计
-     */
-    /*public void insertWatchStatistics(){
-        *//***************************************进入营期会员看课汇总统计定时任务****************************************//*
-        fsUserWatchStatisticsService.insertStatistics();
-        *//***************************************营期会员看课汇总统计定时任务结束***************************************//*
-    }*/
-
-    /**
-     * 添加看课明细统计
-     */
-    /*public void insertWatchCourseStatistics(){
-        *//***************************************进入营期会员看课明细统计定时任务*******************************//*
-        fsUserWatchCourseStatisticsService.insertWatchCourseStatistics();
-        *//***************************************进入营期会员看课明细统计定时任务结束**********************************************//*
-    }*/
-
-    /**
-     * 定时查询未上线的用户
-     */
-    /*public void insertUserNotOnline(){
-        fsUserOnlineStateService.insertUserNotOnline();
-    }*/
-
-    /**
-     * 提醒证件到期任务
-     * */
-    @Autowired
-    private JdbcTemplate jdbcTemplate;
-    public void remindCertValidation() {
-        log.info("提醒店铺证件到期任务执行... 当前时间: {}", LocalTime.now());
-
-        // 从配置表获取需要比较的表和字段
-        List<DateComparisonConfigDTO> tablesToCheck = jdbcTemplate.query(
-                "SELECT table_name, date_column,in_advance,user_column,phone_column,remind_words,platform,cert_type" +
-                        " FROM date_comparison_config",(rs, rowNum)->{
-                    return DateComparisonConfigDTO.builder()
-                            .tableName(rs.getString("table_name"))//表名
-                            .certType(rs.getString("cert_type"))//证件类型
-                            .dateColumn(rs.getString("date_column"))//日期字段
-                            .userColumn(rs.getString("user_column"))//用户字段
-                            .remindWords(rs.getString("remindWords"))//提醒内容
-                            .phoneColumn(rs.getString("phone_column"))//提醒手机
-                            .inAdvance(rs.getInt("inAdvance"))//提前天数
-                            .platform(rs.getString("platform")).build();//平台
-                });
-
-        tablesToCheck.forEach(dto -> {
-            // 校验SQL标识符安全
-            SqlUtil.validateIdentifier(dto.getTableName());
-            SqlUtil.validateIdentifier(dto.getUserColumn());
-            SqlUtil.validateIdentifier(dto.getPhoneColumn());
-            SqlUtil.validateIdentifier(dto.getDateColumn());
-            //获取证件失效日期字段小于当前时间加提前天数的用户和电话号码
-            String sql = String.format("SELECT %s , %s " +
-                            "FROM %s " +
-                            "WHERE %s >= DATE_SUB(CURDATE(), INTERVAL %d DAY)",
-                            dto.getUserColumn(),
-                            dto.getPhoneColumn(),
-                            dto.getTableName(),
-                            dto.getDateColumn(),
-                            dto.getInAdvance()
-                            );
-            List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
-            users.forEach(user -> {
-                String userName = (String) user.get(dto.getUserColumn());
-                String phone = (String) user.get(dto.getPhoneColumn());
-                String remindWords = String.format("【%s平台提示】尊敬的%s用户,店铺%s证件即将到期,请及时处理!",
-                        dto.getPlatform(),
-                        userName,
-                        dto.getCertType());
-                // 使用phone发送remindWords短信
-                // TODO 发送通知
-            });
-        });
-
-    }
-
-    /**
-     * 禁用店铺
-     * */
-    public void disable() {
-        log.info("禁用店铺任务执行... 当前时间: {}", LocalTime.now());
-        // 从配置表获取需要禁用的表和字段
-        List<DateComparisonConfigDTO> toDisable = jdbcTemplate.query(
-                "SELECT table_name, date_column,invalid_expression,status_column" +
-                        " FROM date_comparison_config " +
-                        " WHERE is_do_invalid = '1'",(rs, rowNum)-> DateComparisonConfigDTO.builder()
-                                .tableName(rs.getString("table_name"))//表名
-                                .dateColumn(rs.getString("date_column"))//日期字段
-                                .invalidExpression(rs.getString("invalid_expression"))//失效表达式
-                                .statusColumn(rs.getString("status_column"))//状态字段
-                                .build());
-
-        toDisable.forEach(dto -> {
-            // 校验SQL标识符安全
-            SqlUtil.validateIdentifier(dto.getTableName());
-            SqlUtil.validateIdentifier(dto.getDateColumn());
-            SqlUtil.validateIdentifier(dto.getStatusColumn());
-            //更新证件失效日期字段小于当前时间的数据
-            String sql = String.format("UPDATE %s " +
-                    "SET %s = %s " +
-                    "WHERE %s < CURDATE()",
-                    dto.getTableName(),
-                    dto.getStatusColumn(),
-                    dto.getInvalidExpression(),
-                    dto.getDateColumn());
-            jdbcTemplate.update(sql);
-        });
-    }
-
-    public void getOrderDeliveryStatus()
-    {
-        IErpOrderService erpOrderService = getErpOrderService();
-        List<FsStoreOrderScrm> orders = null;
-        if (erpOrderService != null && erpOrderService == dfOrderService) {
-            orders = fsStoreOrderMapper.selectShippedOrder();
-            if (orders != null && !orders.isEmpty()) {
-                List<CompletableFuture<Void>> futures = new ArrayList<>();
-                for (FsStoreOrderScrm order : orders) {
-                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
-                        erpOrderService.getOrderScrmDeliveryStatus(order);
-                    });
-                    futures.add(future);
-                }
-                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
-            }
-        }
-    }
-
-}

+ 0 - 19
fs-admin-saas/src/main/java/com/fs/hisStore/task/stats/FsStatsMemberDailyTask.java

@@ -1,19 +0,0 @@
-package com.fs.hisStore.task.stats;
-
-import com.fs.statis.service.IFsStatsMemberDailyService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class FsStatsMemberDailyTask {
-    private static final Logger log = LoggerFactory.getLogger(FsStatsMemberDailyTask.class);
-
-    @Autowired
-    private IFsStatsMemberDailyService fsStatsMemberDailyService;
-
-    public void refreshMemberDailyData() {
-        fsStatsMemberDailyService.refreshMemberDailyData();
-    }
-}

+ 0 - 50
fs-admin-saas/src/main/java/com/fs/task/SgTestController.java

@@ -1,50 +0,0 @@
-package com.fs.task;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
- import com.fs.company.service.IStatisticManageService;
-
-import javax.annotation.Resource;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * @description:
- * @author: Guos
- * @time: 2025/10/23 下午2:18
- */
-@RestController
-@RequestMapping("/sg/test")
-public class SgTestController {
-
-    @Resource
-    private SyncTuLinStudentInfoTask syncTuLinStudentInfoTask;
-
-    @Resource
-    private IStatisticManageService iStatisticManageService;
-
-
-    @RequestMapping("/execute")
-    public void execute(){
-        syncTuLinStudentInfoTask.execute();
-    }
-
-    @RequestMapping("/statistic")
-    public void executeTask(@RequestParam(required = false) String dateTime){
-        Date date = null;
-        if (dateTime != null && !dateTime.isEmpty()) {
-            try {
-                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-                date = sdf.parse(dateTime);
-            } catch (ParseException e) {
-                // 处理日期解析异常
-                e.printStackTrace();
-            }
-        }
-        iStatisticManageService.executeTask(date);
-    }
-
-}

+ 14 - 1
fs-admin/pom.xml

@@ -95,7 +95,7 @@
 
 
 
-        <!-- 定时任务-->
+        <!-- 定时任务框架 -->
         <dependency>
             <groupId>com.fs</groupId>
             <artifactId>fs-quartz</artifactId>
@@ -106,6 +106,19 @@
                 </exclusion>
             </exclusions>
         </dependency>
+
+        <!-- 统一定时任务 Bean 模块(包含所有 Task 实现 + TaskRegistry + 手动触发接口) -->
+        <dependency>
+            <groupId>com.fs</groupId>
+            <artifactId>fs-task</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.tomcat</groupId>
+                    <artifactId>annotations-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
         <!-- lombok -->
         <dependency>
             <groupId>org.projectlombok</groupId>

+ 0 - 2
fs-admin/src/main/java/com/fs/FSApplication.java

@@ -10,14 +10,12 @@ import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.FilterType;
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.Transactional;
 
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, RedissonAutoConfiguration.class})
 @Transactional
 @EnableCaching
 @EnableAsync
-@EnableScheduling
 public class FSApplication {
     public static void main(String[] args) {
         SpringApplication.run(FSApplication.class, args);

+ 113 - 0
fs-admin/src/main/java/com/fs/admin/controller/monitor/TenantJobController.java

@@ -0,0 +1,113 @@
+package com.fs.admin.controller.monitor;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.enums.DataSourceType;
+import com.fs.quartz.domain.SysJobTemplate;
+import com.fs.quartz.domain.TenantJobConfig;
+import com.fs.quartz.dto.TenantJobConfigSaveDTO;
+import com.fs.quartz.service.ISysJobTemplateService;
+import com.fs.quartz.service.ITenantJobConfigService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 租户级定时任务管理:模板 → 自动同步 → 总后台开关控制
+ */
+@DataSource(DataSourceType.MASTER)
+@RestController
+@RequestMapping("/monitor/tenantJob")
+public class TenantJobController extends BaseController {
+
+    @Resource
+    private ISysJobTemplateService sysJobTemplateService;
+    @Resource
+    private ITenantJobConfigService tenantJobConfigService;
+
+    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
+    @GetMapping("/template/list")
+    public TableDataInfo templateList(SysJobTemplate query) {
+        startPage();
+        List<SysJobTemplate> list = sysJobTemplateService.selectTemplateList(query);
+        return getDataTable(list);
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
+    @GetMapping("/template/tenantScope")
+    public AjaxResult tenantScopeTemplates() {
+        return AjaxResult.success(sysJobTemplateService.selectTenantScopeTemplates());
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:job:add')")
+    @PostMapping("/template")
+    public AjaxResult addTemplate(@RequestBody SysJobTemplate template) {
+        template.setCreateBy(getUsername());
+        return toAjax(sysJobTemplateService.insertTemplate(template));
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
+    @GetMapping("/template/{templateId}")
+    public AjaxResult getTemplate(@PathVariable Long templateId) {
+        return AjaxResult.success(sysJobTemplateService.selectTemplateById(templateId));
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:job:edit')")
+    @PutMapping("/template")
+    public AjaxResult editTemplate(@RequestBody SysJobTemplate template) {
+        template.setUpdateBy(getUsername());
+        return toAjax(sysJobTemplateService.updateTemplate(template));
+    }
+
+    @PreAuthorize("@ss.hasPermi('monitor:job:remove')")
+    @DeleteMapping("/template/{templateIds}")
+    public AjaxResult removeTemplate(@PathVariable Long[] templateIds) {
+        for (Long id : templateIds) {
+            sysJobTemplateService.deleteTemplateById(id);
+        }
+        return AjaxResult.success();
+    }
+
+    /** 查看某租户的全部任务配置(自动同步后每条模板都有一条) */
+    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
+    @GetMapping("/config/{tenantId}")
+    public AjaxResult getTenantConfig(@PathVariable Long tenantId) {
+        return AjaxResult.success(tenantJobConfigService.selectByTenantId(tenantId));
+    }
+
+    /** 单条任务开关:PUT /monitor/tenantJob/config/status?configId=1&status=0 */
+    @PreAuthorize("@ss.hasPermi('monitor:job:edit')")
+    @PutMapping("/config/status")
+    public AjaxResult updateStatus(@RequestParam Long configId, @RequestParam String status) {
+        tenantJobConfigService.updateStatus(configId, status);
+        return AjaxResult.success();
+    }
+
+    /** 同步全部模板到指定租户库(自动创建缺失的 config) */
+    @PreAuthorize("@ss.hasPermi('monitor:job:edit')")
+    @PostMapping("/sync/{tenantId}")
+    public AjaxResult syncTenant(@PathVariable Long tenantId) {
+        Map<String, Object> result = tenantJobConfigService.syncTenant(tenantId);
+        return AjaxResult.success(result);
+    }
+
+    /** 同步全部模板到所有租户库 */
+    @PreAuthorize("@ss.hasPermi('monitor:job:edit')")
+    @PostMapping("/syncAll")
+    public AjaxResult syncAll() {
+        return AjaxResult.success(tenantJobConfigService.syncAllTenants());
+    }
+
+    /** 分页查询租户任务配置列表 */
+    @PreAuthorize("@ss.hasPermi('monitor:job:list')")
+    @GetMapping("/config/list")
+    public TableDataInfo configList(TenantJobConfig query) {
+        startPage();
+        return getDataTable(tenantJobConfigService.selectConfigList(query));
+    }
+}

+ 85 - 28
fs-framework/src/main/java/com/fs/framework/task/TenantTaskRunner.java

@@ -1,9 +1,7 @@
 package com.fs.framework.task;
 
-import com.alibaba.fastjson.JSONObject;
 import com.fs.common.config.RedisTenantContext;
 import com.fs.common.enums.DataSourceType;
-import com.fs.common.utils.StringUtils;
 import com.fs.config.saas.ProjectConfig;
 import com.fs.core.config.TenantConfigContext;
 import com.fs.framework.datasource.DynamicDataSourceContextHolder;
@@ -13,17 +11,24 @@ import com.fs.system.mapper.SysConfigMapper;
 import com.fs.tenant.domain.TenantInfo;
 import com.fs.tenant.service.TenantInfoService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import javax.annotation.Resource;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 /**
- * SaaS 模式下按租户执行定时任务:从主库查启用租户,逐租户切库并设置租户配置后执行传入的逻辑。
- * 供 fs-admin 等使用 fs-framework 的模块在 @Scheduled 中按租户执行任务。
+ * SaaS multi-tenant task runner: load active tenants from master DB, switch datasource per tenant, then run action.
  */
 @Slf4j
 @Component
@@ -36,38 +41,68 @@ public class TenantTaskRunner {
     @Resource
     private SysConfigMapper sysConfigMapper;
 
-    /**
-     * 对每个启用且未过期的租户执行一次 action(已切到该租户库并设置 TenantConfigContext)。
-     */
+    @Value("${saas.task.parallel:true}")
+    private boolean parallelEnabled;
+
+    @Value("${saas.task.parallel.threads:4}")
+    private int parallelThreads;
+
+    private ExecutorService tenantExecutor;
+
+    @PostConstruct
+    public void initExecutor() {
+        if (parallelEnabled && parallelThreads > 0) {
+            tenantExecutor = new ThreadPoolExecutor(
+                    Math.min(4, parallelThreads),
+                    parallelThreads,
+                    60L, TimeUnit.SECONDS,
+                    new LinkedBlockingQueue<>(512),
+                    r -> {
+                        Thread t = new Thread(r, "saas-tenant-task-" + System.identityHashCode(r));
+                        t.setDaemon(false);
+                        return t;
+                    },
+                    new ThreadPoolExecutor.CallerRunsPolicy()
+            );
+            log.info("[SaaS Task] parallel tenant execution enabled, pool size={}", parallelThreads);
+        }
+    }
+
+    @PreDestroy
+    public void shutdownExecutor() {
+        if (tenantExecutor != null) {
+            tenantExecutor.shutdown();
+            try {
+                if (!tenantExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
+                    tenantExecutor.shutdownNow();
+                }
+            } catch (InterruptedException e) {
+                tenantExecutor.shutdownNow();
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
     public void runForEachTenant(Consumer<TenantInfo> action) {
         runForEachTenant(null, action);
     }
 
-    /**
-     * 对每个启用且未过期的租户执行一次 action,日志中输出任务名。
-     * @param taskName 定时任务名称,会输出在「定时任务切换数据源...」后面
-     */
     public void runForEachTenant(String taskName, Consumer<TenantInfo> action) {
         List<TenantInfo> validTenants = getValidTenants();
         if (validTenants == null || validTenants.isEmpty()) {
             return;
         }
-        for (TenantInfo tenant : validTenants) {
-            runForOneTenant(tenant, taskName, action);
+        if (parallelEnabled && tenantExecutor != null) {
+            runForEachTenantParallel(validTenants, taskName, action);
+        } else {
+            runForEachTenantSequential(validTenants, taskName, action);
         }
     }
 
-    /**
-     * 对每个租户执行无参逻辑(不需要 TenantInfo 时使用)。
-     */
     public void runForEachTenant(Runnable action) {
         runForEachTenant(null, t -> action.run());
     }
 
-    /**
-     * 对每个租户执行无参逻辑,日志中输出任务名。
-     * @param taskName 定时任务名称,会输出在「定时任务切换数据源...」后面
-     */
     public void runForEachTenant(String taskName, Runnable action) {
         runForEachTenant(taskName, t -> action.run());
     }
@@ -79,7 +114,7 @@ public class TenantTaskRunner {
             query.setStatus(1);
             List<TenantInfo> tenants = tenantInfoService.selectTenantInfoList(query);
             if (tenants == null || tenants.isEmpty()) {
-                log.debug("[SaaS Task] 无启用租户,跳过");
+                log.debug("[SaaS Task] no active tenants, skip");
                 return null;
             }
             Date now = new Date();
@@ -91,30 +126,52 @@ public class TenantTaskRunner {
         }
     }
 
+    private void runForEachTenantSequential(List<TenantInfo> validTenants, String taskName, Consumer<TenantInfo> action) {
+        for (TenantInfo tenant : validTenants) {
+            runForOneTenant(tenant, taskName, action);
+        }
+    }
+
+    private void runForEachTenantParallel(List<TenantInfo> validTenants, String taskName, Consumer<TenantInfo> action) {
+        CountDownLatch latch = new CountDownLatch(validTenants.size());
+        for (TenantInfo tenant : validTenants) {
+            tenantExecutor.submit(() -> {
+                try {
+                    runForOneTenant(tenant, taskName, action);
+                } finally {
+                    latch.countDown();
+                }
+            });
+        }
+        try {
+            if (!latch.await(30, TimeUnit.MINUTES)) {
+                log.warn("[SaaS Task] parallel tenant execution timed out after 30 minutes");
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            log.warn("[SaaS Task] parallel tenant execution interrupted", e);
+        }
+    }
+
     private void runForOneTenant(TenantInfo tenant, String taskName, Consumer<TenantInfo> action) {
         String dataSourceKey = "tenant:" + tenant.getId();
         try {
-            // 切换到租户数据源
             tenantDataSourceManager.switchTenant(tenant);
-            // 切换Redis租户上下文
             RedisTenantContext.setTenantId(tenant.getId());
-            log.info("[SaaS Task] 定时任务切换数据源和Redis dataSource={}, tenantId={}, tenantCode={}, task={}",
+            log.info("[SaaS Task] switch datasource and redis dataSource={}, tenantId={}, tenantCode={}, task={}",
                     dataSourceKey, tenant.getId(), tenant.getTenantCode(), taskName != null ? taskName : "");
 
-            // 加载租户项目配置(安全解析,防止非法JSON导致级联崩溃)
             SysConfig cfg = sysConfigMapper.selectConfigByConfigKey("projectConfig");
             ProjectConfig.safeLoadTenantConfigFromValue(cfg != null ? cfg.getConfigValue() : null);
 
-            // 执行租户任务
             action.accept(tenant);
 
         } catch (Exception e) {
-            log.error("[SaaS Task] 租户 tenantId={}, tenantCode={} 执行异常, task={}",
+            log.error("[SaaS Task] tenant tenantId={}, tenantCode={} failed, task={}",
                     tenant.getId(), tenant.getTenantCode(), taskName, e);
         } finally {
             ProjectConfig.clearTenantConfigs();
             TenantConfigContext.clear();
-            // 清理Redis租户上下文
             RedisTenantContext.clear();
             DynamicDataSourceContextHolder.clearDataSourceType();
         }

+ 13 - 8
fs-quartz/src/main/java/com/fs/quartz/mapper/SysJobMapper.java

@@ -5,14 +5,14 @@ import com.fs.quartz.domain.SysJob;
 
 /**
  * 调度任务信息 数据层
- * 
+ *
 
  */
 public interface SysJobMapper
 {
     /**
      * 查询调度任务日志集合
-     * 
+     *
      * @param job 调度信息
      * @return 操作日志集合
      */
@@ -20,14 +20,14 @@ public interface SysJobMapper
 
     /**
      * 查询所有调度任务
-     * 
+     *
      * @return 调度任务列表
      */
     public List<SysJob> selectJobAll();
 
     /**
      * 通过调度ID查询调度任务信息
-     * 
+     *
      * @param jobId 调度ID
      * @return 角色对象信息
      */
@@ -35,7 +35,7 @@ public interface SysJobMapper
 
     /**
      * 通过调度ID删除调度任务信息
-     * 
+     *
      * @param jobId 调度ID
      * @return 结果
      */
@@ -43,7 +43,7 @@ public interface SysJobMapper
 
     /**
      * 批量删除调度任务信息
-     * 
+     *
      * @param ids 需要删除的数据ID
      * @return 结果
      */
@@ -51,7 +51,7 @@ public interface SysJobMapper
 
     /**
      * 修改调度任务信息
-     * 
+     *
      * @param job 调度任务信息
      * @return 结果
      */
@@ -59,9 +59,14 @@ public interface SysJobMapper
 
     /**
      * 新增调度任务信息
-     * 
+     *
      * @param job 调度任务信息
      * @return 结果
      */
     public int insertJob(SysJob job);
+
+    /**
+     * Remove jobs synced from master tenant config.
+     */
+    public int deleteJobsByRemarkPrefix(String remarkPrefix);
 }

+ 19 - 13
fs-quartz/src/main/java/com/fs/quartz/service/impl/SysJobServiceImpl.java

@@ -20,7 +20,7 @@ import com.fs.quartz.util.ScheduleUtils;
 
 /**
  * 定时任务调度信息 服务层
- * 
+ *
 
  */
 @Service
@@ -46,6 +46,12 @@ public class SysJobServiceImpl implements ISysJobService
         scheduler.clear();
         if (tenantDispatcherOnly)
         {
+            // Master sys_job = platform-only tasks; tenant tasks run via TenantJobDispatcherJob in tenant DB
+            List<SysJob> jobList = jobMapper.selectJobAll();
+            for (SysJob job : jobList)
+            {
+                ScheduleUtils.createScheduleJob(scheduler, job);
+            }
             return;
         }
         List<SysJob> jobList = jobMapper.selectJobAll();
@@ -57,7 +63,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 获取quartz调度器的计划任务列表
-     * 
+     *
      * @param job 调度信息
      * @return
      */
@@ -69,7 +75,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 通过调度任务ID查询调度信息
-     * 
+     *
      * @param jobId 调度任务ID
      * @return 调度任务对象信息
      */
@@ -81,7 +87,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 暂停任务
-     * 
+     *
      * @param job 调度信息
      */
     @Override
@@ -101,7 +107,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 恢复任务
-     * 
+     *
      * @param job 调度信息
      */
     @Override
@@ -121,7 +127,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 删除任务后,所对应的trigger也将被删除
-     * 
+     *
      * @param job 调度信息
      */
     @Override
@@ -140,7 +146,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 批量删除调度信息
-     * 
+     *
      * @param jobIds 需要删除的任务ID
      * @return 结果
      */
@@ -157,7 +163,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 任务调度状态修改
-     * 
+     *
      * @param job 调度信息
      */
     @Override
@@ -179,7 +185,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 立即运行任务
-     * 
+     *
      * @param job 调度信息
      */
     @Override
@@ -197,7 +203,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 新增任务
-     * 
+     *
      * @param job 调度信息 调度信息
      */
     @Override
@@ -215,7 +221,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 更新任务的时间表达式
-     * 
+     *
      * @param job 调度信息
      */
     @Override
@@ -233,7 +239,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 更新任务
-     * 
+     *
      * @param job 任务对象
      * @param jobGroup 任务组名
      */
@@ -252,7 +258,7 @@ public class SysJobServiceImpl implements ISysJobService
 
     /**
      * 校验cron表达式是否有效
-     * 
+     *
      * @param cronExpression 表达式
      * @return 结果
      */

+ 15 - 11
fs-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml

@@ -19,12 +19,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 		<result property="updateTime"     column="update_time"     />
 		<result property="remark"         column="remark"          />
 	</resultMap>
-	
+
 	<sql id="selectJobVo">
-        select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark 
+        select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark
 		from sys_job
     </sql>
-	
+
 	<select id="selectJobList" parameterType="SysJob" resultMap="SysJobResult">
 		<include refid="selectJobVo"/>
 		<where>
@@ -42,27 +42,27 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 			</if>
 		</where>
 	</select>
-	
+
 	<select id="selectJobAll" resultMap="SysJobResult">
 		<include refid="selectJobVo"/>
 	</select>
-	
+
 	<select id="selectJobById" parameterType="Long" resultMap="SysJobResult">
 		<include refid="selectJobVo"/>
 		where job_id = #{jobId}
 	</select>
-	
+
 	<delete id="deleteJobById" parameterType="Long">
  		delete from sys_job where job_id = #{jobId}
  	</delete>
- 	
+
  	<delete id="deleteJobByIds" parameterType="Long">
  		delete from sys_job where job_id in
  		<foreach collection="array" item="jobId" open="(" separator="," close=")">
  			#{jobId}
-        </foreach> 
+        </foreach>
  	</delete>
- 	
+
  	<update id="updateJob" parameterType="SysJob">
  		update sys_job
  		<set>
@@ -79,7 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		</set>
  		where job_id = #{jobId}
 	</update>
- 	
+
  	<insert id="insertJob" parameterType="SysJob" useGeneratedKeys="true" keyProperty="jobId">
  		insert into sys_job(
  			<if test="jobId != null and jobId != 0">job_id,</if>
@@ -108,4 +108,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  		)
 	</insert>
 
-</mapper> 
+	<delete id="deleteJobsByRemarkPrefix">
+		delete from sys_job where remark like concat(#{remarkPrefix}, '%')
+	</delete>
+
+</mapper>

+ 0 - 14
fs-qw-task/src/main/java/com/fs/FSServletInitializer.java

@@ -1,14 +0,0 @@
-package com.fs;
-
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-
-
-public class FSServletInitializer extends SpringBootServletInitializer
-{
-    @Override
-    protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
-    {
-        return application.sources(FsQwTaskApplication.class);
-    }
-}

+ 0 - 24
fs-qw-task/src/main/java/com/fs/FsQwTaskApplication.java

@@ -1,24 +0,0 @@
-package com.fs;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.transaction.annotation.EnableTransactionManagement;
-
-/**
- * 启动程序
- */
-@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
-@EnableTransactionManagement
-@EnableAsync
-@EnableScheduling
-public class FsQwTaskApplication
-{
-    public static void main(String[] args){
-        // System.setProperty("spring.devtools.restart.enabled", "false");
-        SpringApplication.run(FsQwTaskApplication.class, args);
-        System.out.println("QwTask启动成功");
-    }
-}

+ 0 - 19
fs-qw-task/src/main/java/com/fs/app/controller/VoiceController.java

@@ -1,19 +0,0 @@
-package com.fs.app.controller;
-
-
-import io.swagger.annotations.Api;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@Api("公共接口")
-@RestController
-@RequestMapping(value="/app/common/voice")
-@Slf4j
-public class VoiceController {
-    @GetMapping
-    public void voice() {
-
-    }
-}

+ 0 - 51
fs-qw-task/src/main/java/com/fs/app/exception/FSException.java

@@ -1,51 +0,0 @@
-package com.fs.app.exception;
-
-/**
- * 自定义异常
- */
-public class FSException extends RuntimeException {
-	private static final long serialVersionUID = 1L;
-	
-    private String msg;
-    private int code = 500;
-    
-    public FSException(String msg) {
-		super(msg);
-		this.msg = msg;
-	}
-	
-	public FSException(String msg, Throwable e) {
-		super(msg, e);
-		this.msg = msg;
-	}
-	
-	public FSException(String msg, int code) {
-		super(msg);
-		this.msg = msg;
-		this.code = code;
-	}
-	
-	public FSException(String msg, int code, Throwable e) {
-		super(msg, e);
-		this.msg = msg;
-		this.code = code;
-	}
-
-	public String getMsg() {
-		return msg;
-	}
-
-	public void setMsg(String msg) {
-		this.msg = msg;
-	}
-
-	public int getCode() {
-		return code;
-	}
-
-	public void setCode(int code) {
-		this.code = code;
-	}
-	
-	
-}

+ 0 - 81
fs-qw-task/src/main/java/com/fs/app/exception/FSExceptionHandler.java

@@ -1,81 +0,0 @@
-package com.fs.app.exception;
-
-
-
-
-import com.fs.common.core.domain.R;
-import com.fs.common.exception.CustomException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.dao.DuplicateKeyException;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.validation.BindException;
-import org.springframework.validation.FieldError;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-import org.springframework.web.servlet.NoHandlerFoundException;
-
-
-/**
- * 异常处理器
- */
-@RestControllerAdvice
-public class FSExceptionHandler {
-	private Logger logger = LoggerFactory.getLogger(getClass());
-
-	/**
-	 * 处理自定义异常
-	 */
-	@ExceptionHandler(FSException.class)
-	public R handleRRException(FSException e){
-		R r = new R();
-		r.put("code", e.getCode());
-		r.put("msg", e.getMessage());
-
-		return r;
-	}
-
-	@ExceptionHandler(NoHandlerFoundException.class)
-	public R handlerNoFoundException(Exception e) {
-		logger.error(e.getMessage(), e);
-		return R.error(404, "路径不存在,请检查路径是否正确");
-	}
-
-	@ExceptionHandler(DuplicateKeyException.class)
-	public R handleDuplicateKeyException(DuplicateKeyException e){
-		logger.error(e.getMessage(), e);
-		return R.error("数据库中已存在该记录");
-	}
-
-
-	@ExceptionHandler(Exception.class)
-	public R handleException(Exception e){
-		logger.error(e.getMessage(), e);
-		return R.error();
-	}
-	@ExceptionHandler(AccessDeniedException.class)
-	public R handleAccessDeniedException(AccessDeniedException e){
-		logger.error(e.getMessage(), e);
-		return R.error("没有权限");
-	}
-
-	@ExceptionHandler(BindException.class)
-	public R bindExceptionHandler(BindException e) {
-		FieldError error = e.getFieldError();
-		String message = String.format("%s",  error.getDefaultMessage());
-		return R.error(message);
-	}
-
-	@ExceptionHandler(MethodArgumentNotValidException.class)
-	public R exceptionHandler(MethodArgumentNotValidException e) {
-		FieldError error = e.getBindingResult().getFieldError();
-		String message = String.format("%s",  error.getDefaultMessage());
-		return R.error(message);
-	}
-	@ExceptionHandler(CustomException.class)
-	public R handleException(CustomException e){
-
-		return R.error(e.getMessage());
-	}
-}

+ 0 - 199
fs-qw-task/src/main/java/com/fs/app/task/TenantTaskRunner.java

@@ -1,199 +0,0 @@
-package com.fs.app.task;
-
-import com.alibaba.fastjson.JSONObject;
-import com.fs.common.config.RedisTenantContext;
-import com.fs.common.enums.DataSourceType;
-import com.fs.common.utils.StringUtils;
-import com.fs.config.saas.ProjectConfig;
-import com.fs.core.config.TenantConfigContext;
-import com.fs.framework.datasource.DynamicDataSourceContextHolder;
-import com.fs.framework.datasource.TenantDataSourceManager;
-import com.fs.system.domain.SysConfig;
-import com.fs.system.mapper.SysConfigMapper;
-import com.fs.tenant.domain.TenantInfo;
-import com.fs.tenant.service.TenantInfoService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.annotation.Resource;
-import java.util.Date;
-import java.util.List;
-import java.util.concurrent.*;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-/**
- * SaaS 模式下按租户执行定时任务:从主库查启用租户,逐租户切库并设置租户配置后执行传入的逻辑。
- * 支持顺序执行与可配置的按租户并行执行,租户多、任务多时可通过并行提升整体执行效率。
- */
-@Slf4j
-@Component
-public class TenantTaskRunner {
-
-    @Resource
-    private TenantDataSourceManager tenantDataSourceManager;
-    @Resource
-    private TenantInfoService tenantInfoService;
-    @Resource
-    private SysConfigMapper sysConfigMapper;
-
-    /** 为 true 时按租户并行执行(线程池);为 false 时顺序执行。默认 false 保持与原有行为一致。 */
-    @Value("${saas.task.parallel:true}")
-    private boolean parallelEnabled;
-    /** 并行时线程池大小,建议不大于租户数量且考虑数据源连接池与机器负载。 */
-    @Value("${saas.task.parallel.threads:4}")
-    private int parallelThreads;
-
-    private ExecutorService tenantExecutor;
-
-    @PostConstruct
-    public void initExecutor() {
-        if (parallelEnabled && parallelThreads > 0) {
-            tenantExecutor = new ThreadPoolExecutor(
-                    Math.min(4, parallelThreads),
-                    parallelThreads,
-                    60L, TimeUnit.SECONDS,
-                    new LinkedBlockingQueue<>(512),
-                    r -> {
-                        Thread t = new Thread(r, "saas-tenant-task-" + System.identityHashCode(r));
-                        t.setDaemon(false);
-                        return t;
-                    },
-                    new ThreadPoolExecutor.CallerRunsPolicy()
-            );
-            log.info("[SaaS Task] 按租户并行已开启,线程池大小: {}", parallelThreads);
-        }
-    }
-
-    @PreDestroy
-    public void shutdownExecutor() {
-        if (tenantExecutor != null) {
-            tenantExecutor.shutdown();
-            try {
-                if (!tenantExecutor.awaitTermination(30, TimeUnit.SECONDS)) {
-                    tenantExecutor.shutdownNow();
-                }
-            } catch (InterruptedException e) {
-                tenantExecutor.shutdownNow();
-                Thread.currentThread().interrupt();
-            }
-        }
-    }
-
-    /**
-     * 对每个启用且未过期的租户执行一次 action(已切到该租户库并设置 TenantConfigContext)。
-     * 根据配置为顺序执行或按租户并行执行。
-     */
-    public void runForEachTenant(Consumer<TenantInfo> action) {
-        runForEachTenant(null, action);
-    }
-
-    /**
-     * 对每个启用且未过期的租户执行一次 action,日志中输出任务名。
-     * @param taskName 定时任务名称,会输出在「定时任务切换数据源...」后面
-     */
-    public void runForEachTenant(String taskName, Consumer<TenantInfo> action) {
-        List<TenantInfo> validTenants = getValidTenants();
-        if (validTenants == null || validTenants.isEmpty()) {
-            return;
-        }
-        if (parallelEnabled && tenantExecutor != null) {
-            runForEachTenantParallel(validTenants, taskName, action);
-        } else {
-            runForEachTenantSequential(validTenants, taskName, action);
-        }
-    }
-
-    /**
-     * 对每个租户执行无参逻辑(不需要 TenantInfo 时使用)。
-     */
-    public void runForEachTenant(Runnable action) {
-        runForEachTenant(null, t -> action.run());
-    }
-
-    /**
-     * 对每个租户执行无参逻辑,日志中输出任务名。
-     * @param taskName 定时任务名称,会输出在「定时任务切换数据源...」后面
-     */
-    public void runForEachTenant(String taskName, Runnable action) {
-        runForEachTenant(taskName, t -> action.run());
-    }
-
-    private List<TenantInfo> getValidTenants() {
-        try {
-            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
-            TenantInfo query = new TenantInfo();
-            query.setStatus(1);
-            List<TenantInfo> tenants = tenantInfoService.selectTenantInfoList(query);
-            if (tenants == null || tenants.isEmpty()) {
-                log.debug("[SaaS Task] 无启用租户,跳过");
-                return null;
-            }
-            Date now = new Date();
-            return tenants.stream()
-                    .filter(t -> t.getExpireTime() == null || !t.getExpireTime().before(now))
-                    .collect(Collectors.toList());
-        } finally {
-            DynamicDataSourceContextHolder.clearDataSourceType();
-        }
-    }
-
-    private void runForEachTenantSequential(List<TenantInfo> validTenants, String taskName, Consumer<TenantInfo> action) {
-        for (TenantInfo tenant : validTenants) {
-            runForOneTenant(tenant, taskName, action);
-        }
-    }
-
-    private void runForEachTenantParallel(List<TenantInfo> validTenants, String taskName, Consumer<TenantInfo> action) {
-        CountDownLatch latch = new CountDownLatch(validTenants.size());
-        for (TenantInfo tenant : validTenants) {
-            tenantExecutor.submit(() -> {
-                try {
-                    runForOneTenant(tenant, taskName, action);
-                } finally {
-                    latch.countDown();
-                }
-            });
-        }
-        try {
-            if (!latch.await(30, TimeUnit.MINUTES)) {
-                log.warn("[SaaS Task] 按租户并行执行超时(30分钟)");
-            }
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            log.warn("[SaaS Task] 按租户并行执行被中断", e);
-        }
-    }
-
-    private void runForOneTenant(TenantInfo tenant, String taskName, Consumer<TenantInfo> action) {
-        String dataSourceKey = "tenant:" + tenant.getId();
-        try {
-            // 切换到租户数据源
-            tenantDataSourceManager.switchTenant(tenant);
-            // 切换Redis租户上下文
-            RedisTenantContext.setTenantId(tenant.getId());
-            log.info("[SaaS Task] 定时任务切换数据源和Redis dataSource={}, tenantId={}, tenantCode={}, task={}",
-                    dataSourceKey, tenant.getId(), tenant.getTenantCode(), taskName != null ? taskName : "");
-
-            // 加载租户项目配置(安全解析,防止非法JSON导致级联崩溃)
-            SysConfig cfg = sysConfigMapper.selectConfigByConfigKey("projectConfig");
-            ProjectConfig.safeLoadTenantConfigFromValue(cfg != null ? cfg.getConfigValue() : null);
-
-            // 执行租户任务
-            action.accept(tenant);
-
-        } catch (Exception e) {
-            log.error("[SaaS Task] 租户 tenantId={}, tenantCode={} 执行异常, task={}",
-                    tenant.getId(), tenant.getTenantCode(), taskName, e);
-        } finally {
-            ProjectConfig.clearTenantConfigs();
-            TenantConfigContext.clear();
-            // 清理Redis租户上下文
-            RedisTenantContext.clear();
-            DynamicDataSourceContextHolder.clearDataSourceType();
-        }
-    }
-}

+ 0 - 55
fs-qw-task/src/main/java/com/fs/app/task/UserCourseWatchCountTask.java

@@ -1,55 +0,0 @@
-package com.fs.app.task;
-
-import com.fs.store.service.IFsUserCourseCountService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * 会员看课统计定时任务。SaaS 模式下按租户执行。
- */
-@Component
-@Slf4j
-public class UserCourseWatchCountTask {
-
-    @Autowired
-    private IFsUserCourseCountService userCourseCountService;
-    @Resource
-    private TenantTaskRunner tenantTaskRunner;
-
-    @Value("${saas.task.enabled:true}")
-    private boolean saasTaskEnabled;
-
-    private final AtomicBoolean isRunning1 = new AtomicBoolean(false);
-
-    /**
-     * 会员看课统计:每20分钟执行一次。SaaS 开启时按租户遍历执行。
-     */
-    @Scheduled(cron = "0 */20 * * * ?")
-    public void userCourseCountTask() {
-        if (!isRunning1.compareAndSet(false, true)) {
-            log.warn("会员看课统计任务执行 - 上一个任务尚未完成,跳过此次执行");
-            return;
-        }
-        try {
-            log.info("==============会员看课统计任务执行===============开始");
-            long startTime = System.currentTimeMillis();
-            if (saasTaskEnabled) {
-                tenantTaskRunner.runForEachTenant("userCourseCountTask", () -> userCourseCountService.insertFsUserCourseCountTask());
-            } else {
-                userCourseCountService.insertFsUserCourseCountTask();
-            }
-            log.info("会员看课统计任务执行==============结束");
-            log.info("会员看课统计任务执行----------执行时长:{}", System.currentTimeMillis() - startTime);
-        } catch (Exception e) {
-            log.error("会员看课统计任务执行----------定时任务执行失败", e);
-        } finally {
-            isRunning1.set(false);
-        }
-    }
-}

+ 0 - 171
fs-qw-task/src/main/java/com/fs/framework/aspectj/DataScopeAspect.java

@@ -1,171 +0,0 @@
-package com.fs.framework.aspectj;
-
-import com.fs.common.annotation.DataScope;
-import com.fs.common.core.domain.BaseEntity;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
-import com.fs.common.utils.spring.SpringUtils;
-import com.fs.company.domain.CompanyRole;
-import com.fs.company.domain.CompanyUser;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.Signature;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.springframework.stereotype.Component;
-
-import java.lang.reflect.Method;
-
-/**
- * 数据过滤处理
- *
-
- */
-@Aspect
-@Component
-public class DataScopeAspect
-{
-    /**
-     * 全部数据权限
-     */
-    public static final String DATA_SCOPE_ALL = "1";
-
-    /**
-     * 自定数据权限
-     */
-    public static final String DATA_SCOPE_CUSTOM = "2";
-
-    /**
-     * 部门数据权限
-     */
-    public static final String DATA_SCOPE_DEPT = "3";
-
-    /**
-     * 部门及以下数据权限
-     */
-    public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
-
-    /**
-     * 仅本人数据权限
-     */
-    public static final String DATA_SCOPE_SELF = "5";
-
-    /**
-     * 数据权限过滤关键字
-     */
-    public static final String DATA_SCOPE = "dataScope";
-
-    // 配置织入点
-    @Pointcut("@annotation(com.fs.common.annotation.DataScope)")
-    public void dataScopePointCut()
-    {
-    }
-
-    @Before("dataScopePointCut()")
-    public void doBefore(JoinPoint point) throws Throwable
-    {
-        handleDataScope(point);
-    }
-
-    protected void handleDataScope(final JoinPoint joinPoint)
-    {
-        // 获得注解
-        DataScope controllerDataScope = getAnnotationLog(joinPoint);
-        if (controllerDataScope == null)
-        {
-            return;
-        }
-        // 获取当前的用户
-        LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
-        if (StringUtils.isNotNull(loginUser))
-        {
-            CompanyUser currentUser = loginUser.getUser();
-            // 如果是超级管理员,则不过滤数据
-            if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
-            {
-                dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
-                        controllerDataScope.userAlias());
-            }
-        }
-    }
-
-    /**
-     * 数据范围过滤
-     *
-     * @param joinPoint 切点
-     * @param user 用户
-     * @param userAlias 别名
-     */
-    public static void dataScopeFilter(JoinPoint joinPoint, CompanyUser user, String deptAlias, String userAlias)
-    {
-        StringBuilder sqlString = new StringBuilder();
-
-        for (CompanyRole role : user.getRoles())
-        {
-            String dataScope = role.getDataScope();
-            if (DATA_SCOPE_ALL.equals(dataScope))
-            {
-                sqlString = new StringBuilder();
-                break;
-            }
-            else if (DATA_SCOPE_CUSTOM.equals(dataScope))
-            {
-                sqlString.append(StringUtils.format(
-                        " OR {}.dept_id IN ( SELECT dept_id FROM company_role_dept WHERE role_id = {} ) ", deptAlias,
-                        role.getRoleId()));
-            }
-            else if (DATA_SCOPE_DEPT.equals(dataScope))
-            {
-                sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
-            }
-            else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
-            {
-                sqlString.append(StringUtils.format(
-                        " OR {}.dept_id IN ( SELECT dept_id FROM company_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
-                        deptAlias, user.getDeptId(), user.getDeptId()));
-            }
-            else if (DATA_SCOPE_SELF.equals(dataScope))
-            {
-                if (StringUtils.isNotBlank(userAlias))
-                {
-                    sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
-                }
-                else
-                {
-                    // 数据权限为仅本人且没有userAlias别名不查询任何数据
-                    //sqlString.append(" OR 1=0 ");
-                        sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
-                }
-            }
-        }
-
-        if (StringUtils.isNotBlank(sqlString.toString()))
-        {
-            Object params = joinPoint.getArgs()[0];
-            if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
-            {
-                BaseEntity baseEntity = (BaseEntity) params;
-                baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
-            }
-        }
-    }
-
-    /**
-     * 是否存在注解,如果存在就获取
-     */
-    private DataScope getAnnotationLog(JoinPoint joinPoint)
-    {
-        Signature signature = joinPoint.getSignature();
-        MethodSignature methodSignature = (MethodSignature) signature;
-        Method method = methodSignature.getMethod();
-
-        if (method != null)
-        {
-            return method.getAnnotation(DataScope.class);
-        }
-        return null;
-    }
-}

+ 0 - 73
fs-qw-task/src/main/java/com/fs/framework/aspectj/DataSourceAspect.java

@@ -1,73 +0,0 @@
-package com.fs.framework.aspectj;
-
-import com.fs.common.annotation.DataSource;
-import com.fs.common.utils.StringUtils;
-import com.fs.framework.datasource.DynamicDataSourceContextHolder;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import java.util.Objects;
-
-/**
- * 多数据源处理
- * 
- 
- */
-@Aspect
-@Order(1)
-@Component
-public class DataSourceAspect
-{
-    protected Logger logger = LoggerFactory.getLogger(getClass());
-
-    @Pointcut("@annotation(com.fs.common.annotation.DataSource)"
-            + "|| @within(com.fs.common.annotation.DataSource)")
-    public void dsPointCut()
-    {
-
-    }
-
-    @Around("dsPointCut()")
-    public Object around(ProceedingJoinPoint point) throws Throwable
-    {
-        DataSource dataSource = getDataSource(point);
-
-        if (StringUtils.isNotNull(dataSource))
-        {
-            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
-        }
-
-        try
-        {
-            return point.proceed();
-        }
-        finally
-        {
-            // 销毁数据源 在执行方法之后
-            DynamicDataSourceContextHolder.clearDataSourceType();
-        }
-    }
-
-    /**
-     * 获取需要切换的数据源
-     */
-    public DataSource getDataSource(ProceedingJoinPoint point)
-    {
-        MethodSignature signature = (MethodSignature) point.getSignature();
-        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
-        if (Objects.nonNull(dataSource))
-        {
-            return dataSource;
-        }
-
-        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
-    }
-}

+ 0 - 219
fs-qw-task/src/main/java/com/fs/framework/aspectj/LogAspect.java

@@ -1,219 +0,0 @@
-package com.fs.framework.aspectj;
-
-import com.alibaba.fastjson.JSON;
-import com.fs.common.annotation.Log;
-import com.fs.common.enums.BusinessStatus;
-import com.fs.common.enums.HttpMethod;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
-import com.fs.common.utils.ip.IpUtils;
-import com.fs.common.utils.spring.SpringUtils;
-import com.fs.company.domain.CompanyOperLog;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.Signature;
-import org.aspectj.lang.annotation.AfterReturning;
-import org.aspectj.lang.annotation.AfterThrowing;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.web.multipart.MultipartFile;
-import org.springframework.web.servlet.HandlerMapping;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-/**
- * 操作日志记录处理
- * 
-
- */
-@Aspect
-@Component
-public class LogAspect
-{
-    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
-
-    // 配置织入点
-    @Pointcut("@annotation(com.fs.common.annotation.Log)")
-    public void logPointCut()
-    {
-    }
-
-    /**
-     * 处理完请求后执行
-     *
-     * @param joinPoint 切点
-     */
-    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
-    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
-    {
-        handleLog(joinPoint, null, jsonResult);
-    }
-
-    /**
-     * 拦截异常操作
-     * 
-     * @param joinPoint 切点
-     * @param e 异常
-     */
-    @AfterThrowing(value = "logPointCut()", throwing = "e")
-    public void doAfterThrowing(JoinPoint joinPoint, Exception e)
-    {
-        handleLog(joinPoint, e, null);
-    }
-
-    protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult)
-    {
-        try
-        {
-            // 获得注解
-            Log controllerLog = getAnnotationLog(joinPoint);
-            if (controllerLog == null)
-            {
-                return;
-            }
-
-            // 获取当前的用户
-            LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
-
-            // *========数据库日志=========*//
-            CompanyOperLog operLog = new CompanyOperLog();
-            operLog.setCompanyId(loginUser.getCompany().getCompanyId());
-            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
-            // 请求的地址
-            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
-            operLog.setOperIp(ip);
-            // 返回参数
-            operLog.setJsonResult(JSON.toJSONString(jsonResult));
-
-            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
-            if (loginUser != null)
-            {
-                operLog.setOperName(loginUser.getUsername());
-            }
-
-            if (e != null)
-            {
-                operLog.setStatus(BusinessStatus.FAIL.ordinal());
-                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
-            }
-            // 设置方法名称
-            String className = joinPoint.getTarget().getClass().getName();
-            String methodName = joinPoint.getSignature().getName();
-            operLog.setMethod(className + "." + methodName + "()");
-            // 设置请求方式
-            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
-            // 处理设置注解上的参数
-            getControllerMethodDescription(joinPoint, controllerLog, operLog);
-            // 保存数据库
-            AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
-        }
-        catch (Exception exp)
-        {
-            // 记录本地异常日志
-            log.error("==前置通知异常==");
-            log.error("异常信息:{}", exp.getMessage());
-            exp.printStackTrace();
-        }
-    }
-
-    /**
-     * 获取注解中对方法的描述信息 用于Controller层注解
-     * 
-     * @param log 日志
-     * @param operLog 操作日志
-     * @throws Exception
-     */
-    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, CompanyOperLog operLog) throws Exception
-    {
-        // 设置action动作
-        operLog.setBusinessType(log.businessType().ordinal());
-        // 设置标题
-        operLog.setTitle(log.title());
-        // 设置操作人类别
-        operLog.setOperatorType(log.operatorType().ordinal());
-        // 是否需要保存request,参数和值
-        if (log.isSaveRequestData())
-        {
-            // 获取参数的信息,传入到数据库中。
-            setRequestValue(joinPoint, operLog);
-        }
-    }
-
-    /**
-     * 获取请求的参数,放到log中
-     * 
-     * @param operLog 操作日志
-     * @throws Exception 异常
-     */
-    private void setRequestValue(JoinPoint joinPoint, CompanyOperLog operLog) throws Exception
-    {
-        String requestMethod = operLog.getRequestMethod();
-        if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
-        {
-            String params = argsArrayToString(joinPoint.getArgs());
-            operLog.setOperParam(StringUtils.substring(params, 0, 2000));
-        }
-        else
-        {
-            Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
-            operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
-        }
-    }
-
-    /**
-     * 是否存在注解,如果存在就获取
-     */
-    private Log getAnnotationLog(JoinPoint joinPoint) throws Exception
-    {
-        Signature signature = joinPoint.getSignature();
-        MethodSignature methodSignature = (MethodSignature) signature;
-        Method method = methodSignature.getMethod();
-
-        if (method != null)
-        {
-            return method.getAnnotation(Log.class);
-        }
-        return null;
-    }
-
-    /**
-     * 参数拼装
-     */
-    private String argsArrayToString(Object[] paramsArray)
-    {
-        String params = "";
-        if (paramsArray != null && paramsArray.length > 0)
-        {
-            for (int i = 0; i < paramsArray.length; i++)
-            {
-                if (!isFilterObject(paramsArray[i]))
-                {
-                    Object jsonObj = JSON.toJSON(paramsArray[i]);
-                    params += jsonObj.toString() + " ";
-                }
-            }
-        }
-        return params.trim();
-    }
-
-    /**
-     * 判断是否需要过滤的对象。
-     * 
-     * @param o 对象信息。
-     * @return 如果是需要过滤的对象,则返回true;否则返回false。
-     */
-    public boolean isFilterObject(final Object o)
-    {
-        return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
-    }
-}

+ 0 - 117
fs-qw-task/src/main/java/com/fs/framework/aspectj/RateLimiterAspect.java

@@ -1,117 +0,0 @@
-package com.fs.framework.aspectj;
-
-import com.fs.common.annotation.RateLimiter;
-import com.fs.common.enums.LimitType;
-import com.fs.common.exception.ServiceException;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
-import com.fs.common.utils.ip.IpUtils;
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.Signature;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.script.RedisScript;
-import org.springframework.stereotype.Component;
-
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * 限流处理
- *
-
- */
-@Aspect
-@Component
-public class RateLimiterAspect
-{
-    private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);
-
-    private RedisTemplate<Object, Object> redisTemplate;
-
-    private RedisScript<Long> limitScript;
-
-    @Autowired
-    public void setRedisTemplate1(RedisTemplate<Object, Object> redisTemplate)
-    {
-        this.redisTemplate = redisTemplate;
-    }
-
-    @Autowired
-    public void setLimitScript(RedisScript<Long> limitScript)
-    {
-        this.limitScript = limitScript;
-    }
-
-    // 配置织入点
-    @Pointcut("@annotation(com.fs.common.annotation.RateLimiter)")
-    public void rateLimiterPointCut()
-    {
-    }
-
-    @Before("rateLimiterPointCut()")
-    public void doBefore(JoinPoint point) throws Throwable
-    {
-        RateLimiter rateLimiter = getAnnotationRateLimiter(point);
-        String key = rateLimiter.key();
-        int time = rateLimiter.time();
-        int count = rateLimiter.count();
-
-        String combineKey = getCombineKey(rateLimiter, point);
-        List<Object> keys = Collections.singletonList(combineKey);
-        try
-        {
-            Long number = redisTemplate.execute(limitScript, keys, count, time);
-            if (StringUtils.isNull(number) || number.intValue() > count)
-            {
-                throw new ServiceException("访问过于频繁,请稍后再试");
-            }
-            log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), key);
-        }
-        catch (ServiceException e)
-        {
-            throw e;
-        }
-        catch (Exception e)
-        {
-            throw new RuntimeException("服务器限流异常,请稍后再试");
-        }
-    }
-
-    /**
-     * 是否存在注解,如果存在就获取
-     */
-    private RateLimiter getAnnotationRateLimiter(JoinPoint joinPoint)
-    {
-        Signature signature = joinPoint.getSignature();
-        MethodSignature methodSignature = (MethodSignature) signature;
-        Method method = methodSignature.getMethod();
-
-        if (method != null)
-        {
-            return method.getAnnotation(RateLimiter.class);
-        }
-        return null;
-    }
-
-    public String getCombineKey(RateLimiter rateLimiter, JoinPoint point)
-    {
-        StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
-        if (rateLimiter.limitType() == LimitType.IP)
-        {
-            stringBuffer.append(IpUtils.getIpAddr(ServletUtils.getRequest()));
-        }
-        MethodSignature signature = (MethodSignature) point.getSignature();
-        Method method = signature.getMethod();
-        Class<?> targetClass = method.getDeclaringClass();
-        stringBuffer.append("-").append(targetClass.getName()).append("- ").append(method.getName());
-        return stringBuffer.toString();
-    }
-}

+ 0 - 31
fs-qw-task/src/main/java/com/fs/framework/config/ApplicationConfig.java

@@ -1,31 +0,0 @@
-package com.fs.framework.config;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.EnableAspectJAutoProxy;
-
-import java.util.TimeZone;
-
-/**
- * 程序注解配置
- *
-
- */
-@Configuration
-// 表示通过aop框架暴露该代理对象,AopContext能够访问
-@EnableAspectJAutoProxy(exposeProxy = true)
-// 指定要扫描的Mapper类的包的路径
-@MapperScan("com.fs.**.mapper")
-public class ApplicationConfig
-{
-    /**
-     * 时区配置
-     */
-    @Bean
-    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
-    {
-        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
-    }
-}

+ 0 - 58
fs-qw-task/src/main/java/com/fs/framework/config/ArrayStringTypeHandler.java

@@ -1,58 +0,0 @@
-package com.fs.framework.config;
-
-import org.apache.ibatis.type.BaseTypeHandler;
-import org.apache.ibatis.type.JdbcType;
-import org.springframework.context.annotation.Configuration;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-@Configuration
-public class ArrayStringTypeHandler extends BaseTypeHandler<List<String>> {
-
-    @Override
-    public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException {
-        // 将 List<String> 转换为字符串,ClickHouse 支持的格式为 "['item1', 'item2']"
-        StringBuilder sb = new StringBuilder();
-        sb.append("[");
-        for (int j = 0; j < parameter.size(); j++) {
-            sb.append("'").append(parameter.get(j)).append("'");
-            if (j < parameter.size() - 1) {
-                sb.append(",");
-            }
-        }
-        sb.append("]");
-        ps.setString(i, sb.toString());
-    }
-
-    @Override
-    public List<String> getNullableResult(ResultSet rs, String columnName) throws SQLException {
-        // 处理查询结果,将其转换为 List<String>
-        String result = rs.getString(columnName);
-        return parseArray(result);
-    }
-
-    @Override
-    public List<String> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
-        String result = rs.getString(columnIndex);
-        return parseArray(result);
-    }
-
-    @Override
-    public List<String> getNullableResult(java.sql.CallableStatement cs, int columnIndex) throws SQLException {
-        String result = cs.getString(columnIndex);
-        return parseArray(result);
-    }
-
-    private List<String> parseArray(String arrayStr) {
-        // 将 ClickHouse 的 Array 字符串转换为 List<String>
-        if (arrayStr == null || arrayStr.isEmpty()) {
-            return null;
-        }
-        arrayStr = arrayStr.substring(1, arrayStr.length() - 1);  // 去掉 "[" 和 "]"
-        String[] elements = arrayStr.split(",");
-        return java.util.Arrays.asList(elements);
-    }
-}

+ 0 - 85
fs-qw-task/src/main/java/com/fs/framework/config/CaptchaConfig.java

@@ -1,85 +0,0 @@
-package com.fs.framework.config;
-
-import com.google.code.kaptcha.impl.DefaultKaptcha;
-import com.google.code.kaptcha.util.Config;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.Properties;
-
-import static com.google.code.kaptcha.Constants.*;
-
-/**
- * 验证码配置
- * 
-
- */
-@Configuration
-public class CaptchaConfig
-{
-    @Bean(name = "captchaProducer")
-    public DefaultKaptcha getKaptchaBean()
-    {
-        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
-        Properties properties = new Properties();
-        // 是否有边框 默认为true 我们可以自己设置yes,no
-        properties.setProperty(KAPTCHA_BORDER, "yes");
-        // 验证码文本字符颜色 默认为Color.BLACK
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
-        // 验证码图片宽度 默认为200
-        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
-        // 验证码图片高度 默认为50
-        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
-        // 验证码文本字符大小 默认为40
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
-        // KAPTCHA_SESSION_KEY
-        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
-        // 验证码文本字符长度 默认为5
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
-        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
-        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
-        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
-        Config config = new Config(properties);
-        defaultKaptcha.setConfig(config);
-        return defaultKaptcha;
-    }
-
-    @Bean(name = "captchaProducerMath")
-    public DefaultKaptcha getKaptchaBeanMath()
-    {
-        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
-        Properties properties = new Properties();
-        // 是否有边框 默认为true 我们可以自己设置yes,no
-        properties.setProperty(KAPTCHA_BORDER, "yes");
-        // 边框颜色 默认为Color.BLACK
-        properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
-        // 验证码文本字符颜色 默认为Color.BLACK
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
-        // 验证码图片宽度 默认为200
-        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
-        // 验证码图片高度 默认为50
-        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
-        // 验证码文本字符大小 默认为40
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
-        // KAPTCHA_SESSION_KEY
-        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
-        // 验证码文本生成器
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.fs.framework.config.KaptchaTextCreator");
-        // 验证码文本字符间距 默认为2
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
-        // 验证码文本字符长度 默认为5
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
-        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
-        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
-        // 验证码噪点颜色 默认为Color.BLACK
-        properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
-        // 干扰实现类
-        properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
-        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
-        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
-        Config config = new Config(properties);
-        defaultKaptcha.setConfig(config);
-        return defaultKaptcha;
-    }
-}

+ 0 - 89
fs-qw-task/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -1,89 +0,0 @@
-package com.fs.framework.config;
-
-import com.alibaba.druid.pool.DruidDataSource;
-import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
-import com.alibaba.druid.util.Utils;
-import com.fs.common.enums.DataSourceType;
-import com.fs.framework.datasource.DynamicDataSource;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-
-import javax.servlet.*;
-import javax.sql.DataSource;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-@Configuration
-public class DataSourceConfig {
-
-    
-
-    @Bean
-    @ConfigurationProperties(prefix = "spring.datasource.mysql.druid.master")
-    public DataSource masterDataSource() {
-        return new DruidDataSource();
-    }
-
-
-
-    @Bean
-    @Primary
-    public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource) {
-        Map<Object, Object> targetDataSources = new HashMap<>();
-        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
-        
-        return new DynamicDataSource(masterDataSource, targetDataSources);
-    }
-
-    /**
-     * 去除监控页面底部的广告
-     */
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Bean
-    @ConditionalOnProperty(name = "spring.datasource.mysql.druid.statViewServlet.enabled", havingValue = "true")
-    public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
-    {
-        // 获取web监控页面的参数
-        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
-        // 提取common.js的配置路径
-        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
-        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
-        final String filePath = "support/http/resources/js/common.js";
-        // 创建filter进行过滤
-        Filter filter = new Filter()
-        {
-            @Override
-            public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
-            {
-            }
-            @Override
-            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
-                    throws IOException, ServletException
-            {
-                chain.doFilter(request, response);
-                // 重置缓冲区,响应头不会被重置
-                response.resetBuffer();
-                // 获取common.js
-                String text = Utils.readFromResource(filePath);
-                // 正则替换banner, 除去底部的广告信息
-                text = text.replaceAll("<a.*?banner\"></a><br/>", "");
-                text = text.replaceAll("powered.*?shrek.wang</a>", "");
-                response.getWriter().write(text);
-            }
-            @Override
-            public void destroy()
-            {
-            }
-        };
-        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
-        registrationBean.setFilter(filter);
-        registrationBean.addUrlPatterns(commonJsPattern);
-        return registrationBean;
-    }
-}

+ 0 - 123
fs-qw-task/src/main/java/com/fs/framework/config/DruidConfig.java

@@ -1,123 +0,0 @@
-package com.fs.framework.config;//package com.fs.framework.config;
-//
-//import com.alibaba.druid.pool.DruidDataSource;
-//import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
-//import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
-//import com.alibaba.druid.util.Utils;
-//import com.fs.framework.datasource.DynamicDataSource;
-//import com.fs.common.enums.DataSourceType;
-//import com.fs.common.utils.spring.SpringUtils;
-//import com.fs.framework.config.properties.DruidProperties;
-//import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-//import org.springframework.boot.context.properties.ConfigurationProperties;
-//import org.springframework.boot.web.servlet.FilterRegistrationBean;
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.Configuration;
-//import org.springframework.context.annotation.Primary;
-//
-//import javax.servlet.*;
-//import javax.sql.DataSource;
-//import java.io.IOException;
-//import java.util.HashMap;
-//import java.util.Map;
-//
-///**
-// * druid 配置多数据源
-// *
-//
-// */
-//@Configuration
-//public class DruidConfig
-//{
-//    @Bean
-//    @ConfigurationProperties("spring.datasource.mysql.druid.master")
-//    public DataSource masterDataSource(DruidProperties druidProperties)
-//    {
-//        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
-//        return druidProperties.dataSource(dataSource);
-//    }
-//
-//    @Bean
-//    @ConfigurationProperties("spring.datasource.mysql.druid.slave")
-//    @ConditionalOnProperty(prefix = "spring.datasource.mysql.druid.slave", name = "enabled", havingValue = "true")
-//    public DataSource slaveDataSource(DruidProperties druidProperties)
-//    {
-//        DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
-//        return druidProperties.dataSource(dataSource);
-//    }
-//
-//    @Bean(name = "dynamicDataSource")
-//    @Primary
-//    public DynamicDataSource dataSource(DataSource masterDataSource)
-//    {
-//        Map<Object, Object> targetDataSources = new HashMap<>();
-//        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
-//        setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
-//        return new DynamicDataSource(masterDataSource, targetDataSources);
-//    }
-//
-//    /**
-//     * 设置数据源
-//     *
-//     * @param targetDataSources 备选数据源集合
-//     * @param sourceName 数据源名称
-//     * @param beanName bean名称
-//     */
-//    public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
-//    {
-//        try
-//        {
-//            DataSource dataSource = SpringUtils.getBean(beanName);
-//            targetDataSources.put(sourceName, dataSource);
-//        }
-//        catch (Exception e)
-//        {
-//        }
-//    }
-//
-//    /**
-//     * 去除监控页面底部的广告
-//     */
-//    @SuppressWarnings({ "rawtypes", "unchecked" })
-//    @Bean
-//    @ConditionalOnProperty(name = "spring.datasource.mysql.druid.statViewServlet.enabled", havingValue = "true")
-//    public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
-//    {
-//        // 获取web监控页面的参数
-//        DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
-//        // 提取common.js的配置路径
-//        String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
-//        String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
-//        final String filePath = "support/http/resources/js/common.js";
-//        // 创建filter进行过滤
-//        Filter filter = new Filter()
-//        {
-//            @Override
-//            public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
-//            {
-//            }
-//            @Override
-//            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
-//                    throws IOException, ServletException
-//            {
-//                chain.doFilter(request, response);
-//                // 重置缓冲区,响应头不会被重置
-//                response.resetBuffer();
-//                // 获取common.js
-//                String text = Utils.readFromResource(filePath);
-//                // 正则替换banner, 除去底部的广告信息
-//                text = text.replaceAll("<a.*?banner\"></a><br/>", "");
-//                text = text.replaceAll("powered.*?shrek.wang</a>", "");
-//                response.getWriter().write(text);
-//            }
-//            @Override
-//            public void destroy()
-//            {
-//            }
-//        };
-//        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
-//        registrationBean.setFilter(filter);
-//        registrationBean.addUrlPatterns(commonJsPattern);
-//        return registrationBean;
-//    }
-//}

+ 0 - 72
fs-qw-task/src/main/java/com/fs/framework/config/FastJson2JsonRedisSerializer.java

@@ -1,72 +0,0 @@
-package com.fs.framework.config;
-
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.parser.ParserConfig;
-import com.alibaba.fastjson.serializer.SerializerFeature;
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-import org.springframework.data.redis.serializer.RedisSerializer;
-import org.springframework.data.redis.serializer.SerializationException;
-import org.springframework.util.Assert;
-
-import java.nio.charset.Charset;
-
-/**
- * Redis使用FastJson序列化
- * 
-
- */
-public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
-{
-    @SuppressWarnings("unused")
-    private ObjectMapper objectMapper = new ObjectMapper();
-
-    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
-
-    private Class<T> clazz;
-
-    static
-    {
-        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
-    }
-
-    public FastJson2JsonRedisSerializer(Class<T> clazz)
-    {
-        super();
-        this.clazz = clazz;
-    }
-
-    @Override
-    public byte[] serialize(T t) throws SerializationException
-    {
-        if (t == null)
-        {
-            return new byte[0];
-        }
-        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
-    }
-
-    @Override
-    public T deserialize(byte[] bytes) throws SerializationException
-    {
-        if (bytes == null || bytes.length <= 0)
-        {
-            return null;
-        }
-        String str = new String(bytes, DEFAULT_CHARSET);
-
-        return JSON.parseObject(str, clazz);
-    }
-
-    public void setObjectMapper(ObjectMapper objectMapper)
-    {
-        Assert.notNull(objectMapper, "'objectMapper' must not be null");
-        this.objectMapper = objectMapper;
-    }
-
-    protected JavaType getJavaType(Class<?> clazz)
-    {
-        return TypeFactory.defaultInstance().constructType(clazz);
-    }
-}

+ 0 - 59
fs-qw-task/src/main/java/com/fs/framework/config/FilterConfig.java

@@ -1,59 +0,0 @@
-package com.fs.framework.config;
-
-import com.fs.common.filter.RepeatableFilter;
-import com.fs.common.filter.XssFilter;
-import com.fs.common.utils.StringUtils;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import javax.servlet.DispatcherType;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Filter配置
- *
-
- */
-@Configuration
-@ConditionalOnProperty(value = "xss.enabled", havingValue = "true")
-public class FilterConfig
-{
-    @Value("${xss.excludes}")
-    private String excludes;
-
-    @Value("${xss.urlPatterns}")
-    private String urlPatterns;
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Bean
-    public FilterRegistrationBean xssFilterRegistration()
-    {
-        FilterRegistrationBean registration = new FilterRegistrationBean();
-        registration.setDispatcherTypes(DispatcherType.REQUEST);
-        registration.setFilter(new XssFilter());
-        registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
-        registration.setName("xssFilter");
-        registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
-        Map<String, String> initParameters = new HashMap<String, String>();
-        initParameters.put("excludes", excludes);
-        registration.setInitParameters(initParameters);
-        return registration;
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Bean
-    public FilterRegistrationBean someFilterRegistration()
-    {
-        FilterRegistrationBean registration = new FilterRegistrationBean();
-        registration.setFilter(new RepeatableFilter());
-        registration.addUrlPatterns("/*");
-        registration.setName("repeatableFilter");
-        registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
-        return registration;
-    }
-
-}

+ 0 - 76
fs-qw-task/src/main/java/com/fs/framework/config/KaptchaTextCreator.java

@@ -1,76 +0,0 @@
-package com.fs.framework.config;
-
-import com.google.code.kaptcha.text.impl.DefaultTextCreator;
-
-import java.util.Random;
-
-/**
- * 验证码文本生成器
- * 
-
- */
-public class KaptchaTextCreator extends DefaultTextCreator
-{
-    private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
-
-    @Override
-    public String getText()
-    {
-        Integer result = 0;
-        Random random = new Random();
-        int x = random.nextInt(10);
-        int y = random.nextInt(10);
-        StringBuilder suChinese = new StringBuilder();
-        int randomoperands = (int) Math.round(Math.random() * 2);
-        if (randomoperands == 0)
-        {
-            result = x * y;
-            suChinese.append(CNUMBERS[x]);
-            suChinese.append("*");
-            suChinese.append(CNUMBERS[y]);
-        }
-        else if (randomoperands == 1)
-        {
-            if (!(x == 0) && y % x == 0)
-            {
-                result = y / x;
-                suChinese.append(CNUMBERS[y]);
-                suChinese.append("/");
-                suChinese.append(CNUMBERS[x]);
-            }
-            else
-            {
-                result = x + y;
-                suChinese.append(CNUMBERS[x]);
-                suChinese.append("+");
-                suChinese.append(CNUMBERS[y]);
-            }
-        }
-        else if (randomoperands == 2)
-        {
-            if (x >= y)
-            {
-                result = x - y;
-                suChinese.append(CNUMBERS[x]);
-                suChinese.append("-");
-                suChinese.append(CNUMBERS[y]);
-            }
-            else
-            {
-                result = y - x;
-                suChinese.append(CNUMBERS[y]);
-                suChinese.append("-");
-                suChinese.append(CNUMBERS[x]);
-            }
-        }
-        else
-        {
-            result = x + y;
-            suChinese.append(CNUMBERS[x]);
-            suChinese.append("+");
-            suChinese.append(CNUMBERS[y]);
-        }
-        suChinese.append("=?@" + result);
-        return suChinese.toString();
-    }
-}

+ 0 - 150
fs-qw-task/src/main/java/com/fs/framework/config/MyBatisConfig.java

@@ -1,150 +0,0 @@
-package com.fs.framework.config;
-
-import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
-import com.fs.common.utils.StringUtils;
-import org.apache.ibatis.io.VFS;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.mybatis.spring.SqlSessionFactoryBean;
-import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.DefaultResourceLoader;
-import org.springframework.core.io.Resource;
-import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-import org.springframework.core.io.support.ResourcePatternResolver;
-import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
-import org.springframework.core.type.classreading.MetadataReader;
-import org.springframework.core.type.classreading.MetadataReaderFactory;
-import org.springframework.util.ClassUtils;
-
-import javax.sql.DataSource;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Mybatis支持*匹配扫描包
- * 
-
- */
-@Configuration
-public class MyBatisConfig
-{
-    @Autowired
-    private Environment env;
-
-    static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
-
-    public static String setTypeAliasesPackage(String typeAliasesPackage)
-    {
-        ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
-        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
-        List<String> allResult = new ArrayList<String>();
-        try
-        {
-            for (String aliasesPackage : typeAliasesPackage.split(","))
-            {
-                List<String> result = new ArrayList<String>();
-                aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
-                        + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
-                Resource[] resources = resolver.getResources(aliasesPackage);
-                if (resources != null && resources.length > 0)
-                {
-                    MetadataReader metadataReader = null;
-                    for (Resource resource : resources)
-                    {
-                        if (resource.isReadable())
-                        {
-                            metadataReader = metadataReaderFactory.getMetadataReader(resource);
-                            try
-                            {
-                                result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
-                            }
-                            catch (ClassNotFoundException e)
-                            {
-                                e.printStackTrace();
-                            }
-                        }
-                    }
-                }
-                if (result.size() > 0)
-                {
-                    HashSet<String> hashResult = new HashSet<String>(result);
-                    allResult.addAll(hashResult);
-                }
-            }
-            if (allResult.size() > 0)
-            {
-                typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
-            }
-            else
-            {
-                throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
-            }
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();
-        }
-        return typeAliasesPackage;
-    }
-
-    public Resource[] resolveMapperLocations(String[] mapperLocations)
-    {
-        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
-        List<Resource> resources = new ArrayList<Resource>();
-        if (mapperLocations != null)
-        {
-            for (String mapperLocation : mapperLocations)
-            {
-                try
-                {
-                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
-                    resources.addAll(Arrays.asList(mappers));
-                }
-                catch (IOException e)
-                {
-                    // ignore
-                }
-            }
-        }
-        return resources.toArray(new Resource[resources.size()]);
-    }
-
-//    @Bean
-//    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
-//    {
-//        String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
-//        String mapperLocations = env.getProperty("mybatis.mapperLocations");
-//        String configLocation = env.getProperty("mybatis.configLocation");
-//        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
-//        VFS.addImplClass(SpringBootVFS.class);
-//
-//        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
-//        sessionFactory.setDataSource(dataSource);
-//        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
-//        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
-//        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
-//        return sessionFactory.getObject();
-//    }
-    @Bean
-    public SqlSessionFactory sqlSessionFactorys(DataSource dataSource) throws Exception
-    {
-        String typeAliasesPackage = env.getProperty("mybatis-plus.typeAliasesPackage");
-        String mapperLocations = env.getProperty("mybatis-plus.mapperLocations");
-        String configLocation = env.getProperty("mybatis-plus.configLocation");
-        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
-        VFS.addImplClass(SpringBootVFS.class);
-
-        final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
-        sessionFactory.setDataSource(dataSource);
-        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
-        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
-        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
-        return sessionFactory.getObject();
-    }
-}

+ 0 - 76
fs-qw-task/src/main/java/com/fs/framework/config/ResourcesConfig.java

@@ -1,76 +0,0 @@
-package com.fs.framework.config;
-
-import com.fs.common.config.FSConfig;
-import com.fs.common.constant.Constants;
-import com.fs.framework.interceptor.RepeatSubmitInterceptor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.format.FormatterRegistry;
-import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import org.springframework.web.filter.CorsFilter;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-import java.time.format.DateTimeFormatter;
-
-/**
- * 通用配置
- *
-
- */
-@Configuration
-public class ResourcesConfig implements WebMvcConfigurer
-{
-    @Autowired
-    private RepeatSubmitInterceptor repeatSubmitInterceptor;
-
-    @Override
-    public void addResourceHandlers(ResourceHandlerRegistry registry)
-    {
-        /** 本地文件上传路径 */
-        registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + FSConfig.getProfile() + "/");
-
-        /** swagger配置 */
-        registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
-    }
-
-    /**
-     * 自定义拦截规
-     */
-    @Override
-    public void addInterceptors(InterceptorRegistry registry)
-    {
-        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
-    }
-
-    /**
-     * 跨域配置
-     */
-    @Bean
-    public CorsFilter corsFilter()
-    {
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        CorsConfiguration config = new CorsConfiguration();
-        config.setAllowCredentials(true);
-        // 设置访问源地址
-        config.addAllowedOriginPattern("*");
-        // 设置访问源请求头
-        config.addAllowedHeader("*");
-        // 设置访问源请求方
-        config.addAllowedMethod("*");
-        // 对接口配置跨域设
-        source.registerCorsConfiguration("/**", config);
-        return new CorsFilter(source);
-    }
-
-    @Override
-    public void addFormatters(FormatterRegistry registry) {
-        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
-        registrar.setDateFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // 统一日期格式
-        registrar.registerFormatters(registry);
-    }
-}

+ 0 - 11
fs-qw-task/src/main/java/com/fs/framework/config/RetryConfig.java

@@ -1,11 +0,0 @@
-package com.fs.framework.config;
-
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.retry.annotation.EnableRetry;
-
-@Configuration
-@EnableRetry
-public class RetryConfig {
-
-}

+ 0 - 157
fs-qw-task/src/main/java/com/fs/framework/config/SecurityConfig.java

@@ -1,157 +0,0 @@
-package com.fs.framework.config;
-
-
-import com.fs.framework.security.filter.JwtAuthenticationTokenFilter;
-import com.fs.framework.security.handle.AuthenticationEntryPointImpl;
-import com.fs.framework.security.handle.LogoutSuccessHandlerImpl;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-import org.springframework.security.web.authentication.logout.LogoutFilter;
-import org.springframework.web.filter.CorsFilter;
-
-/**
- * spring security配置
- *
-
- */
-@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
-public class SecurityConfig extends WebSecurityConfigurerAdapter
-{
-    /**
-     * 自定义用户认证逻辑
-     */
-    @Autowired
-    private UserDetailsService userDetailsService;
-
-    /**
-     * 认证失败处理类
-     */
-    @Autowired
-    private AuthenticationEntryPointImpl unauthorizedHandler;
-
-    /**
-     * 退出处理类
-     */
-    @Autowired
-    private LogoutSuccessHandlerImpl logoutSuccessHandler;
-
-    /**
-     * token认证过滤器
-     */
-    @Autowired
-    private JwtAuthenticationTokenFilter authenticationTokenFilter;
-
-    /**
-     * 跨域过滤器
-     */
-    @Autowired
-    private CorsFilter corsFilter;
-
-    /**
-     * 解决 无法直接注入 AuthenticationManager
-     *
-     * @return
-     * @throws Exception
-     */
-    @Bean
-    @Override
-    public AuthenticationManager authenticationManagerBean() throws Exception
-    {
-        return super.authenticationManagerBean();
-    }
-
-    /**
-     * anyRequest          |   匹配所有请求路径
-     * access              |   SpringEl表达式结果为true时可以访问
-     * anonymous           |   匿名可以访问
-     * denyAll             |   用户不能访问
-     * fullyAuthenticated  |   用户完全认证可以访问(非remember-me下自动登录)
-     * hasAnyAuthority     |   如果有参数,参数表示权限,则其中任何一个权限可以访问
-     * hasAnyRole          |   如果有参数,参数表示角色,则其中任何一个角色可以访问
-     * hasAuthority        |   如果有参数,参数表示权限,则其权限可以访问
-     * hasIpAddress        |   如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
-     * hasRole             |   如果有参数,参数表示角色,则其角色可以访问
-     * permitAll           |   用户可以任意访问
-     * rememberMe          |   允许通过remember-me登录的用户访问
-     * authenticated       |   用户登录后可访问
-     */
-    @Override
-    protected void configure(HttpSecurity httpSecurity) throws Exception
-    {
-        httpSecurity
-                // CSRF禁用,因为不使用session
-                .csrf().disable()
-                // 认证失败处理类
-                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
-                // 基于token,所以不需要session
-                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
-                // 过滤请求
-                .authorizeRequests()
-                // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/chat/upload/**","/login", "/register", "/captchaImage").anonymous()
-                .antMatchers(
-                        HttpMethod.GET,
-                        "/",
-                        "/*.html",
-                        "/**/*.html",
-                        "/**/*.css",
-                        "/**/*.js",
-                        "/profile/**"
-                ).permitAll()
-                .antMatchers("**").anonymous()
-                .antMatchers("/qw/getJsapiTicket/**").anonymous()
-                .antMatchers("/msg/**").anonymous()
-                .antMatchers("/msg/**/**").anonymous()
-                .antMatchers("/msg").anonymous()
-                .antMatchers("/app/common/**").anonymous()
-                .antMatchers("/common/getId**").anonymous()
-                .antMatchers("/common/uploadOSS**").anonymous()
-                .antMatchers("/common/uploadWang**").anonymous()
-                .antMatchers("/common/download**").anonymous()
-                .antMatchers("/common/download/resource**").anonymous()
-                .antMatchers("/swagger-ui.html").anonymous()
-                .antMatchers("/swagger-resources/**").anonymous()
-                .antMatchers("/webjars/**").anonymous()
-                .antMatchers("/*/api-docs").anonymous()
-                .antMatchers("/druid/**").anonymous()
-                .antMatchers("/qw/data/**").anonymous()
-                // 除上面外的所有请求全部需要鉴权认证
-                .anyRequest().authenticated()
-                .and()
-                .headers().frameOptions().disable();
-        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
-        // 添加JWT filter
-        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
-        // 添加CORS filter
-        httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
-        httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
-    }
-
-    /**
-     * 强散列哈希加密实现
-     */
-    @Bean
-    public BCryptPasswordEncoder bCryptPasswordEncoder()
-    {
-        return new BCryptPasswordEncoder();
-    }
-
-    /**
-     * 身份认证接口
-     */
-    @Override
-    protected void configure(AuthenticationManagerBuilder auth) throws Exception
-    {
-        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
-    }
-}

+ 0 - 33
fs-qw-task/src/main/java/com/fs/framework/config/ServerConfig.java

@@ -1,33 +0,0 @@
-package com.fs.framework.config;
-
-import com.fs.common.utils.ServletUtils;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * 服务相关配置
- *
-
- */
-@Component
-public class ServerConfig
-{
-    /**
-     * 获取完整的请求路径,包括:域名,端口,上下文访问路径
-     *
-     * @return 服务地址
-     */
-    public String getUrl()
-    {
-        HttpServletRequest request = ServletUtils.getRequest();
-        return getDomain(request);
-    }
-
-    public static String getDomain(HttpServletRequest request)
-    {
-        StringBuffer url = request.getRequestURL();
-        String contextPath = request.getServletContext().getContextPath();
-        return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
-    }
-}

+ 0 - 121
fs-qw-task/src/main/java/com/fs/framework/config/SwaggerConfig.java

@@ -1,121 +0,0 @@
-package com.fs.framework.config;
-
-import com.fs.common.config.FSConfig;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.models.auth.In;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import springfox.documentation.builders.ApiInfoBuilder;
-import springfox.documentation.builders.PathSelectors;
-import springfox.documentation.builders.RequestHandlerSelectors;
-import springfox.documentation.service.*;
-import springfox.documentation.spi.DocumentationType;
-import springfox.documentation.spi.service.contexts.SecurityContext;
-import springfox.documentation.spring.web.plugins.Docket;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Swagger2的接口配置
- * 
-
- */
-@Configuration
-public class SwaggerConfig
-{
-    /** 系统基础配置 */
-    @Autowired
-    private FSConfig fsConfig;
-
-    /** 是否开启swagger */
-    @Value("${swagger.enabled}")
-    private boolean enabled;
-
-    /** 设置请求的统一前缀 */
-    @Value("${swagger.pathMapping}")
-    private String pathMapping;
-
-    /**
-     * 创建API
-     */
-    @Bean
-    public Docket createRestApi()
-    {
-        return new Docket(DocumentationType.SWAGGER_2)
-                // 是否启用Swagger
-                .enable(enabled)
-                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
-                .apiInfo(apiInfo())
-                // 设置哪些接口暴露给Swagger展示
-                .select()
-                // 扫描所有有注解的api,用这种方式更灵活
-                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
-                // 扫描指定包中的swagger注解
-                // .apis(RequestHandlerSelectors.basePackage("com.fs.project.tool.swagger"))
-                // 扫描所有 .apis(RequestHandlerSelectors.any())
-                .paths(PathSelectors.any())
-                .build()
-                /* 设置安全模式,swagger可以设置访问token */
-                .securitySchemes(securitySchemes())
-                .securityContexts(securityContexts())
-                .pathMapping(pathMapping);
-    }
-
-    /**
-     * 安全模式,这里指定token通过Authorization头请求头传递
-     */
-    private List<ApiKey> securitySchemes()
-    {
-        List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
-        apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
-        return apiKeyList;
-    }
-
-    /**
-     * 安全上下文
-     */
-    private List<SecurityContext> securityContexts()
-    {
-        List<SecurityContext> securityContexts = new ArrayList<>();
-        securityContexts.add(
-                SecurityContext.builder()
-                        .securityReferences(defaultAuth())
-                        .forPaths(PathSelectors.regex("^(?!auth).*$"))
-                        .build());
-        return securityContexts;
-    }
-
-    /**
-     * 默认的安全上引用
-     */
-    private List<SecurityReference> defaultAuth()
-    {
-        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
-        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
-        authorizationScopes[0] = authorizationScope;
-        List<SecurityReference> securityReferences = new ArrayList<>();
-        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
-        return securityReferences;
-    }
-
-    /**
-     * 添加摘要信息
-     */
-    private ApiInfo apiInfo()
-    {
-        // 用ApiInfoBuilder进行定制
-        return new ApiInfoBuilder()
-                // 设置标题
-                .title("标题:FS管理系统_接口文档")
-                // 描述
-                .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
-                // 作者信息
-                .contact(new Contact(fsConfig.getName(), null, null))
-                // 版本
-                .version("版本号:" + fsConfig.getVersion())
-                .build();
-    }
-}

+ 0 - 10
fs-qw-task/src/main/java/com/fs/framework/config/TenantPrincipal.java

@@ -1,10 +0,0 @@
-package com.fs.framework.config;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@Getter
-@AllArgsConstructor
-public class TenantPrincipal {
-    private final Long tenantId;
-}

+ 0 - 115
fs-qw-task/src/main/java/com/fs/framework/config/ThreadPoolConfig.java

@@ -1,115 +0,0 @@
-package com.fs.framework.config;
-
-import com.fs.common.utils.Threads;
-import org.apache.commons.lang3.concurrent.BasicThreadFactory;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.scheduling.TaskScheduler;
-import org.springframework.scheduling.annotation.EnableAsync;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
-
-import java.util.concurrent.Executor;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.ThreadPoolExecutor;
-
-/**
- * 线程池配置
- *
-
- **/
-@Configuration
-@EnableAsync
-public class ThreadPoolConfig
-{
-    // 核心线程池大小
-    private int corePoolSize = 50;
-
-    // 最大可创建的线程数
-    private int maxPoolSize = 300;
-
-    // 队列最大长度
-    private int queueCapacity = 1000;
-
-    // 线程池维护线程所允许的空闲时间
-    private int keepAliveSeconds = 300;
-
-
-    @Bean
-    public TaskScheduler taskScheduler(){
-        ThreadPoolTaskScheduler scheduler=new ThreadPoolTaskScheduler();
-        scheduler.setPoolSize(18);
-        scheduler.setThreadNamePrefix("scheduled-task-");
-        scheduler.setAwaitTerminationSeconds(60);
-        scheduler.setWaitForTasksToCompleteOnShutdown(true);
-        return scheduler;
-    }
-
-    @Bean(name = "threadPoolTaskExecutor")
-    public ThreadPoolTaskExecutor threadPoolTaskExecutor()
-    {
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        executor.setMaxPoolSize(maxPoolSize);
-        executor.setCorePoolSize(corePoolSize);
-        executor.setQueueCapacity(queueCapacity);
-        executor.setKeepAliveSeconds(keepAliveSeconds);
-        // 线程池对拒绝任务(无线程可用)的处理策略
-        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
-        return executor;
-    }
-
-    /**
-     * 执行周期性或定时任务
-     */
-    @Bean(name = "scheduledExecutorService")
-    protected ScheduledExecutorService scheduledExecutorService()
-    {
-        return new ScheduledThreadPoolExecutor(corePoolSize,
-                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
-        {
-            @Override
-            protected void afterExecute(Runnable r, Throwable t)
-            {
-                super.afterExecute(r, t);
-                Threads.printException(r, t);
-            }
-        };
-    }
-
-    @Bean(name = "sopTaskExecutor")
-    public Executor sopTaskExecutor() {
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        executor.setCorePoolSize(16); // 根据需求调整
-        executor.setMaxPoolSize(32);  // 根据需求调整
-        executor.setQueueCapacity(800); // 根据需求调整
-        executor.setThreadNamePrefix("SopTask-");
-        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
-        executor.initialize();
-        return executor;
-    }
-
-    @Bean(name = "sopChatTaskExecutor")
-    public Executor batchInsertExecutor() {
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        executor.setCorePoolSize(16);
-        executor.setMaxPoolSize(32);
-        executor.setQueueCapacity(800);
-        executor.setThreadNamePrefix("BatchInsert-");
-        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
-        executor.initialize();
-        return executor;
-    }
-
-    @Bean(name = "sopRatingExecutor")
-    public Executor sopRatingExecutor() {
-        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
-        executor.setCorePoolSize(16); // 根据需求调整
-        executor.setMaxPoolSize(32);  // 根据需求调整
-        executor.setQueueCapacity(800); // 根据需求调整
-        executor.setThreadNamePrefix("SopRating-");
-        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
-        executor.initialize();
-        return executor;
-    }
-}

+ 0 - 77
fs-qw-task/src/main/java/com/fs/framework/config/properties/DruidProperties.java

@@ -1,77 +0,0 @@
-package com.fs.framework.config.properties;
-
-import com.alibaba.druid.pool.DruidDataSource;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * druid 配置属性
- *
-
- */
-@Configuration
-public class DruidProperties
-{
-    @Value("${spring.datasource.mysql.druid.initialSize}")
-    private int initialSize;
-
-    @Value("${spring.datasource.mysql.druid.minIdle}")
-    private int minIdle;
-
-    @Value("${spring.datasource.mysql.druid.maxActive}")
-    private int maxActive;
-
-    @Value("${spring.datasource.mysql.druid.maxWait}")
-    private int maxWait;
-
-    @Value("${spring.datasource.mysql.druid.timeBetweenEvictionRunsMillis}")
-    private int timeBetweenEvictionRunsMillis;
-
-    @Value("${spring.datasource.mysql.druid.minEvictableIdleTimeMillis}")
-    private int minEvictableIdleTimeMillis;
-
-    @Value("${spring.datasource.mysql.druid.maxEvictableIdleTimeMillis}")
-    private int maxEvictableIdleTimeMillis;
-
-    @Value("${spring.datasource.mysql.druid.validationQuery}")
-    private String validationQuery;
-
-    @Value("${spring.datasource.mysql.druid.testWhileIdle}")
-    private boolean testWhileIdle;
-
-    @Value("${spring.datasource.mysql.druid.testOnBorrow}")
-    private boolean testOnBorrow;
-
-    @Value("${spring.datasource.mysql.druid.testOnReturn}")
-    private boolean testOnReturn;
-
-    public DruidDataSource dataSource(DruidDataSource datasource)
-    {
-        /** 配置初始化大小、最小、最大 */
-        datasource.setInitialSize(initialSize);
-        datasource.setMaxActive(maxActive);
-        datasource.setMinIdle(minIdle);
-
-        /** 配置获取连接等待超时的时间 */
-        datasource.setMaxWait(maxWait);
-
-        /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
-        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
-
-        /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
-        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
-        datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
-
-        /**
-         * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
-         */
-        datasource.setValidationQuery(validationQuery);
-        /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */
-        datasource.setTestWhileIdle(testWhileIdle);
-        /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
-        datasource.setTestOnBorrow(testOnBorrow);
-        /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
-        datasource.setTestOnReturn(testOnReturn);
-        return datasource;
-    }
-}

+ 0 - 27
fs-qw-task/src/main/java/com/fs/framework/datasource/DynamicDataSource.java

@@ -1,27 +0,0 @@
-package com.fs.framework.datasource;
-
-import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
-
-import javax.sql.DataSource;
-import java.util.Map;
-
-/**
- * 动态数据源
- *
-
- */
-public class DynamicDataSource extends AbstractRoutingDataSource
-{
-    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
-    {
-        super.setDefaultTargetDataSource(defaultTargetDataSource);
-        super.setTargetDataSources(targetDataSources);
-        super.afterPropertiesSet();
-    }
-
-    @Override
-    protected Object determineCurrentLookupKey()
-    {
-        return DynamicDataSourceContextHolder.getDataSourceType();
-    }
-}

+ 0 - 45
fs-qw-task/src/main/java/com/fs/framework/datasource/DynamicDataSourceContextHolder.java

@@ -1,45 +0,0 @@
-package com.fs.framework.datasource;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * 数据源切换处理
- *
-
- */
-public class DynamicDataSourceContextHolder
-{
-    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
-
-    /**
-     * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
-     *  所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
-     */
-    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
-
-    /**
-     * 设置数据源的变量
-     */
-    public static void setDataSourceType(String dsType)
-    {
-//        log.info("切换到{}数据源", dsType);
-        CONTEXT_HOLDER.set(dsType);
-    }
-
-    /**
-     * 获得数据源的变量
-     */
-    public static String getDataSourceType()
-    {
-        return CONTEXT_HOLDER.get();
-    }
-
-    /**
-     * 清空数据源变量
-     */
-    public static void clearDataSourceType()
-    {
-        CONTEXT_HOLDER.remove();
-    }
-}

+ 0 - 71
fs-qw-task/src/main/java/com/fs/framework/datasource/TenantDataSourceManager.java

@@ -1,71 +0,0 @@
-package com.fs.framework.datasource;
-
-import com.alibaba.druid.pool.DruidDataSource;
-import com.fs.tenant.domain.TenantInfo;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-import javax.sql.DataSource;
-import java.lang.reflect.Field;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 租户数据源管理,SaaS 模式下定时任务按租户切库时使用。
- */
-@Component
-public class TenantDataSourceManager {
-
-    @Resource
-    private DynamicDataSource dynamicDataSource;
-
-    private static final Map<String, DataSource> TENANT_DS_CACHE = new ConcurrentHashMap<>();
-
-    public void switchTenant(TenantInfo tenantInfo) {
-        String tenantKey = buildTenantKey(tenantInfo.getId());
-        if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
-            synchronized (this) {
-                if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
-                    DataSource tenantDs = createTenantDataSource(tenantInfo);
-                    TENANT_DS_CACHE.put(tenantKey, tenantDs);
-                    Map<Object, DataSource> resolvedMap = getResolvedDataSources();
-                    resolvedMap.put(tenantKey, tenantDs);
-                }
-            }
-        }
-        DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
-    }
-
-    private String buildTenantKey(Long tenantId) {
-        return "tenant:" + tenantId;
-    }
-
-    public void clear() {
-        DynamicDataSourceContextHolder.clearDataSourceType();
-    }
-
-    private DataSource createTenantDataSource(TenantInfo tenant) {
-        DruidDataSource ds = new DruidDataSource();
-        ds.setUrl(tenant.getDbUrl());
-        ds.setUsername(tenant.getDbAccount());
-        ds.setPassword(tenant.getDbPwd());
-        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
-        ds.setInitialSize(5);
-        ds.setMinIdle(10);
-        ds.setMaxActive(20);
-        ds.setMaxWait(60000);
-        return ds;
-    }
-
-    @SuppressWarnings("unchecked")
-    private Map<Object, DataSource> getResolvedDataSources() {
-        try {
-            Field field = org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource.class
-                    .getDeclaredField("resolvedDataSources");
-            field.setAccessible(true);
-            return (Map<Object, DataSource>) field.get(dynamicDataSource);
-        } catch (Exception e) {
-            throw new IllegalStateException("获取 resolvedDataSources 失败", e);
-        }
-    }
-}

+ 0 - 115
fs-qw-task/src/main/java/com/fs/framework/exception/GlobalExceptionHandler.java

@@ -1,115 +0,0 @@
-package com.fs.framework.exception;
-
-import com.fs.common.constant.HttpStatus;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.exception.DemoModeException;
-import com.fs.common.exception.ServiceException;
-import com.fs.common.utils.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.validation.BindException;
-import org.springframework.web.HttpRequestMethodNotSupportedException;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * 全局异常处理器
- *
-
- */
-@RestControllerAdvice
-public class GlobalExceptionHandler
-{
-    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
-
-    /**
-     * 权限校验异常
-     */
-    @ExceptionHandler(AccessDeniedException.class)
-    public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request)
-    {
-        String requestURI = request.getRequestURI();
-        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());
-        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限,请联系管理员授权");
-    }
-
-    /**
-     * 请求方式不支持
-     */
-    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
-    public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
-            HttpServletRequest request)
-    {
-        String requestURI = request.getRequestURI();
-        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
-        return AjaxResult.error(e.getMessage());
-    }
-
-    /**
-     * 业务异常
-     */
-    @ExceptionHandler(ServiceException.class)
-    public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
-    {
-        log.error(e.getMessage(), e);
-        Integer code = e.getCode();
-        return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
-    }
-
-    /**
-     * 拦截未知的运行时异常
-     */
-    @ExceptionHandler(RuntimeException.class)
-    public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
-    {
-        String requestURI = request.getRequestURI();
-        log.error("请求地址'{}',发生未知异常.", requestURI, e);
-        return AjaxResult.error(e.getMessage());
-    }
-
-    /**
-     * 系统异常
-     */
-    @ExceptionHandler(Exception.class)
-    public AjaxResult handleException(Exception e, HttpServletRequest request)
-    {
-        String requestURI = request.getRequestURI();
-        log.error("请求地址'{}',发生系统异常.", requestURI, e);
-        return AjaxResult.error(e.getMessage());
-    }
-
-    /**
-     * 自定义验证异常
-     */
-    @ExceptionHandler(BindException.class)
-    public AjaxResult handleBindException(BindException e)
-    {
-        log.error(e.getMessage(), e);
-        String message = e.getAllErrors().get(0).getDefaultMessage();
-        return AjaxResult.error(message);
-    }
-
-    /**
-     * 自定义验证异常
-     */
-    @ExceptionHandler(MethodArgumentNotValidException.class)
-    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e)
-    {
-        log.error(e.getMessage(), e);
-        String message = e.getBindingResult().getFieldError().getDefaultMessage();
-        return AjaxResult.error(message);
-    }
-
-    /**
-     * 演示模式异常
-     */
-    @ExceptionHandler(DemoModeException.class)
-    public AjaxResult handleDemoModeException(DemoModeException e)
-    {
-        return AjaxResult.error("演示模式,不允许操作");
-    }
-}

+ 0 - 56
fs-qw-task/src/main/java/com/fs/framework/interceptor/RepeatSubmitInterceptor.java

@@ -1,56 +0,0 @@
-package com.fs.framework.interceptor;
-
-import com.alibaba.fastjson.JSONObject;
-import com.fs.common.annotation.RepeatSubmit;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.utils.ServletUtils;
-import org.springframework.stereotype.Component;
-import org.springframework.web.method.HandlerMethod;
-import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.lang.reflect.Method;
-
-/**
- * 防止重复提交拦截器
- *
-
- */
-@Component
-public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
-{
-    @Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
-    {
-        if (handler instanceof HandlerMethod)
-        {
-            HandlerMethod handlerMethod = (HandlerMethod) handler;
-            Method method = handlerMethod.getMethod();
-            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
-            if (annotation != null)
-            {
-                if (this.isRepeatSubmit(request))
-                {
-                    AjaxResult ajaxResult = AjaxResult.error("不允许重复提交,请稍后再试");
-                    ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult));
-                    return false;
-                }
-            }
-            return true;
-        }
-        else
-        {
-            return super.preHandle(request, response, handler);
-        }
-    }
-
-    /**
-     * 验证是否重复提交由子类实现具体的防重复提交的规则
-     *
-     * @param request
-     * @return
-     * @throws Exception
-     */
-    public abstract boolean isRepeatSubmit(HttpServletRequest request);
-}

+ 0 - 126
fs-qw-task/src/main/java/com/fs/framework/interceptor/impl/SameUrlDataInterceptor.java

@@ -1,126 +0,0 @@
-package com.fs.framework.interceptor.impl;
-
-import com.alibaba.fastjson.JSONObject;
-import com.fs.common.constant.Constants;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.filter.RepeatedlyRequestWrapper;
-import com.fs.common.utils.StringUtils;
-import com.fs.common.utils.http.HttpHelper;
-import com.fs.framework.interceptor.RepeatSubmitInterceptor;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 判断请求url和数据是否和上一次相同,
- * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
- *
-
- */
-@Component
-public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
-{
-    public final String REPEAT_PARAMS = "repeatParams";
-
-    public final String REPEAT_TIME = "repeatTime";
-
-    // 令牌自定义标识
-    @Value("${token.header}")
-    private String header;
-
-    @Autowired
-    private RedisCache redisCache;
-
-    /**
-     * 间隔时间,单位:秒 默认10秒
-     *
-     * 两次相同参数的请求,如果间隔时间大于该参数,系统不会认定为重复提交的数据
-     */
-    private int intervalTime = 10;
-
-    public void setIntervalTime(int intervalTime)
-    {
-        this.intervalTime = intervalTime;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public boolean isRepeatSubmit(HttpServletRequest request)
-    {
-        String nowParams = "";
-        if (request instanceof RepeatedlyRequestWrapper)
-        {
-            RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
-            nowParams = HttpHelper.getBodyString(repeatedlyRequest);
-        }
-
-        // body参数为空,获取Parameter的数据
-        if (StringUtils.isEmpty(nowParams))
-        {
-            nowParams = JSONObject.toJSONString(request.getParameterMap());
-        }
-        Map<String, Object> nowDataMap = new HashMap<String, Object>();
-        nowDataMap.put(REPEAT_PARAMS, nowParams);
-        nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
-
-        // 请求地址(作为存放cache的key值)
-        String url = request.getRequestURI();
-
-        // 唯一值(没有消息头则使用请求地址)
-        String submitKey = request.getHeader(header);
-        if (StringUtils.isEmpty(submitKey))
-        {
-            submitKey = url;
-        }
-
-        // 唯一标识(指定key + 消息头)
-        String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
-
-        Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
-        if (sessionObj != null)
-        {
-            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
-            if (sessionMap.containsKey(url))
-            {
-                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
-                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap))
-                {
-                    return true;
-                }
-            }
-        }
-        Map<String, Object> cacheMap = new HashMap<String, Object>();
-        cacheMap.put(url, nowDataMap);
-        redisCache.setCacheObject(cacheRepeatKey, cacheMap, intervalTime, TimeUnit.SECONDS);
-        return false;
-    }
-
-    /**
-     * 判断参数是否相同
-     */
-    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap)
-    {
-        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
-        String preParams = (String) preMap.get(REPEAT_PARAMS);
-        return nowParams.equals(preParams);
-    }
-
-    /**
-     * 判断两次间隔时间
-     */
-    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap)
-    {
-        long time1 = (Long) nowMap.get(REPEAT_TIME);
-        long time2 = (Long) preMap.get(REPEAT_TIME);
-        if ((time1 - time2) < (this.intervalTime * 1000))
-        {
-            return true;
-        }
-        return false;
-    }
-}

+ 0 - 56
fs-qw-task/src/main/java/com/fs/framework/manager/AsyncManager.java

@@ -1,56 +0,0 @@
-package com.fs.framework.manager;
-
-import com.fs.common.utils.Threads;
-import com.fs.common.utils.spring.SpringUtils;
-
-import java.util.TimerTask;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 异步任务管理器
- * 
- 
- */
-public class AsyncManager
-{
-    /**
-     * 操作延迟10毫秒
-     */
-    private final int OPERATE_DELAY_TIME = 10;
-
-    /**
-     * 异步操作任务调度线程池
-     */
-    private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
-
-    /**
-     * 单例模式
-     */
-    private AsyncManager(){}
-
-    private static AsyncManager me = new AsyncManager();
-
-    public static AsyncManager me()
-    {
-        return me;
-    }
-
-    /**
-     * 执行任务
-     * 
-     * @param task 任务
-     */
-    public void execute(TimerTask task)
-    {
-        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
-    }
-
-    /**
-     * 停止任务线程池
-     */
-    public void shutdown()
-    {
-        Threads.shutdownAndAwaitTermination(executor);
-    }
-}

+ 0 - 40
fs-qw-task/src/main/java/com/fs/framework/manager/ShutdownManager.java

@@ -1,40 +0,0 @@
-package com.fs.framework.manager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.PreDestroy;
-
-/**
- * 确保应用退出时能关闭后台线程
- *
- 
- */
-@Component
-public class ShutdownManager
-{
-    private static final Logger logger = LoggerFactory.getLogger("sys-user");
-
-    @PreDestroy
-    public void destroy()
-    {
-        shutdownAsyncManager();
-    }
-
-    /**
-     * 停止异步执行任务
-     */
-    private void shutdownAsyncManager()
-    {
-        try
-        {
-            logger.info("====关闭后台任务任务线程池====");
-            AsyncManager.me().shutdown();
-        }
-        catch (Exception e)
-        {
-            logger.error(e.getMessage(), e);
-        }
-    }
-}

+ 0 - 106
fs-qw-task/src/main/java/com/fs/framework/manager/factory/AsyncFactory.java

@@ -1,106 +0,0 @@
-package com.fs.framework.manager.factory;
-
-import com.fs.common.constant.Constants;
-import com.fs.common.utils.LogUtils;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.ip.AddressUtils;
-import com.fs.common.utils.ip.IpUtils;
-import com.fs.common.utils.spring.SpringUtils;
-import com.fs.company.domain.CompanyLogininfor;
-import com.fs.company.domain.CompanyOperLog;
-import com.fs.company.service.ICompanyLogininforService;
-import com.fs.company.service.ICompanyOperLogService;
-import eu.bitwalker.useragentutils.UserAgent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Date;
-import java.util.TimerTask;
-
-/**
- * 异步工厂(产生任务用)
- * 
-
- */
-public class AsyncFactory
-{
-    private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
-
-    /**
-     * 记录登录信息
-     * 
-     * @param username 用户名
-     * @param status 状态
-     * @param message 消息
-     * @param args 列表
-     * @return 任务task
-     */
-    public static TimerTask recordLogininfor(final Long companyId,final String username, final String status, final String message,
-            final Object... args)
-    {
-        final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
-        final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
-        return new TimerTask()
-        {
-            @Override
-            public void run()
-            {
-                String address = AddressUtils.getRealAddressByIP(ip);
-                StringBuilder s = new StringBuilder();
-                s.append(LogUtils.getBlock(ip));
-                s.append(address);
-                s.append(LogUtils.getBlock(username));
-                s.append(LogUtils.getBlock(status));
-                s.append(LogUtils.getBlock(message));
-                // 打印信息到日志
-                sys_user_logger.info(s.toString(), args);
-                // 获取客户端操作系统
-                String os = userAgent.getOperatingSystem().getName();
-                // 获取客户端浏览器
-                String browser = userAgent.getBrowser().getName();
-                // 封装对象
-                CompanyLogininfor logininfor = new CompanyLogininfor();
-                logininfor.setCompanyId(companyId);
-                logininfor.setUserName(username);
-                logininfor.setIpaddr(ip);
-                logininfor.setLoginLocation(address);
-                logininfor.setBrowser(browser);
-                logininfor.setOs(os);
-                logininfor.setMsg(message);
-                // 日志状态
-                if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
-                {
-                    logininfor.setStatus(Constants.SUCCESS);
-                }
-                else if (Constants.LOGIN_FAIL.equals(status))
-                {
-                    logininfor.setStatus(Constants.FAIL);
-                }
-                logininfor.setLoginTime(new Date());
-                // 插入数据
-                SpringUtils.getBean(ICompanyLogininforService.class).insertCompanyLogininfor(logininfor);
-            }
-        };
-    }
-
-    /**
-     * 操作日志记录
-     * 
-     * @param operLog 操作日志信息
-     * @return 任务task
-     */
-    public static TimerTask recordOper(final CompanyOperLog operLog)
-    {
-        return new TimerTask()
-        {
-            @Override
-            public void run()
-            {
-                // 远程查询操作地点
-                operLog.setOperTime(new Date());
-                operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
-                SpringUtils.getBean(ICompanyOperLogService.class).insertCompanyOperLog(operLog);
-            }
-        };
-    }
-}

+ 0 - 69
fs-qw-task/src/main/java/com/fs/framework/security/LoginBody.java

@@ -1,69 +0,0 @@
-package com.fs.framework.security;
-
-/**
- * 用户登录对象
- * 
-
- */
-public class LoginBody
-{
-    /**
-     * 用户名
-     */
-    private String username;
-
-    /**
-     * 用户密码
-     */
-    private String password;
-
-    /**
-     * 验证码
-     */
-    private String code;
-
-    /**
-     * 唯一标识
-     */
-    private String uuid = "";
-
-    public String getUsername()
-    {
-        return username;
-    }
-
-    public void setUsername(String username)
-    {
-        this.username = username;
-    }
-
-    public String getPassword()
-    {
-        return password;
-    }
-
-    public void setPassword(String password)
-    {
-        this.password = password;
-    }
-
-    public String getCode()
-    {
-        return code;
-    }
-
-    public void setCode(String code)
-    {
-        this.code = code;
-    }
-
-    public String getUuid()
-    {
-        return uuid;
-    }
-
-    public void setUuid(String uuid)
-    {
-        this.uuid = uuid;
-    }
-}

+ 0 - 255
fs-qw-task/src/main/java/com/fs/framework/security/LoginUser.java

@@ -1,255 +0,0 @@
-package com.fs.framework.security;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fs.company.domain.Company;
-import com.fs.company.domain.CompanyUser;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import java.util.Collection;
-import java.util.Set;
-
-/**
- * 登录用户身份权限
- * 
-
- */
-public class LoginUser implements UserDetails
-{
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 用户唯一标识
-     */
-    private String token;
-
-    /**
-     * 登录时间
-     */
-    private Long loginTime;
-
-    /**
-     * 过期时间
-     */
-    private Long expireTime;
-
-    /**
-     * 登录IP地址
-     */
-    private String ipaddr;
-
-    /**
-     * 登录地点
-     */
-    private String loginLocation;
-
-    /**
-     * 浏览器类型
-     */
-    private String browser;
-
-    /**
-     * 操作系统
-     */
-    private String os;
-
-
-
-    /**
-     * 权限列表
-     */
-    private Set<String> permissions;
-
-    /**
-     * 用户信息
-     */
-    private CompanyUser user;
-
-    private Company company;
-
-
-
-    public static long getSerialVersionUID() {
-        return serialVersionUID;
-    }
-
-
-
-    public Company getCompany() {
-        return company;
-    }
-
-    public void setCompany(Company company) {
-        this.company = company;
-    }
-
-    public String getToken()
-    {
-        return token;
-    }
-
-    public void setToken(String token)
-    {
-        this.token = token;
-    }
-
-    public LoginUser()
-    {
-    }
-    public LoginUser(CompanyUser user, Set<String> permissions, Company company)
-    {
-        this.user = user;
-        this.permissions = permissions;
-        this.company=company;
-    }
-    public LoginUser(CompanyUser user, Set<String> permissions)
-    {
-        this.user = user;
-        this.permissions = permissions;
-    }
-
-    @JsonIgnore
-    @Override
-    public String getPassword()
-    {
-        return user.getPassword();
-    }
-
-    @Override
-    public String getUsername()
-    {
-        return user.getUserName();
-    }
-
-    /**
-     * 账户是否未过期,过期无法验证
-     */
-    @JsonIgnore
-    @Override
-    public boolean isAccountNonExpired()
-    {
-        return true;
-    }
-
-    /**
-     * 指定用户是否解锁,锁定的用户无法进行身份验证
-     * 
-     * @return
-     */
-    @JsonIgnore
-    @Override
-    public boolean isAccountNonLocked()
-    {
-        return true;
-    }
-
-    /**
-     * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
-     * 
-     * @return
-     */
-    @JsonIgnore
-    @Override
-    public boolean isCredentialsNonExpired()
-    {
-        return true;
-    }
-
-    /**
-     * 是否可用 ,禁用的用户不能身份验证
-     * 
-     * @return
-     */
-    @JsonIgnore
-    @Override
-    public boolean isEnabled()
-    {
-        return true;
-    }
-
-    public Long getLoginTime()
-    {
-        return loginTime;
-    }
-
-    public void setLoginTime(Long loginTime)
-    {
-        this.loginTime = loginTime;
-    }
-
-    public String getIpaddr()
-    {
-        return ipaddr;
-    }
-
-    public void setIpaddr(String ipaddr)
-    {
-        this.ipaddr = ipaddr;
-    }
-
-    public String getLoginLocation()
-    {
-        return loginLocation;
-    }
-
-    public void setLoginLocation(String loginLocation)
-    {
-        this.loginLocation = loginLocation;
-    }
-
-    public String getBrowser()
-    {
-        return browser;
-    }
-
-    public void setBrowser(String browser)
-    {
-        this.browser = browser;
-    }
-
-    public String getOs()
-    {
-        return os;
-    }
-
-    public void setOs(String os)
-    {
-        this.os = os;
-    }
-
-    public Long getExpireTime()
-    {
-        return expireTime;
-    }
-
-    public void setExpireTime(Long expireTime)
-    {
-        this.expireTime = expireTime;
-    }
-
-    public Set<String> getPermissions()
-    {
-        return permissions;
-    }
-
-    public void setPermissions(Set<String> permissions)
-    {
-        this.permissions = permissions;
-    }
-
-    public CompanyUser getUser()
-    {
-        return user;
-    }
-
-    public void setUser(CompanyUser user)
-    {
-        this.user = user;
-    }
-
-    @Override
-    public Collection<? extends GrantedAuthority> getAuthorities()
-    {
-        return null;
-    }
-}

+ 0 - 89
fs-qw-task/src/main/java/com/fs/framework/security/SecurityUtils.java

@@ -1,89 +0,0 @@
-package com.fs.framework.security;
-
-import com.fs.common.constant.HttpStatus;
-import com.fs.common.exception.CustomException;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-
-/**
- * 安全服务工具类
- * 
-
- */
-public class SecurityUtils
-{
-    /**
-     * 获取用户账户
-     **/
-    public static String getUsername()
-    {
-        try
-        {
-            return getLoginUser().getUsername();
-        }
-        catch (Exception e)
-        {
-            throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
-        }
-    }
-
-    /**
-     * 获取用户
-     **/
-    public static LoginUser getLoginUser()
-    {
-        try
-        {
-            return (LoginUser) getAuthentication().getPrincipal();
-        }
-        catch (Exception e)
-        {
-            throw new CustomException("获取用户信息异常", HttpStatus.UNAUTHORIZED);
-        }
-    }
-
-    /**
-     * 获取Authentication
-     */
-    public static Authentication getAuthentication()
-    {
-        return SecurityContextHolder.getContext().getAuthentication();
-    }
-
-    /**
-     * 生成BCryptPasswordEncoder密码
-     *
-     * @param password 密码
-     * @return 加密字符串
-     */
-    public static String encryptPassword(String password)
-    {
-        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
-        return passwordEncoder.encode(password);
-    }
-
-    /**
-     * 判断密码是否相同
-     *
-     * @param rawPassword 真实密码
-     * @param encodedPassword 加密后字符
-     * @return 结果
-     */
-    public static boolean matchesPassword(String rawPassword, String encodedPassword)
-    {
-        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
-        return passwordEncoder.matches(rawPassword, encodedPassword);
-    }
-
-    /**
-     * 是否为管理员
-     * 
-     * @param userId 用户ID
-     * @return 结果
-     */
-    public static boolean isAdmin(Long userId)
-    {
-        return userId != null && 1L == userId;
-    }
-}

+ 0 - 47
fs-qw-task/src/main/java/com/fs/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -1,47 +0,0 @@
-package com.fs.framework.security.filter;
-
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.utils.StringUtils;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.security.SecurityUtils;
-import com.fs.framework.service.TokenService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * token过滤器 验证token有效性
- *
-
- */
-@Component
-public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
-{
-    @Autowired
-    private TokenService tokenService;
-    @Autowired
-    private RedisCache redisCache;
-    @Override
-    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
-            throws ServletException, IOException
-    {
-        LoginUser loginUser = tokenService.getLoginUser(request);
-        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
-        {
-            tokenService.verifyToken(loginUser);
-            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
-            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
-        }
-        chain.doFilter(request, response);
-    }
-}

+ 0 - 35
fs-qw-task/src/main/java/com/fs/framework/security/handle/AuthenticationEntryPointImpl.java

@@ -1,35 +0,0 @@
-package com.fs.framework.security.handle;
-
-import com.alibaba.fastjson.JSON;
-import com.fs.common.constant.HttpStatus;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.web.AuthenticationEntryPoint;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.Serializable;
-
-/**
- * 认证失败处理类 返回未授权
- * 
- 
- */
-@Component
-public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable
-{
-    private static final long serialVersionUID = -8970718410437077606L;
-
-    @Override
-    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
-            throws IOException
-    {
-        int code = HttpStatus.UNAUTHORIZED;
-        String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
-        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg)));
-    }
-}

+ 0 - 54
fs-qw-task/src/main/java/com/fs/framework/security/handle/LogoutSuccessHandlerImpl.java

@@ -1,54 +0,0 @@
-package com.fs.framework.security.handle;
-
-import com.alibaba.fastjson.JSON;
-import com.fs.common.constant.Constants;
-import com.fs.common.constant.HttpStatus;
-import com.fs.common.core.domain.AjaxResult;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
-import com.fs.framework.service.TokenService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * 自定义退出处理类 返回成功
- *
-
- */
-@Configuration
-public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
-{
-    @Autowired
-    private TokenService tokenService;
-
-    /**
-     * 退出处理
-     *
-     * @return
-     */
-    @Override
-    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
-            throws IOException, ServletException
-    {
-        LoginUser loginUser = tokenService.getLoginUser(request);
-        if (StringUtils.isNotNull(loginUser))
-        {
-            String userName = loginUser.getUsername();
-            // 删除用户缓存记录
-            tokenService.delLoginUser(loginUser.getToken());
-            // 记录用户退出日志
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginUser.getCompany().getCompanyId(),userName, Constants.LOGOUT, "退出成功"));
-        }
-        ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
-    }
-}

+ 0 - 93
fs-qw-task/src/main/java/com/fs/framework/service/CompanyLoginService.java

@@ -1,93 +0,0 @@
-package com.fs.framework.service;
-
-import com.fs.common.constant.Constants;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.exception.ServiceException;
-import com.fs.common.exception.user.CaptchaException;
-import com.fs.common.exception.user.CaptchaExpireException;
-import com.fs.common.exception.user.UserPasswordNotMatchException;
-import com.fs.common.utils.MessageUtils;
-import com.fs.framework.manager.AsyncManager;
-import com.fs.framework.manager.factory.AsyncFactory;
-import com.fs.framework.security.LoginUser;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 登录校验方法
- *
-
- */
-@Component
-public class CompanyLoginService
-{
-    @Autowired
-    private TokenService tokenService;
-
-    @Resource
-    private AuthenticationManager authenticationManager;
-
-    @Autowired
-    private RedisCache redisCache;
-
-    /**
-     * 登录验证
-     *
-     * @param username 用户名
-     * @param password 密码
-     * @param code 验证码
-     * @param uuid 唯一标识
-     * @return 结果
-     */
-    public String login(String username, String password, String code, String uuid)
-    {
-        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
-        Object captchaObj = redisCache.getCacheObject(verifyKey);
-        String captcha = captchaObj != null ? String.valueOf(captchaObj) : null;
-        redisCache.deleteObject(verifyKey);
-        if (captcha == null)
-        {
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
-            throw new CaptchaExpireException();
-        }
-        if (!code.equalsIgnoreCase(captcha))
-        {
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
-            throw new CaptchaException();
-        }
-        // 用户验证
-        Authentication authentication = null;
-        try
-        {
-            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
-            authentication = authenticationManager
-                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
-        }
-        catch (Exception e)
-        {
-            if (e instanceof BadCredentialsException)
-            {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
-                throw new UserPasswordNotMatchException();
-            }
-            else
-            {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, e.getMessage()));
-                throw new ServiceException(e.getMessage());
-            }
-        }
-        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
-        AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginUser.getUser().getCompanyId(),username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
-        redisCache.setCacheObject("companyId:"+loginUser.getUser().getUserId(),loginUser.getUser().getCompanyId(),604800, TimeUnit.SECONDS);
-        // 生成token
-        return tokenService.createToken(loginUser);
-    }
-
-}

+ 0 - 66
fs-qw-task/src/main/java/com/fs/framework/service/CompanyPermissionService.java

@@ -1,66 +0,0 @@
-package com.fs.framework.service;
-
-import com.fs.company.domain.CompanyUser;
-import com.fs.company.service.ICompanyMenuService;
-import com.fs.company.service.ICompanyRoleService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * 用户权限处理
- * 
- 
- */
-@Component
-public class CompanyPermissionService
-{
-    @Autowired
-    private ICompanyRoleService roleService;
-    @Autowired
-    private ICompanyMenuService menuService;
-
-    /**
-     * 获取角色数据权限
-     * 
-     * @param user 用户信息
-     * @return 角色权限信息
-     */
-    public Set<String> getRolePermission(CompanyUser user)
-    {
-        Set<String> roles = new HashSet<String>();
-        // 管理员拥有所有权限
-        if (user.isAdmin())
-        {
-            roles.add("admin");
-        }
-        else
-        {
-            roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
-        }
-        return roles;
-    }
-
-    /**
-     * 获取菜单数据权限
-     * 
-     * @param user 用户信息
-     * @return 菜单权限信息
-     */
-    public Set<String> getMenuPermission(CompanyUser user)
-    {
-        Set<String> perms = new HashSet<String>();
-        // 管理员拥有所有权限
-        if (user.isAdmin())
-        {
-            perms.add("*:*:*");
-        }
-        else
-        {
-            perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
-        }
-        return perms;
-    }
-}

+ 0 - 170
fs-qw-task/src/main/java/com/fs/framework/service/PermissionService.java

@@ -1,170 +0,0 @@
-package com.fs.framework.service;
-
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
-import com.fs.company.domain.CompanyRole;
-import com.fs.framework.security.LoginUser;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-
-import java.util.Set;
-
-/**
- * 自定义权限实现,ss取自SpringSecurity首字母
- */
-@Service("ss")
-public class PermissionService
-{
-    /** 所有权限标识 */
-    private static final String ALL_PERMISSION = "*:*:*";
-
-    /** 管理员角色权限标识 */
-    private static final String SUPER_ADMIN = "admin";
-
-    private static final String ROLE_DELIMETER = ",";
-
-    private static final String PERMISSION_DELIMETER = ",";
-
-    @Autowired
-    private TokenService tokenService;
-
-    /**
-     * 验证用户是否具备某权限
-     * 
-     * @param permission 权限字符串
-     * @return 用户是否具备某权限
-     */
-    public boolean hasPermi(String permission)
-    {
-        if (StringUtils.isEmpty(permission))
-        {
-            return false;
-        }
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
-        {
-            return false;
-        }
-        return hasPermissions(loginUser.getPermissions(), permission);
-    }
-
-    /**
-     * 验证用户是否不具备某权限,与 hasPermi逻辑相反
-     *
-     * @param permission 权限字符串
-     * @return 用户是否不具备某权限
-     */
-    public boolean lacksPermi(String permission)
-    {
-        return hasPermi(permission) != true;
-    }
-
-    /**
-     * 验证用户是否具有以下任意一个权限
-     *
-     * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
-     * @return 用户是否具有以下任意一个权限
-     */
-    public boolean hasAnyPermi(String permissions)
-    {
-        if (StringUtils.isEmpty(permissions))
-        {
-            return false;
-        }
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
-        {
-            return false;
-        }
-        Set<String> authorities = loginUser.getPermissions();
-        for (String permission : permissions.split(PERMISSION_DELIMETER))
-        {
-            if (permission != null && hasPermissions(authorities, permission))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 判断用户是否拥有某个角色
-     * 
-     * @param role 角色字符串
-     * @return 用户是否具备某角色
-     */
-    public boolean hasRole(String role)
-    {
-        if (StringUtils.isEmpty(role))
-        {
-            return false;
-        }
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
-        {
-            return false;
-        }
-        for (CompanyRole sysRole : loginUser.getUser().getRoles())
-        {
-            String roleKey = sysRole.getRoleKey();
-            if (SUPER_ADMIN.contains(roleKey) || roleKey.contains(StringUtils.trim(role)))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 验证用户是否不具备某角色,与 isRole逻辑相反。
-     *
-     * @param role 角色名称
-     * @return 用户是否不具备某角色
-     */
-    public boolean lacksRole(String role)
-    {
-        return hasRole(role) != true;
-    }
-
-    /**
-     * 验证用户是否具有以下任意一个角色
-     *
-     * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
-     * @return 用户是否具有以下任意一个角色
-     */
-    public boolean hasAnyRoles(String roles)
-    {
-        if (StringUtils.isEmpty(roles))
-        {
-            return false;
-        }
-        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
-        if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
-        {
-            return false;
-        }
-        for (String role : roles.split(ROLE_DELIMETER))
-        {
-            if (hasRole(role))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 判断是否包含权限
-     * 
-     * @param permissions 权限列表
-     * @param permission 权限字符串
-     * @return 用户是否具备某权限
-     */
-    private boolean hasPermissions(Set<String> permissions, String permission)
-    {
-        return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
-    }
-
-
-}

+ 0 - 236
fs-qw-task/src/main/java/com/fs/framework/service/TokenService.java

@@ -1,236 +0,0 @@
-package com.fs.framework.service;
-
-import com.fs.common.constant.Constants;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.utils.ServletUtils;
-import com.fs.common.utils.StringUtils;
-import com.fs.common.utils.ip.AddressUtils;
-import com.fs.common.utils.ip.IpUtils;
-import com.fs.common.utils.uuid.IdUtils;
-import com.fs.framework.security.LoginUser;
-import eu.bitwalker.useragentutils.UserAgent;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * token验证处理
- *
- 
- */
-@Component
-public class TokenService
-{
-    // 令牌自定义标识
-    @Value("${token.header}")
-    private String header;
-
-    // 令牌秘钥
-    @Value("${token.secret}")
-    private String secret;
-
-    // 令牌有效期(默认30分钟)
-    @Value("${token.expireTime}")
-    private int expireTime;
-
-    protected static final long MILLIS_SECOND = 1000;
-
-    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
-
-    private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 100000000000L;
-
-    @Autowired
-    private RedisCache redisCache;
-
-    /**
-     * 获取用户身份信息
-     *
-     * @return 用户信息
-     */
-    public LoginUser getLoginUser(HttpServletRequest request)
-    {
-        // 获取请求携带的令牌
-        String token = getToken(request);
-        if (StringUtils.isNotEmpty(token))
-        {
-            Claims claims = parseToken(token);
-            // 解析对应的权限以及用户信息
-            String uuid = (String) claims.get(Constants.COMPANY_LOGIN_USER_KEY);
-            String userKey = getTokenKey(uuid);
-            LoginUser user = redisCache.getCacheObject(userKey);
-            return user;
-        }
-        token=getUrlToken(request);
-        if (StringUtils.isNotEmpty(token))
-        {
-            Claims claims = parseToken(token);
-            // 解析对应的权限以及用户信息
-            String uuid = (String) claims.get(Constants.COMPANY_LOGIN_USER_KEY);
-            String userKey = getTokenKey(uuid);
-            LoginUser user = redisCache.getCacheObject(userKey);
-            return user;
-        }
-
-        return null;
-    }
-
-    /**
-     * 设置用户身份信息
-     */
-    public void setLoginUser(LoginUser loginUser)
-    {
-        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
-        {
-            refreshToken(loginUser);
-        }
-    }
-
-    /**
-     * 删除用户身份信息
-     */
-    public void delLoginUser(String token)
-    {
-        if (StringUtils.isNotEmpty(token))
-        {
-            String userKey = getTokenKey(token);
-            redisCache.deleteObject(userKey);
-        }
-    }
-
-    /**
-     * 创建令牌
-     *
-     * @param loginUser 用户信息
-     * @return 令牌
-     */
-    public String createToken(LoginUser loginUser)
-    {
-        String token = IdUtils.fastUUID();
-        loginUser.setToken(token);
-        setUserAgent(loginUser);
-        refreshToken(loginUser);
-
-        Map<String, Object> claims = new HashMap<>();
-        claims.put(Constants.COMPANY_LOGIN_USER_KEY, token);
-        return createToken(claims);
-    }
-
-    /**
-     * 验证令牌有效期,相差不足20分钟,自动刷新缓存
-     *
-     * @param loginUser
-     * @return 令牌
-     */
-    public void verifyToken(LoginUser loginUser)
-    {
-        long expireTime = loginUser.getExpireTime();
-        long currentTime = System.currentTimeMillis();
-        if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
-        {
-            refreshToken(loginUser);
-        }
-    }
-
-    /**
-     * 刷新令牌有效期
-     *
-     * @param loginUser 登录信息
-     */
-    public void refreshToken(LoginUser loginUser)
-    {
-        loginUser.setLoginTime(System.currentTimeMillis());
-        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
-        // 根据uuid将loginUser缓存
-        String userKey = getTokenKey(loginUser.getToken());
-        redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
-    }
-
-    /**
-     * 设置用户代理信息
-     *
-     * @param loginUser 登录信息
-     */
-    public void setUserAgent(LoginUser loginUser)
-    {
-        UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
-        String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
-        loginUser.setIpaddr(ip);
-        loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
-        loginUser.setBrowser(userAgent.getBrowser().getName());
-        loginUser.setOs(userAgent.getOperatingSystem().getName());
-    }
-
-    /**
-     * 从数据声明生成令牌
-     *
-     * @param claims 数据声明
-     * @return 令牌
-     */
-    private String createToken(Map<String, Object> claims)
-    {
-        String token = Jwts.builder()
-                .setClaims(claims)
-                .signWith(SignatureAlgorithm.HS512, secret).compact();
-        return token;
-    }
-
-    /**
-     * 从令牌中获取数据声明
-     *
-     * @param token 令牌
-     * @return 数据声明
-     */
-    private Claims parseToken(String token)
-    {
-        return Jwts.parser()
-                .setSigningKey(secret)
-                .parseClaimsJws(token)
-                .getBody();
-    }
-
-    /**
-     * 从令牌中获取用户名
-     *
-     * @param token 令牌
-     * @return 用户名
-     */
-    public String getUsernameFromToken(String token)
-    {
-        Claims claims = parseToken(token);
-        return claims.getSubject();
-    }
-
-    /**
-     * 获取请求token
-     *
-     * @param request
-     * @return token
-     */
-    private String getToken(HttpServletRequest request)
-    {
-        String token = request.getHeader(header);
-        if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
-        {
-            token = token.replace(Constants.TOKEN_PREFIX, "");
-        }
-        return token;
-    }
-    private String getUrlToken(HttpServletRequest request)
-    {
-        String token = request.getParameter("token");
-        return token;
-    }
-
-    private String getTokenKey(String uuid)
-    {
-        return Constants.COMPANY_LOGIN_TOKEN_KEY + uuid;
-    }
-}

+ 0 - 75
fs-qw-task/src/main/java/com/fs/framework/service/UserDetailsServiceImpl.java

@@ -1,75 +0,0 @@
-package com.fs.framework.service;
-
-
-import com.fs.common.enums.UserStatus;
-import com.fs.common.exception.CustomException;
-import com.fs.common.utils.StringUtils;
-import com.fs.company.domain.Company;
-import com.fs.company.domain.CompanyUser;
-import com.fs.company.service.ICompanyService;
-import com.fs.company.service.ICompanyUserService;
-import com.fs.framework.security.LoginUser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.stereotype.Service;
-
-/**
- * 用户验证处理
- *
- 
- */
-@Service
-public class UserDetailsServiceImpl implements UserDetailsService
-{
-    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
-
-    @Autowired
-    private ICompanyUserService userService;
-
-    @Autowired
-    private CompanyPermissionService permissionService;
-
-    @Autowired
-    private ICompanyService companyService;
-
-
-
-
-    @Override
-    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
-    {
-
-
-        CompanyUser user = userService.selectUserByUserName(username);
-        if (StringUtils.isNull(user))
-        {
-            log.info("登录用户:{} 不存在.", username);
-            throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
-        }
-        Company company=companyService.selectCompanyById(user.getCompanyId()) ;
-        if(company==null||company.getStatus()==0||company.getIsDel()==1){
-            throw new CustomException("此用户所属公司不存在或已停用");
-        }
-        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
-        {
-            log.info("登录用户:{} 已被删除.", username);
-            throw new CustomException("对不起,您的账号:" + username + " 已被删除");
-        }
-        else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
-        {
-            log.info("登录用户:{} 已被停用.", username);
-            throw new CustomException("对不起,您的账号:" + username + " 已停用");
-        }
-
-        return createLoginUser(user);
-    }
-
-    public UserDetails createLoginUser(CompanyUser user)
-    {
-        return new LoginUser(user, permissionService.getMenuPermission(user),companyService.selectCompanyById(user.getCompanyId()));
-    }
-}

+ 0 - 1
fs-qw-task/src/main/resources/META-INF/spring-devtools.properties

@@ -1 +0,0 @@
-restart.include.json=/com.alibaba.fastjson.*.jar

+ 0 - 21
fs-qw-task/src/main/resources/application.yml

@@ -1,21 +0,0 @@
-# 开发环境配置
-server:
-  # 服务器的HTTP端口,默认为8080
-  port: 7006
-
-# Spring配置
-spring:
-  profiles:
-#    active: dev
-#    active: druid-hcl
-#    active: druid-sxjz
-#    active: druid-hdt
-    active: druid-myhk-test
-
-# SaaS 定时任务(主库需有 tenant_info,各租户独立库)
-# saas:
-#   task:
-#     enabled: true          # 为 true 时各 @Scheduled 按租户执行
-#     parallel: false        # 为 true 时按租户并行执行(可提升多租户时整体效率)
-#     parallel:
-#       threads: 4           # 并行时线程池大小,建议不大于租户数并考虑连接池与负载

+ 0 - 2
fs-qw-task/src/main/resources/banner.txt

@@ -1,2 +0,0 @@
-Application Version: ${fs.version}
-Spring Boot Version: ${spring-boot.version}

+ 0 - 37
fs-qw-task/src/main/resources/i18n/messages.properties

@@ -1,37 +0,0 @@
-#错误消息
-not.null=* 必须填写
-user.jcaptcha.error=验证码错误
-user.jcaptcha.expire=验证码已失效
-user.not.exists=用户不存在/密码错误
-user.password.not.match=用户不存在/密码错误
-user.password.retry.limit.count=密码输入错误{0}次
-user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定10分钟
-user.password.delete=对不起,您的账号已被删除
-user.blocked=用户已封禁,请联系管理员
-role.blocked=角色已封禁,请联系管理员
-user.logout.success=退出成功
-
-length.not.valid=长度必须在{min}到{max}个字符之间
-
-user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
-user.password.not.valid=* 5-50个字符
- 
-user.email.not.valid=邮箱格式错误
-user.mobile.phone.number.not.valid=手机号格式错误
-user.login.success=登录成功
-user.register.success=注册成功
-user.notfound=请重新登录
-user.forcelogout=管理员强制退出,请重新登录
-user.unknown.error=未知错误,请重新登录
-
-##文件上传消息
-upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
-upload.filename.exceed.length=上传的文件名最长{0}个字符
-
-##权限
-no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
-no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
-no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
-no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
-no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
-no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]

+ 0 - 19
fs-qw-task/src/main/resources/mybatis/mybatis-config.xml

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!DOCTYPE configuration
-PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-config.dtd">
-<configuration>
-
-	<settings>
-		<setting name="cacheEnabled"             value="true" />  <!-- 全局映射器启用缓存 -->
-		<setting name="useGeneratedKeys"         value="true" />  <!-- 允许 JDBC 支持自动生成主键 -->
-		<setting name="defaultExecutorType"      value="REUSE" /> <!-- 配置默认的执行器 -->
-		<setting name="logImpl"                  value="SLF4J" /> <!-- 指定 MyBatis 所用日志的具体实现 -->
-		 <setting name="mapUnderscoreToCamelCase" value="true"/>
-	</settings>
-
-	<typeHandlers>
-		<typeHandler handler="com.fs.framework.config.ArrayStringTypeHandler"/>
-	</typeHandlers>
-
-</configuration>

+ 0 - 26
fs-service/src/main/java/com/fs/ad/controller/task/BaiduTask.java

@@ -1,26 +0,0 @@
-package com.fs.ad.controller.task;
-
-import com.fs.qw.service.IQwWorkUserService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-@Component("baiduTask")
-public class BaiduTask {
-    private static final Logger log = LoggerFactory.getLogger(BaiduTask.class);
-
-    @Autowired
-    private IQwWorkUserService qwWorkUserService;
-
-    /**
-     * 同步完企微客户,然后对加微的数据信息筛选并上传给百度进行投流优化
-     */
-    public void bdUpload(){
-        qwWorkUserService.uploadBd();
-//        qwWorkUserService.uploadYk();
-    }
-
-
-}

+ 0 - 2
fs-service/src/main/java/com/fs/company/service/workflow/event/UserEventMonitor.java

@@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
@@ -151,7 +150,6 @@ public class UserEventMonitor {
     /**
      * 定时刷新: 每5分钟强制处理缓冲区中的事件
      */
-    @Scheduled(fixedDelay = 300000)
     public void flushBuffer() {
         if (buffer.isEmpty()) return;
         List<Long> keys = new ArrayList<>(buffer.keySet());

+ 1 - 3
fs-service/src/main/java/com/fs/company/service/workflow/evolution/impl/EvolutionSchedulerImpl.java

@@ -12,14 +12,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
 
 /**
  * 自动进化调度服务实现
- * 
+ *
  * 调度机制:
  * 1. 定时调度:每日凌晨2:00自动检查所有租户是否满足进化条件
  * 2. 事件触发:当租户积累的事件数达到阈值时,可手动触发
@@ -62,7 +61,6 @@ public class EvolutionSchedulerImpl implements EvolutionScheduler {
      * 定时调度:每日凌晨2:00执行
      * 检查所有租户是否满足进化条件,满足则触发
      */
-    @Scheduled(cron = "0 0 2 * * ?")
     public void scheduledEvolution() {
         logger.info("[EvolutionScheduler] 定时进化调度开始");
         try {

+ 0 - 2
fs-service/src/main/java/com/fs/company/service/workflow/heartbeat/impl/HeartbeatSchedulerImpl.java

@@ -5,7 +5,6 @@ import com.fs.company.service.workflow.heartbeat.HeartbeatScheduler;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
@@ -147,7 +146,6 @@ public class HeartbeatSchedulerImpl implements HeartbeatScheduler {
     }
 
     @Override
-    @Scheduled(fixedDelay = 60000)
     public void checkAndExecute() {
         if (!tablesReady) {
             return;

+ 0 - 17
fs-service/src/main/java/com/fs/course/task/CourseStatisticsTask.java

@@ -1,17 +0,0 @@
-package com.fs.course.task;
-
-import com.fs.course.service.IFsUserCourseCompanyStatisticsService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component("courseStatisticsTask")
-public class CourseStatisticsTask {
-    @Autowired
-    private IFsUserCourseCompanyStatisticsService fsUserCourseCompanyStatisticsService;
-
-    public void saveCourseStatisticsTask(Integer status,Integer day) {
-        fsUserCourseCompanyStatisticsService.courseDailyStatisticsTask(status,day);
-
-    }
-
-}

+ 0 - 37
fs-service/src/main/java/com/fs/course/task/RedPacketLogsTask.java

@@ -1,37 +0,0 @@
-package com.fs.course.task;
-
-import com.fs.course.mapper.FsCourseRedPacketLogMapper;
-import com.fs.course.service.IFsCourseRedPacketLogService;
-import com.fs.course.service.impl.FsCourseRedPacketLogServiceImpl;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDateTime;
-
-/**
- * @description: 微信红包转账回调部分没有接收到,主动自己去查询
- * @author: Xgb
- * @createDate: 2025/10/15
- * @version: 1.0
- */
-@Component("redPacketLogsTask")
-public class RedPacketLogsTask {
-
-    @Autowired
-    private IFsCourseRedPacketLogService fsCourseRedPacketLogService;
-
-    /**
-     * @Description: 查询微信红包转账结果 每10分钟查询上一个10分钟区间的红包转账结果
-     * (定时调取失败 可以启动fs-qw-task 中的 CommonController queryRedPacketResult 手动调取) 仅给内部人员使用
-     * @Param:
-     * @Return:
-     * @Author xgb
-     * @Date 2025/10/15 16:32
-     */
-    public void queryRedPacketResult() {
-
-        // 查询RedPacketLog表,
-        fsCourseRedPacketLogService.queryRedPacketResult(null, null);
-    }
-
-}

+ 0 - 257
fs-service/src/main/java/com/fs/course/task/VideoTask.java

@@ -1,257 +0,0 @@
-package com.fs.course.task;
-
-import cn.hutool.json.JSONUtil;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.course.config.CourseConfig;
-import com.fs.course.domain.*;
-import com.fs.course.mapper.*;
-import com.fs.course.service.IFsCourseTrafficLogService;
-import com.fs.course.service.IFsUserVideoCommentService;
-import com.fs.his.domain.FsUser;
-import com.fs.his.mapper.FsUserMapper;
-import com.qcloud.cos.COSClient;
-import com.qcloud.cos.ClientConfig;
-import com.qcloud.cos.auth.BasicCOSCredentials;
-import com.qcloud.cos.auth.COSCredentials;
-import com.qcloud.cos.model.ObjectMetadata;
-import com.qcloud.cos.region.Region;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import java.time.LocalDate;
-import java.time.ZoneId;
-import java.util.*;
-
-@Component("videoTask")
-public class VideoTask {
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-    private static final String YL_SECRET_ID = "AKIDiMq9lDf2EOM9lIfqqfKo7FNgM5meD0sT";
-    private static final String YL_SECRET_KEY = "u5SuS80342xzx8FRBukza9lVNHKNMSaB";
-    private static final String LIKE_KEY_PREFIX = "like:video:";
-    private static final String UNLIKE_KEY_PREFIX = "unlike:video:";
-    private static final String FAVORITE_KEY_PREFIX = "favorite:video:";
-    private static final String NO_FAVORITE_KEY_PREFIX = "nofavorite:video:";
-    private static final String COMMENT_KEY_PREFIX = "comment:video:";
-    private static final String VIDEO_COMMENT_COUNT_KEY_PATTERN = "comment:count:video:*";
-    private static final String COMMENT_REPLY_COUNT_KEY_PATTERN = "reply:count:comment:*";
-    @Autowired
-    private FsUserVideoMapper videoMapper;
-    @Autowired
-    private FsUserVideoLikeMapper videoLikeMapper;
-    @Autowired
-    private FsUserVideoFavoriteMapper videoFavoriteMapper;
-    @Autowired
-    private FsUserVideoCommentMapper videoCommentMapper;
-    @Autowired
-    private IFsUserVideoCommentService videoCommentService;
-    @Autowired
-    private RedisCache redisCache;
-    @Autowired
-    private RedisTemplate<String, Object> redisTemplate;
-    @Autowired
-    private FsUserCourseVideoMapper courseVideoMapper;
-    @Autowired
-    private FsCourseRedPacketLogMapper redPacketLogMapper;
-
-    @Autowired
-    private IFsCourseTrafficLogService iFsCourseTrafficLogService;
-
-    public void autoNotShowVideo() {
-        List<Long> list = videoMapper.selectNotAuditVideo();
-        for (Long videoId : list){
-            FsUserVideo video = new FsUserVideo();
-            video.setVideoId(videoId);
-            video.setStatus(0);
-            video.setIsAudit(-1);
-            video.setAuditTime(new Date());
-            videoMapper.updateFsUserVideo(video);
-        }
-    }
-
-    //同步点赞到数据库
-    public void syncLikesToDatabase() {
-        Collection<String> keys = redisCache.keys(LIKE_KEY_PREFIX + "*:user:*");
-        if (keys != null && !keys.isEmpty()) {
-            for (String key : keys) {
-                String[] parts = key.split(":");
-                Long videoId = Long.parseLong(parts[2]);
-                long userId = Long.parseLong(parts[4]);
-                //判断是否存在数据库
-                int check = videoLikeMapper.checkLike(videoId, userId);
-                if (check==0){
-                    FsUserVideoLike map=new FsUserVideoLike();
-                    map.setVideoId(videoId);
-                    map.setUserId(userId);
-                    map.setCreateTime(new Date());
-                    videoLikeMapper.insertFsUserVideoLike(map);
-                }
-                //删除key
-                redisCache.deleteObject(key);
-            }
-        }
-    }
-
-    //同步取消点赞到数据库
-    public void syncUnlikesToDatabase() {
-        Collection<String> keys = redisCache.keys(UNLIKE_KEY_PREFIX + "*:user:*");
-        if (keys != null && !keys.isEmpty()) {
-            for (String key : keys) {
-                String[] parts = key.split(":");
-                Long videoId = Long.parseLong(parts[2]);
-                long userId = Long.parseLong(parts[4]);
-
-                // 从数据库中删除点赞记录
-                videoLikeMapper.deleteLike(videoId, userId);
-
-                // 从Redis中删除记录
-                redisCache.deleteObject(key);
-            }
-        }
-    }
-
-    //同步收藏到数据库
-    public void syncFavoritesToDatabase() {
-        Collection<String> keys = redisCache.keys(FAVORITE_KEY_PREFIX + "*:user:*");
-        if (keys != null && !keys.isEmpty()) {
-            for (String key : keys) {
-                String[] parts = key.split(":");
-                Long videoId = Long.parseLong(parts[2]);
-                long userId = Long.parseLong(parts[4]);
-                //判断是否存在数据库
-                int check = videoFavoriteMapper.checkFavorite(videoId, userId);
-                if (check==0){
-                    FsUserVideoFavorite map=new FsUserVideoFavorite();
-                    map.setVideoId(videoId);
-                    map.setUserId(userId);
-                    map.setCreateTime(new Date());
-                    videoFavoriteMapper.insertFsUserVideoFavorite(map);
-                }
-                //删除key
-                redisCache.deleteObject(key);
-            }
-        }
-    }
-
-    //同步取消收藏到数据库
-    public void syncUnFavoritesToDatabase() {
-        Collection<String> keys = redisCache.keys(NO_FAVORITE_KEY_PREFIX + "*:user:*");
-        if (keys != null && !keys.isEmpty()) {
-            for (String key : keys) {
-                String[] parts = key.split(":");
-                Long videoId = Long.parseLong(parts[2]);
-                long userId = Long.parseLong(parts[4]);
-
-                // 从数据库中删除点赞记录
-                videoFavoriteMapper.deleteFavorite(videoId, userId);
-
-                // 从Redis中删除记录
-                redisCache.deleteObject(key);
-            }
-        }
-    }
-
-    //同步评论数量
-    public void syncCommentCountToDatabase() {
-        Set<String> keys = redisTemplate.keys(VIDEO_COMMENT_COUNT_KEY_PATTERN);
-        if (keys != null) {
-            for (String key : keys) {
-                String videoIdStr = key.split(":")[3];
-                Long videoId = Long.parseLong(videoIdStr);
-                Integer commentCount = (Integer) redisTemplate.opsForValue().get(key);
-                if (commentCount != null) {
-                    videoMapper.updateCommentCount(videoId, commentCount);
-                    redisTemplate.delete(key);
-                }
-            }
-        }
-    }
-
-    //同步评论
-    public void syncCommentsToDatabase() {
-        videoCommentService.syncCommentsToDatabase();
-        videoCommentService.syncRepliesToDatabase();
-    }
-
-    @Autowired
-    private FsUserMapper fsUserMapper;
-
-    //会员到期任务
-    public void vipExpiration() {
-        List<FsUser> list = fsUserMapper.selectFsUserIsVip();
-        LocalDate today = LocalDate.now();
-
-        for (FsUser user : list) {
-            LocalDate vipEndDate = user.getVipEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-            if (vipEndDate.isBefore(today) || vipEndDate.isEqual(today)) {
-                FsUser userMap = new FsUser();
-                userMap.setUserId(user.getUserId());
-                userMap.setIsVip(0);
-                userMap.setVipStatus(2);
-                fsUserMapper.updateFsUser(userMap);
-                // 添加日志记录
-                logger.info("User ID: " + user.getUserId() + " VIP status updated.");
-            }
-        }
-    }
-
-    public boolean isSameYearMonthDay(LocalDate date1, LocalDate date2) {
-        return date1.isEqual(date2);
-    }
-
-    @Autowired
-    private FsCourseWatchLogMapper courseWatchLogMapper;
-
-    public void findWatchLogsExitAndWatching() {
-
-        List<FsCourseWatchLog> watchingLogs = courseWatchLogMapper.findWatchLogsExitAndWatching();
-        for (FsCourseWatchLog log : watchingLogs) {
-            FsCourseWatchLog log1 = new FsCourseWatchLog();
-            log1.setLogType(2);
-            log1.setLogId(log.getLogId());
-            courseWatchLogMapper.updateFsCourseWatchLog(log1);
-        }
-    }
-
-
-
-    public void getFileSize() {
-        List<FsUserCourseVideo> videos  = courseVideoMapper.selectVideoIsPrivate();
-        for (FsUserCourseVideo video : videos){
-            // 1 初始化用户身份信息(secretId, secretKey)
-            COSCredentials cred = new BasicCOSCredentials(YL_SECRET_ID, YL_SECRET_KEY);
-            // 2 设置bucket的区域,
-            ClientConfig clientConfig = new ClientConfig(new Region("ap-chongqing"));
-            // 3 生成cos客户端
-            COSClient cosclient = new COSClient(cred, clientConfig);
-
-            int index = video.getVideoUrl().indexOf("com/");
-            if (index != -1) {
-                String subString = video.getVideoUrl().substring(index + 4); // Adding 4 to skip "com/"
-                ObjectMetadata objectMetadata = cosclient.getObjectMetadata("hylj-1323137866", subString);
-                video.setFileSize(objectMetadata.getContentLength());
-                video.setFileKey(subString);
-                video.setLineOne("https://rttcpv.ylrzcloud.com/"+subString);
-                video.setLineTwo("https://rtctev.ylrzcloud.com/"+subString);
-                video.setVideoUrl("https://rttcpv.ylrzcloud.com/"+subString);
-                courseVideoMapper.updateFsUserCourseVideo(video);
-            }
-
-
-        }
-    }
-
-    /**
-     * 存储课程流量日志
-     * @throws Exception
-     */
-//    @Scheduled(fixedRate = 1000)
-    public void saveCourseTrafficLog() throws Exception
-    {
-        iFsCourseTrafficLogService.saveCourseTrafficLog();
-    }
-
-}

+ 0 - 2
fs-service/src/main/java/com/fs/erp/service/impl/JstTokenService.java

@@ -13,7 +13,6 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
@@ -168,7 +167,6 @@ public class JstTokenService {
      * 根据文档说明,刷新token必须在有效期小于15天时进行,所以这里设置20天刷新一次
      */
 //    @Scheduled(fixedRate = 20 * 24 * 60 * 60 * 1000)
-    @Scheduled(cron = "0 0 3 */28 * ?")
     public void scheduleTokenRefresh() {
         log.info("定时任务:刷新聚水潭API令牌");
         try {

+ 0 - 3
fs-service/src/main/java/com/fs/fastgptApi/util/EventLogUtils.java

@@ -10,7 +10,6 @@ import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
 import com.fs.qw.domain.QwUser;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
 import java.util.Date;
@@ -28,8 +27,6 @@ public class EventLogUtils {
     public void setFastGptChatMsgService(IFastGptChatMsgService service) {
         EventLogUtils.fastGptChatMsgService = service;
     }
-
-    @Scheduled(fixedDelay = 200)
     public void consumeLogs() {
         FastGptEventLog eventLog;
         while ((eventLog = EventLogQueue.pollEventLog()) != null) {

+ 24 - 27
fs-service/src/main/java/com/fs/framework/datasource/DynamicDataSource.java

@@ -1,27 +1,24 @@
-//package com.fs.framework.datasource;
-//
-//import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
-//
-//import javax.sql.DataSource;
-//import java.util.Map;
-//
-///**
-// * 动态数据源
-// *
-//
-// */
-//public class DynamicDataSource extends AbstractRoutingDataSource
-//{
-//    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
-//    {
-//        super.setDefaultTargetDataSource(defaultTargetDataSource);
-//        super.setTargetDataSources(targetDataSources);
-//        super.afterPropertiesSet();
-//    }
-//
-//    @Override
-//    protected Object determineCurrentLookupKey()
-//    {
-//        return DynamicDataSourceContextHolder.getDataSourceType();
-//    }
-//}
+package com.fs.framework.datasource;
+
+import java.util.Map;
+import javax.sql.DataSource;
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+
+/**
+ * 动态数据源
+ */
+public class DynamicDataSource extends AbstractRoutingDataSource
+{
+    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
+    {
+        super.setDefaultTargetDataSource(defaultTargetDataSource);
+        super.setTargetDataSources(targetDataSources);
+        super.afterPropertiesSet();
+    }
+
+    @Override
+    protected Object determineCurrentLookupKey()
+    {
+        return DynamicDataSourceContextHolder.getDataSourceType();
+    }
+}

+ 42 - 44
fs-service/src/main/java/com/fs/framework/datasource/DynamicDataSourceContextHolder.java

@@ -1,44 +1,42 @@
-//package com.fs.framework.datasource;
-//
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//
-///**
-// * 数据源切换处理
-// *
-//
-// */
-//public class DynamicDataSourceContextHolder {
-//    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
-//
-//    /**
-//     * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
-//     *  所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
-//     */
-//    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
-//
-//    /**
-//     * 设置数据源的变量
-//     */
-//    public static void setDataSourceType(String dsType)
-//    {
-////        log.info("切换到{}数据源", dsType);
-//        CONTEXT_HOLDER.set(dsType);
-//    }
-//
-//    /**
-//     * 获得数据源的变量
-//     */
-//    public static String getDataSourceType()
-//    {
-//        return CONTEXT_HOLDER.get();
-//    }
-//
-//    /**
-//     * 清空数据源变量
-//     */
-//    public static void clearDataSourceType()
-//    {
-//        CONTEXT_HOLDER.remove();
-//    }
-//}
+package com.fs.framework.datasource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 数据源切换处理
+ */
+public class DynamicDataSourceContextHolder
+{
+    public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
+
+    /**
+     * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
+     * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
+     */
+    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
+
+    /**
+     * 设置数据源的变量
+     */
+    public static void setDataSourceType(String dsType)
+    {
+        CONTEXT_HOLDER.set(dsType);
+    }
+
+    /**
+     * 获得数据源的变量
+     */
+    public static String getDataSourceType()
+    {
+        return CONTEXT_HOLDER.get();
+    }
+
+    /**
+     * 清空数据源变量
+     */
+    public static void clearDataSourceType()
+    {
+        CONTEXT_HOLDER.remove();
+    }
+}

+ 122 - 144
fs-service/src/main/java/com/fs/framework/datasource/TenantDataSourceManager.java

@@ -1,144 +1,122 @@
-//package com.fs.framework.datasource;
-//
-//import com.alibaba.druid.pool.DruidDataSource;
-//import com.fs.common.enums.DataSourceType;
-//import com.fs.framework.datasource.DynamicDataSourceContextHolder;
-//import com.fs.tenant.domain.TenantInfo;
-//import com.fs.tenant.service.TenantInfoService;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.stereotype.Component;
-//
-//import javax.annotation.Resource;
-//import javax.sql.DataSource;
-//import java.lang.reflect.Field;
-//import java.util.Map;
-//import java.util.concurrent.ConcurrentHashMap;
-//
-//@Component
-//public class TenantDataSourceManager {
-//
-//    private static final Logger log = LoggerFactory.getLogger(TenantDataSourceManager.class);
-//
-//    @Resource
-//    private DynamicDataSource dynamicDataSource;
-//
-//    @Resource
-//    private TenantInfoService tenantInfoService;
-//
-//    /**
-//     * 租户数据源缓存
-//     */
-//    private static final Map<String, DataSource> TENANT_DS_CACHE = new ConcurrentHashMap<>();
-//
-//    /**
-//     * 切换到租户数据源(不存在则创建)
-//     */
-//    public void switchTenant(TenantInfo tenantInfo) {
-//
-//        // 用租户主键作为唯一标识
-//        String tenantKey = buildTenantKey(tenantInfo.getId());
-//
-//        if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
-//            synchronized (this) {
-//                if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
-//
-//                    DataSource tenantDs = createTenantDataSource(tenantInfo);
-//                    TENANT_DS_CACHE.put(tenantKey, tenantDs);
-//
-//                    // 动态追加到已解析的数据源
-//                    Map<Object, DataSource> resolvedMap = getResolvedDataSources();
-//                    resolvedMap.put(tenantKey, tenantDs);
-//                }
-//            }
-//        }
-//
-//        // ThreadLocal 切库
-//        DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
-//    }
-//
-//    private String buildTenantKey(Long tenantId) {
-//        return "tenant:" + tenantId;
-//    }
-//
-//
-//
-//    /**
-//     * 清理 ThreadLocal
-//     */
-//    public void clear() {
-//        DynamicDataSourceContextHolder.clearDataSourceType();
-//    }
-//
-//    /**
-//     * 根据租户ID确保数据源已注册并切换(用于 Filter/拦截器等非登录场景)
-//     * 解决 JVM 重启后 TENANT_DS_CACHE 被清空,导致 resolvedDataSources 中找不到租户数据源的问题
-//     *
-//     * @param tenantId 租户ID
-//     */
-//    public void ensureSwitchByTenantId(Long tenantId) {
-//        String tenantKey = buildTenantKey(tenantId);
-//
-//        if (TENANT_DS_CACHE.containsKey(tenantKey)) {
-//            DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
-//            log.debug("[TenantDS] 数据源已缓存,直接切换: {}", tenantKey);
-//            return;
-//        }
-//
-//        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
-//        try {
-//            TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
-//            if (tenantInfo == null) {
-//                log.warn("[TenantDS] 租户ID={} 在主库中不存在,回退到主库", tenantId);
-//                DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
-//                return;
-//            }
-//            if (!tenantInfo.getStatus().equals(1)) {
-//                log.warn("[TenantDS] 租户ID={} 已禁用,回退到主库", tenantId);
-//                DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
-//                return;
-//            }
-//            switchTenant(tenantInfo);
-//            log.info("[TenantDS] 动态注册并切换数据源: key={}, url={}", tenantKey, tenantInfo.getDbUrl());
-//        } catch (Exception e) {
-//            log.error("[TenantDS] 动态注册租户数据源失败, tenantId={}, 回退到主库", tenantId, e);
-//            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
-//        }
-//    }
-//
-//    /**
-//     * 创建租户数据源(MySQL + Druid)
-//     */
-//    private DataSource createTenantDataSource(TenantInfo tenant) {
-//
-//        DruidDataSource ds = new DruidDataSource();
-//        ds.setUrl(tenant.getDbUrl());
-//        ds.setUsername(tenant.getDbAccount());
-//        ds.setPassword(tenant.getDbPwd());
-//
-//        // 统一 MySQL
-//        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
-//
-//        ds.setInitialSize(5);
-//        ds.setMinIdle(10);
-//        ds.setMaxActive(20);
-//        ds.setMaxWait(60000);
-//
-//        return ds;
-//    }
-//
-//    /**
-//     * 反射获取 AbstractRoutingDataSource.resolvedDataSources
-//     */
-//    @SuppressWarnings("unchecked")
-//    private Map<Object, DataSource> getResolvedDataSources() {
-//        try {
-//            Field field = org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
-//                    .class.getDeclaredField("resolvedDataSources");
-//            field.setAccessible(true);
-//            return (Map<Object, DataSource>) field.get(dynamicDataSource);
-//        } catch (Exception e) {
-//            throw new IllegalStateException("获取 resolvedDataSources 失败", e);
-//        }
-//    }
-//}
+package com.fs.framework.datasource;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.fs.common.enums.DataSourceType;
+import com.fs.tenant.domain.TenantInfo;
+import com.fs.tenant.service.TenantInfoService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+public class TenantDataSourceManager {
+
+    private static final Logger log = LoggerFactory.getLogger(TenantDataSourceManager.class);
+
+    @Resource
+    private DynamicDataSource dynamicDataSource;
+
+    @Resource
+    private TenantInfoService tenantInfoService;
+
+    /**
+     * 租户数据源缓存
+     */
+    private static final Map<String, DataSource> TENANT_DS_CACHE = new ConcurrentHashMap<>();
+
+    /**
+     * 切换到租户数据源(不存在则创建)
+     */
+    public void switchTenant(TenantInfo tenantInfo) {
+        String tenantKey = buildTenantKey(tenantInfo.getId());
+
+        if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
+            synchronized (this) {
+                if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
+                    DataSource tenantDs = createTenantDataSource(tenantInfo);
+                    TENANT_DS_CACHE.put(tenantKey, tenantDs);
+
+                    Map<Object, DataSource> resolvedMap = getResolvedDataSources();
+                    resolvedMap.put(tenantKey, tenantDs);
+                }
+            }
+        }
+
+        DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
+    }
+
+    private String buildTenantKey(Long tenantId) {
+        return "tenant:" + tenantId;
+    }
+
+    /**
+     * 清理 ThreadLocal
+     */
+    public void clear() {
+        DynamicDataSourceContextHolder.clearDataSourceType();
+    }
+
+    /**
+     * 根据租户ID确保数据源已注册并切换(用于 Filter/拦截器等非登录场景)
+     */
+    public void ensureSwitchByTenantId(Long tenantId) {
+        String tenantKey = buildTenantKey(tenantId);
+
+        if (TENANT_DS_CACHE.containsKey(tenantKey)) {
+            DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
+            log.debug("[TenantDS] 数据源已缓存,直接切换: {}", tenantKey);
+            return;
+        }
+
+        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+        try {
+            TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
+            if (tenantInfo == null) {
+                log.warn("[TenantDS] 租户ID={} 在主库中不存在,回退到主库", tenantId);
+                DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+                return;
+            }
+            if (!tenantInfo.getStatus().equals(1)) {
+                log.warn("[TenantDS] 租户ID={} 已禁用,回退到主库", tenantId);
+                DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+                return;
+            }
+            switchTenant(tenantInfo);
+            log.info("[TenantDS] 动态注册并切换数据源: key={}, url={}", tenantKey, tenantInfo.getDbUrl());
+        } catch (Exception e) {
+            log.error("[TenantDS] 动态注册租户数据源失败, tenantId={}, 回退到主库", tenantId, e);
+            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+        }
+    }
+
+    private DataSource createTenantDataSource(TenantInfo tenant) {
+        DruidDataSource ds = new DruidDataSource();
+        ds.setUrl(tenant.getDbUrl());
+        ds.setUsername(tenant.getDbAccount());
+        ds.setPassword(tenant.getDbPwd());
+        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
+        ds.setInitialSize(5);
+        ds.setMinIdle(10);
+        ds.setMaxActive(20);
+        ds.setMaxWait(60000);
+        return ds;
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<Object, DataSource> getResolvedDataSources() {
+        try {
+            Field field = org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
+                    .class.getDeclaredField("resolvedDataSources");
+            field.setAccessible(true);
+            return (Map<Object, DataSource>) field.get(dynamicDataSource);
+        } catch (Exception e) {
+            throw new IllegalStateException("获取 resolvedDataSources 失败", e);
+        }
+    }
+}

+ 0 - 127
fs-service/src/main/java/com/fs/his/task/BillTask.java

@@ -1,127 +0,0 @@
-//package com.fs.his.task;
-//
-//import com.alibaba.fastjson.JSON;
-//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-//import com.fs.common.utils.PubFun;
-//import com.fs.his.domain.FsStoreOrder;
-//import com.fs.his.domain.FsStoreOrderBillLog;
-//import com.fs.his.service.IFsStoreOrderBillLogService;
-//import com.fs.his.service.IFsStoreOrderService;
-//import com.fs.nuonuo.NuonuoUtils;
-//import com.fs.nuonuo.vo.InvoiceRedVo;
-//import com.fs.nuonuo.vo.InvoiceResultVo;
-//import lombok.AllArgsConstructor;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.scheduling.annotation.Scheduled;
-//import org.springframework.stereotype.Component;
-//import org.springframework.transaction.annotation.Transactional;
-//
-//import java.math.BigDecimal;
-//import java.time.LocalDateTime;
-//import java.util.List;
-//import java.util.Map;
-//import java.util.stream.Collectors;
-//
-//
-//@Component("billTask")
-//@AllArgsConstructor
-//public class BillTask {
-//    private static final Logger log = LoggerFactory.getLogger(BillTask.class);
-//
-//    private final IFsStoreOrderBillLogService fsStoreOrderBillLogService;
-//    private final IFsStoreOrderService fsStoreOrderService;
-//
-//    /**
-//     * 查询发票信息,同步数据
-//     */
-//    @Transactional
-//    public void bill(){
-//        log.debug("发票信息同步");
-//        List<FsStoreOrderBillLog> list = fsStoreOrderBillLogService.list(new QueryWrapper<FsStoreOrderBillLog>().in("status", 20).eq("upload_api", 1));
-//        if(list.isEmpty()) return;
-//        PubFun.batchProcessing(50, list, this::updateData);
-//
-//        log.debug("冲红信息同步");
-//        List<FsStoreOrderBillLog> list2 = fsStoreOrderBillLogService.list(new QueryWrapper<FsStoreOrderBillLog>().in("red_status", "01").isNull("bill_no"));
-//        if(list2.isEmpty()) return;
-//        PubFun.batchProcessing(50, list2, this::updateRedData);
-//    }
-//    @Transactional
-//    public void billUpload(){
-//        // 节假日判断
-////        LocalDateTime dateNow = LocalDateTime.now();
-////        LocalDateTime startDate = LocalDateTime.of(2025, 1, 26, 23, 0, 0);   // 0点
-////        LocalDateTime endDate = LocalDateTime.of(2025, 2, 1, 0, 0, 0);
-////        if((!dateNow.isBefore(startDate) && !dateNow.isAfter(endDate))) return;
-//        List<FsStoreOrderBillLog> list = fsStoreOrderBillLogService.list(new QueryWrapper<FsStoreOrderBillLog>().eq("upload_api", 0));
-//        if(list.isEmpty()) return;
-//        list.forEach(e -> NuonuoUtils.requestBilling(e.getOrderNo(), e.getPayerName(), e.getPayerTaxNo(), e.getOrderAmount(), e.getRemark()));
-//        list.forEach(e -> e.setUploadApi(1));
-//        fsStoreOrderBillLogService.updateBatchById(list);
-//    }
-//
-//    // 冲红信息同步
-//    public void updateRedData(List<FsStoreOrderBillLog> list){
-//        List<InvoiceResultVo> invoiceResultList = NuonuoUtils.queryInvoiceResult(PubFun.listToNewList(list, FsStoreOrderBillLog::getOrderNo));
-//        Map<String, InvoiceResultVo> invoiceResultMap = PubFun.listToMapByGroupObject(invoiceResultList, InvoiceResultVo::getOrderNo);
-//        list.stream().filter(e -> invoiceResultMap.containsKey(e.getOrderNo())).forEach(e -> e.setJson(JSON.toJSONString(invoiceResultMap.get(e.getOrderNo()))));
-//
-//        list.forEach(e -> {
-//            List<InvoiceRedVo> invoiceRedVoList = NuonuoUtils.queryInvoiceRedConfirm(e.getInvoiceNo());
-//            if(invoiceRedVoList.isEmpty()) return;
-//            InvoiceRedVo invoiceRedVo = invoiceRedVoList.get(0);
-//            e.setBillUuid(invoiceRedVo.getBillUuid());
-//            e.setBillNo(invoiceRedVo.getBillNo());
-//            e.setRedStatus(invoiceRedVo.getBillStatus());
-//        });
-//        fsStoreOrderBillLogService.updateBatchById(list);
-//        rollbackOrderBill(list);
-//    }
-//    // 开票信息同步
-//    public void updateData(List<FsStoreOrderBillLog> list){
-//        List<InvoiceResultVo> invoiceResultList = NuonuoUtils.queryInvoiceResult(PubFun.listToNewList(list, FsStoreOrderBillLog::getOrderNo));
-//        Map<String, InvoiceResultVo> invoiceResultMap = PubFun.listToMapByGroupObject(invoiceResultList, InvoiceResultVo::getOrderNo);
-//        list.stream().filter(e -> invoiceResultMap.containsKey(e.getOrderNo())).forEach(e -> {
-//            InvoiceResultVo vo = invoiceResultMap.get(e.getOrderNo());
-//            e.setSerialNo(vo.getSerialNo());
-//            e.setInvoiceCode(vo.getInvoiceCode());
-//            e.setInvoiceNo(vo.getInvoiceNo());
-//            e.setAllElectronicInvoiceNumbe(vo.getAllElectronicInvoiceNumbe());
-//            e.setInvoiceKind(vo.getInvoiceKind());
-//            e.setOrderAmount(BigDecimal.valueOf(Double.parseDouble(vo.getOrderAmount())));
-//            e.setPayerName(vo.getPayerName());
-//            e.setPayerTaxNo(vo.getPayerTaxNo());
-//            e.setAddress(vo.getAddress());
-//            e.setTelephone(vo.getTelephone());
-//            e.setPaperPdfUrl(vo.getPaperPdfUrl());
-//            e.setInvoiceTime(vo.getInvoiceTime());
-//            e.setPictureUrl(vo.getPictureUrl());
-//            e.setPdfUrl(vo.getPdfUrl());
-//            e.setFailCause(vo.getFailCause());
-//            e.setStatusMsg(vo.getStatusMsg());
-//            e.setStatus(Integer.parseInt(vo.getStatus()));
-//            e.setImgUrls(vo.getImgUrls());
-//            e.setRemark(vo.getRemark());
-//            e.setJson(JSON.toJSONString(vo));
-//        });
-//        fsStoreOrderBillLogService.updateBatchById(list);
-//        // 筛选开票异常列表
-//        rollbackOrderBill(list.stream().filter(e -> e.getStatus() != 2).collect(Collectors.toList()));
-//    }
-//    //退回订单开票金额
-//    public void rollbackOrderBill(List<FsStoreOrderBillLog> failedList){
-//        if(failedList.isEmpty()) return;
-//        Map<Long, List<FsStoreOrderBillLog>> logListMap = PubFun.listToMapByGroupList(failedList, FsStoreOrderBillLog::getOrderId);
-//        List<FsStoreOrder> orderList = fsStoreOrderService.selectFsStoreOrderByOrderIdIn(PubFun.listToNewList(failedList, FsStoreOrderBillLog::getOrderId));
-//        // 返还开票金额并且保存
-//        orderList.stream().filter(e -> logListMap.containsKey(e.getOrderId())).forEach(e -> {
-//            List<FsStoreOrderBillLog> logs = logListMap.get(e.getOrderId());
-//            BigDecimal total = logs.stream().map(FsStoreOrderBillLog::getOrderAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
-//            e.setBillPrice(e.getBillPrice().subtract(total));
-//            fsStoreOrderService.updateFsStoreOrder(e);
-//        });
-//    }
-//
-//
-//}

+ 0 - 135
fs-service/src/main/java/com/fs/his/task/CompanyBalanceTask.java

@@ -1,135 +0,0 @@
-//package com.fs.his.task;
-//
-//import com.fs.common.core.domain.R;
-//import com.fs.common.utils.DateUtils;
-//import com.fs.common.utils.StringUtils;
-//import com.fs.company.service.ICompanyService;
-//import com.fs.course.service.BalanceRollbackErrorService;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Component;
-//
-//import java.util.Date;
-//
-///**
-// * @description: 公司余额同步定时任务 (红包余额)
-// * @author: Xgb
-// * @createDate: 2025/10/22
-// * @version: 1.0
-// */
-//@Component("companyBalanceTask")
-//public class CompanyBalanceTask {
-//    private static final Logger log = LoggerFactory.getLogger(CompanyBalanceTask.class);
-//
-//
-//    @Autowired
-//    private BalanceRollbackErrorService balanceRollbackErrorService;
-//
-//    @Autowired
-//    private ICompanyService companyService;
-//
-//
-//    /**
-//     * @Description: 每10分钟从缓存获取余额同步到公司账户中
-//     * @Param:
-//     * @Return:
-//     * @Author xgb
-//     * @Date 2025/10/22 10:56
-//     */
-//    public void syncCompanyBalance() {
-//        companyService.syncCompanyBalance();
-//    }
-//
-//    /**
-//     * @Description: 定时回滚公司余额数据
-//     * @Param:
-//     * @Return:
-//     * @Author xgb
-//     * @Date 2025/10/22 11:48
-//     */
-//    public void processBatchRollbackByCompanyId() {
-//        balanceRollbackErrorService.processBatchRollbackByCompanyId();
-//    }
-//
-//    /**
-//     * @Description: spring启动执行 initCompanyBalance 查询余额报存到缓存中
-//     * 如果新增公司可以重启admin或者定时配置一下这个方法手动执行一次
-//     * @Param:
-//     * @Return:
-//     * @Author xgb
-//     * @Date 2025/10/22 11:52
-//     */
-//    public void initCompanyBalance() {
-//        balanceRollbackErrorService.initCompanyBalance();
-//    }
-//
-//    /**
-//     * @Description: 优化成回滚前查询记录,一笔一笔回滚
-//     * @Param: 每天0点执行一次
-//     * @Return:
-//     * @Author xgb
-//     * @Date 2025/11/7 9:48
-//     */
-//    public void rollbackRedPacketMoney(String time) throws Exception {
-//        // 默认是前两天时间
-//        String createSTime;
-//        String createETime;
-//        if (StringUtils.isNotBlank(time)) {
-//            Date date = DateUtils.parseDate(time);
-//            createSTime = time+" 00:00:00";
-//            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(date, 1))+" 00:00:00";
-//        } else {
-//            createSTime = DateUtils.parseDateToStr( DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -2))+" 00:00:00";
-//            createETime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD,DateUtils.addDays(new Date(), -1))+" 00:00:00";
-//        }
-//
-//        // 这个地方真加的是company money字段 xgb
-//        companyService.rollbackRedPacketMoney(createSTime, createETime);
-//    }
-//
-//    /**
-//     * @Description: 每天晚上0点定时获取获取公司余额,记录到数据库中
-//     * @Param:
-//     * @Return:
-//     * @Author xgb
-//     * @Date 2025/11/4 10:43
-//     */
-//    public void recordRedPacketBalance() {
-//        companyService.recordRedPacketBalance();
-//    }
-//
-//
-//
-//    /**
-//     * @Description: 更具批次号查询转账结果
-//     * @Param:
-//     * @Return:
-//     * @Author xgb
-//     * @Date 2025/12/25 10:31
-//     */
-//    public void checkMchTransferStatus(String outBatchNo,String companyIdStr) {
-//        Long companyId=Long.parseLong(companyIdStr);
-//        String result=companyService.checkMchTransferStatus(outBatchNo,companyId);
-//        log.info("查询商户转账结果:{}",result);
-//    }
-//
-//
-//
-//    /**
-//     * @Description: 更具批次号查询转账结果
-//     * @Param:
-//     * @Return:
-//     * @Author xgb
-//     * @Date 2025/12/25 10:31
-//     */
-//    public void checkMchTransferStatusByBatchID(String batchId,String companyIdStr) {
-//        Long companyId=Long.parseLong(companyIdStr);
-//        R result=companyService.checkMchTransferStatusByBatchID(batchId,companyId);
-//        log.info("查询商户转账结果:{}",result);
-//    }
-//
-//
-//
-//
-//}

+ 0 - 62
fs-service/src/main/java/com/fs/his/task/FsCourseTask.java

@@ -1,62 +0,0 @@
-//package com.fs.his.task;
-//
-//import com.fs.course.service.IFsCourseWatchLogService;
-//import com.fs.qw.service.ICustomerTransferApprovalService;
-//import com.fs.qw.service.IHyWorkTaskService;
-//import com.fs.statis.service.FsStatisSalerWatchService;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Service;
-//
-///**
-// * 后台统计相关 定时任务
-// */
-//@Service("fsCourseTask")
-//public class FsCourseTask {
-//    private static final Logger log = LoggerFactory.getLogger(FsCourseTask.class);
-//    @Autowired
-//    private IFsCourseWatchLogService fsCourseWatchLogService;
-//    @Autowired
-//    private IHyWorkTaskService hyWorkTaskService;
-//
-//    @Autowired
-//    private FsStatisSalerWatchService fsStatisSalerWatchService;
-//    @Autowired
-//    private ICustomerTransferApprovalService customerTransferApprovalService;
-//    /**
-//     * 添加会员观看日志
-//     * @throws Exception
-//     */
-//    public void addHyWatchLog() throws Exception
-//    {
-//        fsCourseWatchLogService.addCourseWatchLogDayNew();
-//    }
-//
-//    /**
-//     * 删除过期数据
-//     * @throws Exception
-//     */
-//    public void hyWorkTask4() throws Exception
-//    {
-//        // 更新已完课的催课看板
-//        hyWorkTaskService.delHyWorkTaskByOver();
-//    }
-//
-//    /**
-//     * 会员查看催课面板 获取看课中断和待看的先导课
-//     * @throws Exception
-//     */
-//    public void hyWorkTask(){
-//
-//        hyWorkTaskService.hyWorkTask();
-//    }
-//
-//    /**
-//     * 客户转移审批自动通过
-//     */
-//    public void fsUserTransferAutoPass(){
-//        customerTransferApprovalService.autoApprovePass();
-//    }
-//
-//}

+ 0 - 480
fs-service/src/main/java/com/fs/his/task/NetMedicalService.java

@@ -1,480 +0,0 @@
-package com.fs.his.task;
-
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.file.PathUtil;
-import cn.hutool.core.util.IdcardUtil;
-import cn.hutool.http.HttpRequest;
-import cn.hutool.http.HttpResponse;
-import cn.hutool.http.HttpUtil;
-import cn.hutool.json.JSONUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.fs.common.utils.file.ImageUtils;
-import com.fs.his.domain.FsInquiryOrderDTO;
-import com.fs.his.domain.FsPrescribeDrugDTO;
-import com.fs.his.dto.FsInquiryOrderPatientDTO;
-import com.fs.his.mapper.FsInquiryOrderMapper;
-import com.fs.his.mapper.FsPrescribeDrugMapper;
-import com.fs.his.param.FurtherConsultationParam;
-import com.fs.his.param.PrescriptionParam;
-import com.fs.his.service.IFsPrescribeService;
-import com.qiniu.util.Json;
-import lombok.AllArgsConstructor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-
-import java.text.SimpleDateFormat;
-import java.time.Instant;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.util.*;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-
-/**
- * 互联网医疗服务定时任务
- * 润天推送参考:每天从中午12点到下午17点,每个小时的整点执行一次
- */
-@Component("netMedicalService")
-@AllArgsConstructor
-public class NetMedicalService {
-    private static final Logger log = LoggerFactory.getLogger(NetMedicalService.class);
-
-    private final String prefix = "https://202.61.88.184:19200/";
-    private final String prescriptionPath = "wjw/upload/uploadRecipe";
-    private final String reconsultPath = "wjw/upload/uploadFurtherConsult";
-
-    private final IFsPrescribeService iFsPrescribeService;
-    private final FsPrescribeDrugMapper durgMapper;
-    private final FsInquiryOrderMapper inquiryOrderMapper;
-
-    public void uploadPrescription() {
-        log.info("互联网医疗服务定时任务启动,时间{}", LocalDateTime.now());
-
-        try {
-            // 1.抽取有生成电子处方and上传了首诊记录的数据
-            LocalDate today = LocalDate.now().minusDays(1);
-            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-            String date = today.format(formatter);
-
-            // 此任务准备在凌晨执行,上传前一天的电子处方。
-            List<Map<String, Object>> result = iFsPrescribeService.selectUploadDate("2025-09-21");//TODO:测试修改
-            log.info("查询到 {} 条待上传处方数据", result.size());
-
-            if (result.isEmpty()) {
-                log.info("没有需要上传的处方数据");
-                return;
-            }
-
-            List<PrescriptionParam> paramList = processPrescriptions(result);
-
-            uploadToRemoteService(paramList);
-
-        } catch (Exception e) {
-            log.error("上传处方任务执行失败", e);
-        }
-    }
-
-    /**
-     * 网络诊疗服务数据上传
-     * TODO:请求体太大,可能需要分批请求;
-     */
-    public void uploadReconsultDate() {
-        log.info("开始执行网络诊疗服务数据上传任务");
-
-        // 使用 DateTimeFormatter 替代 SimpleDateFormat
-        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-
-        LocalDate today = LocalDate.now().minusDays(1);
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        String date = today.format(formatter);
-
-        log.info("查询日期: {}", date);
-        List<FsInquiryOrderDTO> fsInquiryOrderDTOS = inquiryOrderMapper.selectNeedUploadData("2025-01-01");//TODO:测试修改
-        log.info("查询到需要上传的数据条数: {}", fsInquiryOrderDTOS.size());
-
-        ArrayList<FurtherConsultationParam> paramList = new ArrayList<>();
-        int successCount = 0;
-        int skipCount = 0;
-        int errorCount = 0;
-
-        for (int i = 0; i < fsInquiryOrderDTOS.size(); i++) {
-            FsInquiryOrderDTO fsInquiryOrder = fsInquiryOrderDTOS.get(i);
-            String orderSn = fsInquiryOrder.getOrderSn();
-
-            log.debug("正在处理第 {}/{} 条数据, 订单号: {}", i + 1, fsInquiryOrderDTOS.size(), orderSn);
-
-            try {
-                // 检查是否开具处方
-                int isPrescribe = iFsPrescribeService.selectPrescribeByinquiryOrderId(fsInquiryOrder.getOrderId());
-                log.debug("订单 {} 处方检查结果: {}", orderSn, isPrescribe > 0 ? "有处方" : "无处方");
-
-                String imageUrl = fsInquiryOrder.getReportImages();
-                if (imageUrl == null || imageUrl.trim().isEmpty()) {
-                    log.warn("订单 {} 报告图片URL为空,跳过处理", orderSn);
-                    skipCount++;
-                    continue;
-                }
-
-                log.debug("订单 {} 报告图片URL: {}", orderSn, imageUrl);
-
-                Integer supportedImageFormat = getSupportedImageFormat(imageUrl);
-                if (Objects.isNull(supportedImageFormat)) {
-                    log.warn("订单 {} 不支持的文件后缀,跳过处理,图片URL: {}", orderSn, imageUrl);
-                    skipCount++;
-                    continue;
-                }
-                log.debug("订单 {} 图片格式识别成功: {}", orderSn, supportedImageFormat);
-
-                byte[] image = ImageUtils.getImage(imageUrl);
-                if (image == null || image.length == 0) {
-                    log.warn("订单 {} 无法获取图片数据,图片URL: {}", orderSn, imageUrl);
-                    skipCount++;
-                    continue;
-                }
-                log.debug("订单 {} 成功获取图片数据,图片大小: {} bytes", orderSn, image.length);
-
-                String base64Image = Base64.getEncoder().encodeToString(image);
-                log.debug("订单 {} Base64编码完成,编码后长度: {}", orderSn, base64Image.length());
-
-                // 安全处理时间字段
-                String applyTime = formatDateTimeSafely(fsInquiryOrder.getCreateTime(), dateTimeFormatter);
-                String startTime = formatDateTimeSafely(fsInquiryOrder.getStartTime(), dateTimeFormatter);
-                String endTime = formatDateTimeSafely(fsInquiryOrder.getFinishTime(), dateTimeFormatter);
-                String uploadTime = LocalDateTime.now().format(dateTimeFormatter);//TODO:这个完成时间必须传,业务上判断是否需要未完结的复诊数据
-
-                if (applyTime == null || startTime == null || endTime == null) {
-                    log.warn("订单 {} 时间字段存在空值,跳过处理", orderSn);
-                    skipCount++;
-                    continue;
-                }
-
-                FurtherConsultationParam param = FurtherConsultationParam.builder()
-                        .thirdUniqueid(orderSn)
-                        .orgName(fsInquiryOrder.getHospitalName())
-                        .orgCode("组织结构代码")
-                        .channelName("平台名称")
-                        .section(fsInquiryOrder.getDeptName())
-                        .sectionCode(fsInquiryOrder.getDeptCode())
-                        .docName(fsInquiryOrder.getDoctorName())
-                        .certificateNum(fsInquiryOrder.getCertificateCode())
-                        .patientName(fsInquiryOrder.getPatientName())
-                        .patientAge(IdcardUtil.getAgeByIdCard(fsInquiryOrder.getIdCard()))
-                        .patientSex(fsInquiryOrder.getSex())
-                        .patientIdcardType(1)
-                        .patientIdcardNum(fsInquiryOrder.getIdCard())
-                        .furtherConsultNo(orderSn)
-                        .furtherConsulType(1)
-                        .medicalHistory(fsInquiryOrder.getSelfMedHistory())
-                        .furtherConsultApplyTime(applyTime)
-                        .furtherConsulStartTime(startTime)
-                        .furtherConsulEndTime(endTime)
-                        .furtherConsulIsReply(1)
-                        .feeType(1)
-                        .furtherConsultDiagnosis(fsInquiryOrder.getInquiryResult())
-                        .furtherConsultDiagnosisNo("复诊icd诊断编码")
-                        .furtherConsultPrice(fsInquiryOrder.getMoney().toBigInteger().doubleValue())
-                        .patientEvaluate(1)
-                        .complainInfo("")
-                        .disposeResult("")
-                        .isRiskWarn(1)
-                        .isPatientSign(1)
-                        .isPrescription(isPrescribe > 0 ? 1 : 0)
-                        .uploadTime(uploadTime)
-                        .consultDiagnosisType(supportedImageFormat)
-                        .consultOrg("首诊机构")
-                        .consultDiagnosis(base64Image)
-                        .cityId("")
-                        .isMark("1")
-                        .build();
-
-                paramList.add(param);
-                successCount++;
-                log.debug("订单 {} 参数构建完成,已添加到上传列表", orderSn);
-
-            } catch (Exception e) {
-                errorCount++;
-                log.error("处理订单 {} 时发生异常: {}", orderSn, e.getMessage(), e);
-            }
-        }
-
-        log.info("数据处理完成 - 成功: {}条, 跳过: {}条, 异常: {}条", successCount, skipCount, errorCount);
-
-        if (paramList.isEmpty()) {
-            log.info("没有需要上传的数据,任务结束");
-            return;
-        }
-
-        try {
-            String jsonParam = JSON.toJSONString(paramList);
-            log.info("准备上传数据,参数条数: {}", paramList.size());
-//            log.debug("请求参数JSON: {}", jsonParam);
-
-            String urlPath = prefix + reconsultPath;
-            log.info("请求URL: {}", urlPath);
-
-            HttpRequest post = HttpUtil.createPost(urlPath);
-            post.body(jsonParam, "application/json; charset=utf-8");
-
-            log.info("开始发送HTTP请求...");
-            long startTime = System.currentTimeMillis();
-            HttpResponse response = post.execute();
-            long endTime = System.currentTimeMillis();
-
-            log.info("HTTP请求完成,状态码: {}, 耗时: {}ms", response.getStatus(), endTime - startTime);
-
-            if (response.isOk()) {
-                String responseBody = response.body();
-                log.info("上传成功,响应内容: {}", responseBody);
-
-                // 可以在这里添加响应结果解析和业务逻辑判断
-                try {
-                    JSONObject responseJson = JSON.parseObject(responseBody);
-                    if (responseJson != null) {
-                        String code = responseJson.getString("status");
-                        String message = responseJson.getString("message");
-                        log.info("响应解析 - 状态码: {}, 消息: {}", code, message);
-                    }
-                } catch (Exception e) {
-                    log.warn("响应内容解析失败: {}", e.getMessage());
-                }
-            } else {
-                log.error("上传失败,状态码: {}, 响应内容: {}", response.getStatus(), response.body());
-            }
-
-        } catch (Exception e) {
-            log.error("数据上传过程中发生异常: {}", e.getMessage(), e);
-        }
-        log.info("网络诊疗服务数据上传任务执行完毕");
-    }
-
-    private List<PrescriptionParam> processPrescriptions(List<Map<String, Object>> prescriptions) {
-        List<PrescriptionParam> paramList = new ArrayList<>();
-
-        for (Map<String, Object> prescribe : prescriptions) {
-            try {
-                PrescriptionParam param = processSinglePrescription(prescribe);
-                if (param != null) {
-                    paramList.add(param);
-                }
-            } catch (Exception e) {
-                log.error("处理处方失败, prescribe_id: {}", prescribe.get("prescribe_id"), e);
-            }
-        }
-
-        log.info("成功处理 {} 个处方", paramList.size());
-        return paramList;
-    }
-
-    private PrescriptionParam processSinglePrescription(Map<String, Object> prescribe) {
-        Long prescribeId = Convert.toLong(prescribe.get("prescribe_id"));
-        if (prescribeId == null) {
-            log.warn("处方ID为空,跳过处理");
-            return null;
-        }
-
-        // 药品信息查询
-        List<FsPrescribeDrugDTO> drugs = durgMapper.selectDrugList(prescribeId);
-        if (drugs == null || drugs.isEmpty()) {
-            log.warn("处方 {} 没有药品信息,跳过处理", prescribeId);
-            return null;
-        }
-
-        // 计算总量
-        Double quantity = calculateTotalQuantity(drugs);
-        Double days = calculateTotalDays(drugs);
-
-        // 组装药品信息
-        Map<String, String> drugInfoMap = buildDrugInfoMap(drugs);
-
-        // 构建处方参数
-        return buildPrescriptionParam(prescribe, drugInfoMap, quantity, days);
-    }
-
-    private Double calculateTotalQuantity(List<FsPrescribeDrugDTO> drugs) {
-        return drugs.stream().map(FsPrescribeDrugDTO::getDrugNum).filter(Objects::nonNull).mapToDouble(Convert::toDouble).sum();
-    }
-
-    private Double calculateTotalDays(List<FsPrescribeDrugDTO> drugs) {
-        return drugs.stream().map(FsPrescribeDrugDTO::getUsageDays).filter(Objects::nonNull).mapToDouble(Convert::toDouble).sum();
-    }
-
-    private Map<String, String> buildDrugInfoMap(List<FsPrescribeDrugDTO> drugs) {
-        Map<String, String> resultMap = new HashMap<>();
-        resultMap.put("drugName", join(drugs, FsPrescribeDrugDTO::getDrugName));
-        resultMap.put("specification", join(drugs, FsPrescribeDrugDTO::getDrugSpec));
-        resultMap.put("frequency", join(drugs, FsPrescribeDrugDTO::getUsageFrequencyUnit));
-        resultMap.put("useMethod", join(drugs, FsPrescribeDrugDTO::getUsageMethod));
-        resultMap.put("usagePerUseUnit", join(drugs, FsPrescribeDrugDTO::getUsagePerUseUnit));
-        resultMap.put("drugCode", join(drugs, FsPrescribeDrugDTO::getBarCode));
-        resultMap.put("doseEachTime", join(drugs, FsPrescribeDrugDTO::getUsagePerUseCount)); // 修复类型
-        return resultMap;
-    }
-
-    private PrescriptionParam buildPrescriptionParam(Map<String, Object> prescribe, Map<String, String> drugInfoMap, Double quantity, Double days) {
-        return PrescriptionParam.builder()
-                .thirdUniqueid(getString(prescribe, "prescribe_code"))
-                .orgName(getString(prescribe, "hospital_name"))
-                .orgCode("机构编码") // TODO: 不晓得从哪取
-                .section(getString(prescribe, "dept_name"))
-                .sectionCode(getString(prescribe, "dept_code"))
-                .docName(getString(prescribe, "doctor_name"))
-                .docCertificateNum(getString(prescribe, "certificate_code"))
-                .pharmacistName(getString(prescribe, "doctor_drug_name"))
-                .pharmacistCertificateNum(getString(prescribe, "doctor_drug_code"))
-                .patientName(getString(prescribe, "patient_name"))
-                .patientSex(getString(prescribe, "patient_gender"))
-                .patientAge(getInteger(prescribe, "patient_age"))
-                .patientIdcardType(1)
-                .feeType(1)
-                .patientIdcardNum(getString(prescribe, "id_card"))
-                .recipeTime(getString(prescribe, "create_time"))
-                .reviewTime(getString(prescribe, "create_time"))
-                .recipeUnitPrice(getDouble(prescribe, "total_price"))
-                .drugName(drugInfoMap.get("drugName"))
-                .drugCode(drugInfoMap.get("drugCode"))
-                .drugCommonName(drugInfoMap.get("drugName"))
-                .specification(drugInfoMap.get("specification"))
-                .frequency(drugInfoMap.get("frequency"))
-                .usage(drugInfoMap.get("useMethod"))
-                .doseUnit(drugInfoMap.get("usagePerUseUnit"))
-                .doseEachTime(drugInfoMap.get("doseEachTime"))
-                .medicationDays(days)
-                .quantity(quantity)
-                .drugPackage("药品包装") // TODO: 不晓得去哪取
-                .recipeAllPrice(getDouble(prescribe, "total_price"))
-                .uploadTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
-                .recipeNo(getString(prescribe, "prescribe_code"))
-                .cityId("") // TODO: 没有对应字典
-                .build();
-    }
-
-    private void uploadToRemoteService(List<PrescriptionParam> paramList) {
-        if (paramList.isEmpty()) {
-            log.info("没有需要上传的数据");
-            return;
-        }
-
-        try {
-            String url = prefix + prescriptionPath;
-            log.info("开始上传 {} 个处方到: {}", paramList.size(), url);
-
-            HttpRequest post = HttpUtil.createPost(url);
-            String requestBody = JSON.toJSONString(paramList);
-            log.debug("上传数据: {}", requestBody);//很大一坨
-
-            post.body(requestBody);
-            HttpResponse response = post.execute();
-
-//            log.info("上传完成,响应状态: {}", response.getStatus());
-            log.info("响应内容: {}", JSON.toJSONString(response));
-
-        } catch (Exception e) {
-            log.error("上传处方数据到远程服务失败", e);
-            throw new RuntimeException("上传失败", e);
-        }
-    }
-
-    // 工具方法
-    private String getString(Map<String, Object> map, String key) {
-        Object value = map.get(key);
-        return value != null ? value.toString() : "";
-    }
-
-    private Integer getInteger(Map<String, Object> map, String key) {
-        try {
-            Object value = map.get(key);
-            return value != null ? Integer.valueOf(value.toString()) : 0;
-        } catch (NumberFormatException e) {
-            log.warn("字段 {} 转换整数失败, 使用默认值0", key);
-            return 0;
-        }
-    }
-
-    private Double getDouble(Map<String, Object> map, String key) {
-        try {
-            Object value = map.get(key);
-            return value != null ? Double.valueOf(value.toString()) : 0.0;
-        } catch (NumberFormatException e) {
-            log.warn("字段 {} 转换浮点数失败, 使用默认值0.0", key);
-            return 0.0;
-        }
-    }
-
-    private String join(List<FsPrescribeDrugDTO> drugs, Function<FsPrescribeDrugDTO, String> fieldExtractor) {
-        return drugs.stream().map(fieldExtractor).filter(Objects::nonNull).filter(str -> !str.trim().isEmpty()).collect(Collectors.joining("|"));
-    }
-
-    /**
-     * 获取图片格式(只支持jpg、png、bmp)
-     *
-     * @param imagePath 图片路径
-     * @return 图片格式(jpeg, png, bmp),如果不支持则返回null
-     */
-    public static Integer getSupportedImageFormat(String imagePath) {
-        if (imagePath == null || imagePath.trim().isEmpty()) {
-            return null;
-        }
-
-        // 处理URL参数
-        String cleanPath = imagePath.split("[?#]")[0];
-
-        // 获取扩展名
-        String extension = "";
-        int lastDotIndex = cleanPath.lastIndexOf('.');
-        if (lastDotIndex > 0 && lastDotIndex < cleanPath.length() - 1) {
-            extension = cleanPath.substring(lastDotIndex + 1).toLowerCase();
-        }
-
-        // 只支持三种格式
-        switch (extension) {
-            case "jpg":
-            case "jpeg":
-                return 2;
-            case "png":
-                return 3;
-            case "bmp":
-                return 4;
-            default:
-                return null; // 不支持的格式返回null
-        }
-    }
-
-    /**
-     * 安全格式化时间方法,处理各种时间类型
-     */
-    private String formatDateTimeSafely(Object dateTime, DateTimeFormatter formatter) {
-        if (dateTime == null) {
-            log.warn("时间字段为null");
-            return null;
-        }
-
-        try {
-            if (dateTime instanceof java.util.Date) {
-                // 转换 java.util.Date 到 LocalDateTime
-                Instant instant = ((java.util.Date) dateTime).toInstant();
-                return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).format(formatter);
-            } else if (dateTime instanceof java.sql.Timestamp) {
-                // 转换 java.sql.Timestamp 到 LocalDateTime
-                return ((java.sql.Timestamp) dateTime).toLocalDateTime().format(formatter);
-            } else if (dateTime instanceof LocalDateTime) {
-                // 直接格式化 LocalDateTime
-                return ((LocalDateTime) dateTime).format(formatter);
-            } else if (dateTime instanceof LocalDate) {
-                // 处理 LocalDate,添加时间部分
-                return ((LocalDate) dateTime).atStartOfDay().format(formatter);
-            } else {
-                log.warn("不支持的时间类型: {}", dateTime.getClass().getName());
-                return null;
-            }
-        } catch (Exception e) {
-            log.error("时间格式化失败: {}, 原始值: {}", e.getMessage(), dateTime);
-            return null;
-        }
-    }
-}

+ 0 - 29
fs-service/src/main/java/com/fs/his/task/PeriodTask.java

@@ -1,29 +0,0 @@
-//package com.fs.his.task;
-//
-//import com.fs.course.service.IFsUserCoursePeriodDaysService;
-//import com.fs.course.service.IFsUserCoursePeriodService;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Component;
-//
-//@Component("periodTask")
-//public class PeriodTask {
-//
-//    @Autowired
-//    private IFsUserCoursePeriodService userCoursePeriodService;
-//    @Autowired
-//    private IFsUserCoursePeriodDaysService userCoursePeriodDaysService;
-//
-//    /**
-//     * 更新营期状态
-//     */
-//    public void refreshPeriod() {
-//        userCoursePeriodService.changePeriodStatus();
-//    }
-//
-//    /**
-//     * 更新营期课程状态
-//     */
-//    public void refreshPeriodDays() {
-//        userCoursePeriodDaysService.changePeriodCourseStatus();
-//    }
-//}

+ 0 - 21
fs-service/src/main/java/com/fs/his/task/SendRedPacketTask.java

@@ -1,21 +0,0 @@
-//package com.fs.his.task;
-//
-//import com.fs.course.service.IFsCourseRedPacketLogService;
-//import com.fs.course.service.IFsUserCourseVideoRedPackageService;
-//import com.fs.course.service.IFsUserCourseVideoService;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Service;
-//
-//@Service("sendRedPacketTask")
-//public class SendRedPacketTask {
-//    private static final Logger log = LoggerFactory.getLogger(SendRedPacketTask.class);
-//    @Autowired
-//    private IFsCourseRedPacketLogService redPacketLogService;
-//
-//    public void sendRedPacket(){
-//        redPacketLogService.sendRedPacketBf();
-//    }
-//
-//}

+ 0 - 1902
fs-service/src/main/java/com/fs/his/task/Task.java

@@ -1,1902 +0,0 @@
-//package com.fs.his.task;
-//
-//import cn.hutool.core.collection.CollectionUtil;
-//import cn.hutool.core.date.DateTime;
-//import cn.hutool.json.JSONUtil;
-//import com.alibaba.fastjson.JSON;
-//import com.alibaba.fastjson.JSONObject;
-//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-//import com.fs.common.core.domain.R;
-//import com.fs.common.core.redis.RedisCache;
-//import com.fs.common.service.impl.SmsServiceImpl;
-//import com.fs.common.utils.DateUtils;
-//import com.fs.common.utils.SecurityUtils;
-//import com.fs.company.domain.CompanyMoneyLogs;
-//import com.fs.company.domain.CompanyUser;
-//import com.fs.company.domain.CompanyVoiceCaller;
-//import com.fs.company.mapper.*;
-//import com.fs.company.service.ICompanyService;
-//import com.fs.company.service.ICompanyUserService;
-//import com.fs.company.vo.QwIpadTotalVo;
-//import com.fs.company.vo.RedPacketMoneyVO;
-//import com.fs.course.dto.BatchSendCourseAllDTO;
-//import com.fs.course.mapper.FsCourseRedPacketLogMapper;
-//import com.fs.course.service.IFsCourseWatchLogService;
-//import com.fs.course.service.ITencentCloudCosService;
-//import com.fs.erp.domain.ErpDeliverys;
-//import com.fs.erp.domain.ErpOrderQuery;
-//import com.fs.erp.dto.ErpOrderQueryRequert;
-//import com.fs.erp.dto.ErpOrderQueryResponse;
-//import com.fs.erp.service.IErpOrderService;
-//import com.fs.fastGpt.domain.*;
-//import com.fs.fastGpt.mapper.FastGptChatSessionMapper;
-//import com.fs.fastGpt.mapper.FastgptChatVoiceHomoMapper;
-//import com.fs.fastGpt.service.AiHookService;
-//import com.fs.fastGpt.service.IFastgptEventLogTotalService;
-//import com.fs.framework.task.TenantTaskRunner;
-//import com.fs.fastgptApi.util.AudioUtils;
-//import com.fs.fastgptApi.vo.AudioVO;
-//import com.fs.his.config.FsSysConfig;
-//import com.fs.his.config.StoreConfig;
-//import com.fs.his.domain.*;
-//import com.fs.his.dto.FsInquiryOrderPatientDTO;
-//import com.fs.his.enums.FsStoreOrderLogEnum;
-//import com.fs.his.enums.FsStoreOrderStatusEnum;
-//import com.fs.his.mapper.*;
-//import com.fs.his.param.FsInquiryOrderFinishParam;
-//import com.fs.his.param.FsPackageOrderCancelParam;
-//import com.fs.his.service.*;
-//import com.fs.his.utils.ConfigUtil;
-//import com.fs.his.vo.FsSubOrderResultVO;
-//import com.fs.hisStore.domain.FsStoreOrderScrm;
-//import com.fs.hisStore.domain.FsStorePaymentScrm;
-//import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
-//import com.fs.hisStore.service.IFsStoreOrderScrmService;
-//import com.fs.hisStore.service.IFsStorePaymentScrmService;
-//import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
-//import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
-//import com.fs.huifuPay.service.HuiFuService;
-//import com.fs.im.dto.*;
-//import com.fs.im.service.IImService;
-//import com.fs.im.service.OpenIMService;
-//import com.fs.qw.domain.QwCompany;
-//import com.fs.qw.domain.QwUser;
-//import com.fs.qw.mapper.QwRestrictionPushRecordMapper;
-//import com.fs.qw.mapper.QwUserMapper;
-//import com.fs.qw.service.*;
-//import com.fs.sop.domain.QwSopTempVoice;
-//import com.fs.sop.service.IQwSopTempVoiceService;
-//import com.fs.system.domain.SysConfig;
-//import com.fs.system.mapper.SysConfigMapper;
-//import com.fs.system.service.ISysConfigService;
-//import com.fs.utils.OrderContextHolder;
-//import com.google.gson.Gson;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.apache.commons.lang3.StringUtils;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.beans.factory.annotation.Qualifier;
-//import org.springframework.beans.factory.annotation.Value;
-//import org.springframework.data.redis.core.RedisTemplate;
-//import org.springframework.scheduling.annotation.Scheduled;
-//import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-//import org.springframework.stereotype.Component;
-//
-//import java.text.ParseException;
-//import java.text.SimpleDateFormat;
-//import java.time.LocalDateTime;
-//import java.time.format.DateTimeFormatter;
-//import java.util.*;
-//import java.util.concurrent.CompletableFuture;
-//import java.util.function.Consumer;
-//import java.util.stream.Collectors;
-//
-//@Component("task")
-//public class Task {
-//    private static final Logger log = LoggerFactory.getLogger(Task.class);
-//    @Autowired
-//    private FsUserCouponMapper fsUserCouponMapper;
-//    @Autowired
-//    private SysConfigMapper sysConfigMapper;
-//    @Autowired
-//    private IFsPrescribeService fsPrescribeService;
-//    @Autowired
-//    IFsStoreOrderService fsStoreOrderService;
-//    @Autowired
-//    FsStoreOrderMapper fsStoreOrderMapper;
-//    @Autowired
-//    private RedisCache redisCache;
-//    @Autowired
-//    private FsPackageOrderMapper fsPackageOrderMapper;
-//    @Autowired
-//    private IFsFollowService fsFollowService;
-//    @Autowired
-//    private IFsStoreAfterSalesService fsStoreAfterSalesService;
-//    //    @Autowired
-////    IErpOrderService erpOrderService;
-//    @Autowired
-//    FsIntegralOrderMapper integralOrderMapper;
-//    @Autowired
-//    IFsInquiryOrderService iFsInquiryOrderService;
-//    @Autowired
-//    FsPackageMapper fsPackageMapper;
-//    @Autowired
-//    FsStoreProductMapper fsStoreProductMapper;
-//    @Autowired
-//    CompanyMapper companyMapper;
-//    @Autowired
-//    private CompanyMoneyLogsMapper moneyLogsMapper;
-//    @Autowired
-//    FsUserMapper fsUserMapper;
-//    @Autowired
-//    IFsUserIntegralLogsService fsUserIntegralLogsService;
-//    @Autowired
-//    SmsServiceImpl smsService;
-//    @Autowired
-//    FsStoreOrderItemMapper fsStoreOrderItemMapper;
-//
-//    @Autowired
-//    FsPatientMapper fsPatientMapper;
-//    @Autowired
-//    FsPrescribeDrugMapper fsPrescribeDrugMapper;
-//    @Autowired
-//    FsFollowMapper fsFollowMapper;
-//    @Autowired
-//    private IImService imService;
-//    @Autowired
-//    private FsInquiryOrderMapper inquiryOrderMapper;
-//    @Autowired
-//    private CompanyVoiceCallerMapper companyVoiceCallerMapper;
-//    @Autowired
-//    private CompanyVoiceLogsMapper companyVoiceLogsMapper;
-//    @Autowired
-//    IFsPackageOrderService packageOrderService;
-//    @Autowired
-//    private IFsStoreOrderLogsService fsStoreOrderLogsService;
-//    org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
-//    @Autowired
-//    IFsDoctorService doctorService;
-//    @Autowired
-//    CompanyUserMapper companyUserMapper;
-//    @Autowired
-//    FsInquiryOrderMapper fsInquiryOrderMapper;
-//    @Autowired
-//    FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
-//    //每天执行一次
-//    @Autowired
-//    IQwAppContactWayService qwAppContactWayService;
-//
-//    @Autowired
-//    FastGptChatSessionMapper fastGptChatSessionMapper;
-//
-//    @Autowired
-//    IQwExternalContactTransferLogService qwExternalContactTransferLogService;
-//
-//    @Autowired
-//    private IFsCourseWatchLogService fsCourseWatchLogService;
-//
-//    @Autowired
-//    ITencentCloudCosService tencentCloudCosService;
-//    @Autowired
-//    private ConfigUtil configUtil;
-//    @Autowired
-//    private IQwCompanyService qwCompanyService;
-//    @Autowired
-//    private IQwUserService qwUserService;
-//    @Autowired
-//    private OpenIMService openIMService;
-//    @Autowired
-//    public RedisTemplate redisTemplate;
-//
-//    @Autowired
-//    private ICompanyUserService userService;
-//
-//    @Autowired
-//    private IFastgptEventLogTotalService fastgptEventLogTotalService;
-//
-//    @Autowired
-//    private FastgptChatVoiceHomoMapper fastgptChatVoiceHomoMapper;
-//    @Autowired
-//    private IQwSopTempVoiceService qwSopTempVoiceService;
-//
-//    @Autowired
-//    private QwRestrictionPushRecordMapper qwRestrictionPushRecordMapper;
-//    @Autowired
-//    private FsUserOperationLogMapper fsUserOperationLogMapper;
-//
-//    @Autowired(required = false)
-//    private TenantTaskRunner tenantTaskRunner;
-//
-//    /** SaaS 模式:为 true 时定时任务按租户执行 */
-//    @Value("${saas.task.enabled:true}")
-//    private boolean saasTaskEnabled;
-//
-//    public static final String SOP_TEMP_VOICE_KEY = "sop:tempVoice";
-//    @Autowired
-//    private IFsStorePaymentService fsStorePaymentService;
-//
-//    @Autowired
-//    private IFsStoreOrderService orderService;
-//    @Autowired
-//    private ISysConfigService sysConfigService;
-//
-//    @Autowired
-//    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
-//    @Autowired
-//    private FsIntegralOrderMapper fsIntegralOrderMapper;
-//
-//    private final String DELAY_MSG = "delayMsg";
-//
-//    @Autowired
-//    private QwUserMapper qwUserMapper;
-//
-//    @Autowired
-//    private AiHookService aiHookService;
-//
-//    @Autowired
-//    private IFsStorePaymentScrmService paymentScrmService;
-//
-//    @Autowired
-//    private IFsStoreOrderScrmService orderScrmService;
-//    /**
-//     * 定时任务,处理ai禁止回复之后的消息
-//     */
-//    /*public void forbidTimeMsgTask() {
-//        Map<String, Object> cacheMap = redisCache.hGetAll(DELAY_MSG);
-//        for (String key : cacheMap.keySet()) {
-//            String value = (String) cacheMap.get(key);
-//            //获取sessionId
-//            Long sessionId = Long.parseLong(key);
-//            try {
-//                Thread.sleep(800);
-//            } catch (Exception e) {
-//                log.error("定时消息处理异常,会话id:{},文本:{}",sessionId,value,e);
-//            }
-//            try {
-//                if (value != null && !value.isEmpty()) {
-//                    FastGptChatSession chatSession = fastGptChatSessionMapper.selectFastGptChatSessionBySessionId(sessionId);
-//                    Long qwUserId = chatSession.getQwUserId();
-//                    QwUser qwUser = qwUserMapper.selectQwUserById(qwUserId);
-//                    String uid = qwUser.getUid();
-//
-//                    JSONObject jsonObject = JSONObject.parseObject(value);
-//                    String content = jsonObject.getString("content");
-//                    Long sender = jsonObject.getLong("sender");
-//                    Integer type = jsonObject.getInteger("type");
-//
-//                    aiHookService.qwHookNotifyAiReply(qwUserId,sender,content,uid,type,tendId);
-//                    //删除已经处理的缓存
-//                    redisCache.hDel(DELAY_MSG,key);
-//                }
-//            } catch (Exception e) {
-//                log.error("个人定时消息处理异常,会话id:{},文本:{}",sessionId,value,e);
-//            }
-//        }
-//    }*/
-//
-//    /**
-//     * sop任务token消耗统计
-//     */
-//    public void sopPushTokenTotal() {
-//        // 判断是否是凌晨 00:00 - 00:59
-//        boolean isEarlyMorning = isEarlyMorning();
-//
-//        // 获取日期字符串(今天或昨天)
-//        String dateTime;
-//        if (isEarlyMorning) {
-//            dateTime = DateUtils.addDateDays(-1); // 昨天
-//        } else {
-//            dateTime = DateUtils.getDate(); // 今天
-//        }
-//        log.info("开始执行sop任务token消耗统计");
-//        try {
-//            List<FastGptPushTokenTotal> fastGptPushTotalList = qwRestrictionPushRecordMapper.selectFastgptPushTokenTotal(dateTime);
-//            if (fastGptPushTotalList != null && !fastGptPushTotalList.isEmpty()) {
-//                for (FastGptPushTokenTotal fastGptPushTotal : fastGptPushTotalList) {
-//                    // 获取统计数据
-//                    Integer type = fastGptPushTotal.getType();
-//                    Long count = 0L;
-//                    if(type == 7){
-//                        count = fastGptPushTotal.getCount() * 450;
-//                    }else{
-//                        count = fastGptPushTotal.getCount() * 150;
-//                    }
-//                    fastGptPushTotal.setCount(count);
-//                    FastGptPushTokenTotal pushTotal = qwRestrictionPushRecordMapper.selectFastGptPushTokenTotalByInfo(fastGptPushTotal);
-//                    if(pushTotal == null){
-//                        qwRestrictionPushRecordMapper.insertPushTokenTotal(fastGptPushTotal);
-//                    }else{
-//                        fastGptPushTotal.setId(pushTotal.getId());
-//                        qwRestrictionPushRecordMapper.updatePushTokenTotal(fastGptPushTotal);
-//                    }
-//                }
-//            }
-//            log.info("结束执行sop任务token消耗统计");
-//        } catch (Exception e) {
-//            log.error("执行sop任务token消耗统计异常", e);
-//        }
-//    }
-//
-//    /**
-//     * 一键生成语音定时任务
-//     */
-//    public void ConsumerSopTempVoice() {
-//        try {
-//            Long newCompanyUserId = redisCache.popVoiceKey(SOP_TEMP_VOICE_KEY);
-//            if (newCompanyUserId != null) {
-//                List<QwSopTempVoice> sopTempVoices = redisCache.getVoiceAllList(SOP_TEMP_VOICE_KEY + ":" + newCompanyUserId);
-//                if (sopTempVoices != null && !sopTempVoices.isEmpty()) {
-//                    try {
-//                        for (QwSopTempVoice qwSopTempVoice : sopTempVoices) {
-//                            try {
-//                                AudioVO audioVO = new AudioVO();
-//                                List<FastgptChatVoiceHomo> homos = fastgptChatVoiceHomoMapper.selectFastgptChatVoiceHomoList(new FastgptChatVoiceHomo());
-//                                audioVO = AudioUtils.createUserUrlAndUrl(homos, qwSopTempVoice.getCompanyUserId(), qwSopTempVoice.getVoiceTxt());
-//                                if (audioVO != null && audioVO.getWavUrl() != null && audioVO.getUrl() != null) {
-//                                    qwSopTempVoice.setVoiceUrl(audioVO.getUrl());
-//                                    qwSopTempVoice.setUserVoiceUrl(audioVO.getWavUrl());
-//                                    qwSopTempVoice.setDuration(audioVO.getDuration());
-//                                    qwSopTempVoice.setRecordType(1);
-//                                    qwSopTempVoiceService.updateQwSopTempVoice(qwSopTempVoice);
-//                                }
-//                            } catch (Exception e) {
-//
-//                            }
-//                        }
-//                    } finally {
-//                        redisCache.deleteObject(SOP_TEMP_VOICE_KEY + ":" + newCompanyUserId);
-//                    }
-//                }
-//            } else {
-//                log.info("没有需要生成的语音");
-//            }
-//        } catch (Exception e) {
-//            log.error("生成语音定时任务执行异常", e);
-//        }
-//    }
-//
-//    //统计ai事件埋点
-//    public void eventLogTotals() {
-//        // 判断是否是凌晨 00:00 - 00:59
-//        boolean isEarlyMorning = isEarlyMorning();
-//
-//        // 获取日期字符串(今天或昨天)
-//        String dateTime;
-//        Date date;
-//        if (isEarlyMorning) {
-//            dateTime = DateUtils.addDateDays(-1); // 昨天
-//            date = DateUtils.addDays(new Date(), -1); // 昨天的 Date 对象
-//        } else {
-//            dateTime = DateUtils.getDate(); // 今天
-//            date = new Date(); // 今天的 Date 对象
-//        }
-//        //更新埋点
-//        processEventLogTotals(date, dateTime);
-//        //更新token消耗
-//        processTokenLogs(date, dateTime);
-//    }
-//
-//    private void processEventLogTotals(Date date, String dateTime) {
-//        FastgptEventLogTotal logTotal = new FastgptEventLogTotal();
-//        logTotal.setCreateTime(date);
-//        List<FastgptEventLogTotal> totalList = fastgptEventLogTotalService.selectFastgptEventLogTotalInfoList(logTotal);
-//
-//        // 分别收集需要更新和插入的记录
-//        List<FastgptEventLogTotal> toUpdateList = new ArrayList<>();
-//        List<FastgptEventLogTotal> toInsertList = new ArrayList<>();
-//
-//        // 用于防止重复添加相同记录的集合
-//        Set<String> processedKeys = new HashSet<>();
-//
-//        for (FastgptEventLogTotal total : totalList) {
-//            try {
-//                if (total == null) {
-//                    continue;
-//                }
-//
-//                if (total.getType() == 1) {
-//                    total.setCount(total.getSenderCount());
-//                }
-//                // 构造唯一标识符,用于防止重复处理
-//                String uniqueKey = String.format("%d_%d_%d_%d_%d_%s",
-//                        total.getRoleId() != null ? total.getRoleId() : 0,
-//                        total.getType() != null ? total.getType() : 0,
-//                        total.getCompanyId() != null ? total.getCompanyId() : 0,
-//                        total.getCompanyUserId() != null ? total.getCompanyUserId() : 0,
-//                        total.getQwUserId() != null ? total.getQwUserId() : 0,
-//                        dateTime
-//                );
-//                // 检查是否已经处理过这个记录
-//                if (processedKeys.contains(uniqueKey)) {
-//                    continue;
-//                }
-//
-//                FastgptEventLogTotal info = fastgptEventLogTotalService.selectFastgptEventLogTotalByRoleIdAndType(total);
-//                if (info != null) {
-//                    Long newCount = total.getCount() != null ? total.getCount() : 0L;
-//                    // 只有当count值发生变化时才加入更新列表
-//                    if (!newCount.equals(info.getCount())) {
-//                        FastgptEventLogTotal eventLogTotal = new FastgptEventLogTotal();
-//                        eventLogTotal.setId(info.getId());
-//                        eventLogTotal.setCount(newCount);
-//                        if (!processedKeys.contains(uniqueKey)) {
-//                            toUpdateList.add(eventLogTotal);
-//                            // 标记为已处理
-//                            processedKeys.add(uniqueKey);
-//                        }
-//                    }
-//                } else {
-//                    total.setStatTime(dateTime);
-//                    if (!processedKeys.contains(uniqueKey)) {
-//                        toInsertList.add(total);
-//                        // 标记为已处理
-//                        processedKeys.add(uniqueKey);
-//                    }
-//                }
-//            } catch (Exception e) {
-//                log.error("统计AI事件触发情况异常,数据:" + total, e);
-//            }
-//        }
-//
-//        // 批量处理更新和插入操作
-//        processBatchUpdates(toUpdateList);
-//        processBatchInserts(toInsertList);
-//    }
-//
-//    private void processBatchUpdates(List<FastgptEventLogTotal> toUpdateList) {
-//        // 使用批量更新方法替代逐条更新,提高处理速度
-//        int batchSize = 100;
-//        for (int i = 0; i < toUpdateList.size(); i += batchSize) {
-//            int endIndex = Math.min(i + batchSize, toUpdateList.size());
-//            List<FastgptEventLogTotal> batch = toUpdateList.subList(i, endIndex);
-//            try {
-//                fastgptEventLogTotalService.updateFastgptEventLogTotalBatch(batch);
-//            } catch (Exception e) {
-//                // 如果批量更新失败,则逐条更新
-//                log.warn("批量更新AI事件统计信息失败,将逐条更新", e);
-//                for (FastgptEventLogTotal item : batch) {
-//                    try {
-//                        fastgptEventLogTotalService.updateFastgptEventLogTotal(item);
-//                    } catch (Exception ex) {
-//                        log.error("更新AI事件统计信息失败,数据:" + item, ex);
-//                    }
-//                }
-//            }
-//        }
-//    }
-//
-//    private void processBatchInserts(List<FastgptEventLogTotal> toInsertList) {
-//        // 使用批量插入方法替代逐条插入,提高处理速度
-//        int batchSize = 100;
-//        for (int i = 0; i < toInsertList.size(); i += batchSize) {
-//            int endIndex = Math.min(i + batchSize, toInsertList.size());
-//            List<FastgptEventLogTotal> batch = toInsertList.subList(i, endIndex);
-//            try {
-//                fastgptEventLogTotalService.insertFastgptEventLogTotalBatch(batch);
-//            } catch (Exception e) {
-//                // 如果批量插入失败,则逐条插入
-//                log.warn("批量插入AI事件统计信息失败,将逐条插入", e);
-//                for (FastgptEventLogTotal item : batch) {
-//                    try {
-//                        fastgptEventLogTotalService.insertFastgptEventLogTotal(item);
-//                    } catch (Exception ex) {
-//                        log.error("插入AI事件统计信息失败,数据:" + item, ex);
-//                    }
-//                }
-//            }
-//        }
-//    }
-//
-//    private void processTokenLogs(Date date, String dateTime) {
-//        FastGptEventTokenLog fastGptEventTokenLog = new FastGptEventTokenLog();
-//        fastGptEventTokenLog.setCreateTime(date);
-//        List<FastGptEventTokenLog> tokenLogs = fastgptEventLogTotalService.selectFastgptEventTokenLogTotalList(fastGptEventTokenLog);
-//
-//        // 分别收集需要更新和插入的记录
-//        List<FastgptEventLogTotal> toUpdateList = new ArrayList<>();
-//        List<FastgptEventLogTotal> toInsertList = new ArrayList<>();
-//        Random random = new Random();
-//
-//        // 用于防止重复添加相同记录的集合
-//        Set<String> processedKeys = new HashSet<>();
-//
-//        for (FastGptEventTokenLog tokenLog : tokenLogs) {
-//            try {
-//                if (tokenLog == null) {
-//                    continue;
-//                }
-//
-//                // 构造唯一标识符,用于防止重复处理
-//                String uniqueKey = String.format("%d_11_%d_%d_%d_%s",
-//                        tokenLog.getRoleId() != null ? tokenLog.getRoleId() : 0,
-//                        tokenLog.getCompanyId() != null ? tokenLog.getCompanyId() : 0,
-//                        tokenLog.getCompanyUserId() != null ? tokenLog.getCompanyUserId() : 0,
-//                        tokenLog.getQwUserId() != null ? tokenLog.getQwUserId() : 0,
-//                        dateTime
-//                );
-//
-//                // 检查是否已经处理过这个记录
-//                if (processedKeys.contains(uniqueKey)) {
-//                    continue;
-//                }
-//
-//                FastgptEventLogTotal info = fastgptEventLogTotalService.selectFastgptEventTokenLogTotalByRoleIdAndType(tokenLog);
-//                Long tokenCount = tokenLog.getTokenCount() != null ? tokenLog.getTokenCount() : 0L;
-//                Long totalCount = (tokenCount * 8) + random.nextInt(21) - 10;
-//
-//                if (info != null) {
-//                    // 只有当count值发生变化时才加入更新列表
-//                    if (!totalCount.equals(info.getCount())) {
-//                        FastgptEventLogTotal eventLogTotalNew = new FastgptEventLogTotal();
-//                        eventLogTotalNew.setId(info.getId());
-//                        eventLogTotalNew.setCount(totalCount);
-//                        if (!processedKeys.contains(uniqueKey)) {
-//                            toUpdateList.add(eventLogTotalNew);
-//                            // 标记为已处理
-//                            processedKeys.add(uniqueKey);
-//                        }
-//
-//                    }
-//                } else {
-//                    FastgptEventLogTotal eventLogTotal = new FastgptEventLogTotal();
-//                    eventLogTotal.setRoleId(tokenLog.getRoleId());
-//                    eventLogTotal.setCount(totalCount);
-//                    eventLogTotal.setType(11);
-//                    eventLogTotal.setCompanyId(tokenLog.getCompanyId());
-//                    eventLogTotal.setCompanyUserId(tokenLog.getCompanyUserId());
-//                    eventLogTotal.setQwUserId(tokenLog.getQwUserId());
-//                    eventLogTotal.setStatTime(dateTime);
-//
-//                    if (!processedKeys.contains(uniqueKey)) {
-//                        toInsertList.add(eventLogTotal);
-//                        // 标记为已处理
-//                        processedKeys.add(uniqueKey);
-//                    }
-//                }
-//            } catch (Exception e) {
-//                log.error("统计AI消耗token触发情况异常,数据:" + tokenLog, e);
-//            }
-//        }
-//
-//        // 批量处理更新和插入操作
-//        processBatchUpdates(toUpdateList);
-//        processBatchInserts(toInsertList);
-//    }
-//
-//    private boolean isEarlyMorning() {
-//        Date now = new Date();
-//        java.time.LocalDateTime localDateTime = now.toInstant()
-//                .atZone(java.time.ZoneId.systemDefault())
-//                .toLocalDateTime();
-//        return localDateTime.getHour() == 0;
-//    }
-//
-//
-//    //定时查询ipad主机使用情况,建议每天凌晨1点执行一次
-//    public void totalIpadTask() {
-//        String dateTime = DateUtils.addDateDays(-1); // 昨天
-//        List<QwIpadTotalVo> qwIpadTotalVos = userService.selectCompanyByIpadStatusCount();
-//        if (qwIpadTotalVos != null && !qwIpadTotalVos.isEmpty()) {
-//            qwIpadTotalVos.forEach(qwIpadTotalVo ->
-//                    qwIpadTotalVo.setStatTime(dateTime)
-//            );
-//            int a = userService.insertQwIpadTotal(qwIpadTotalVos);
-//            if (a == 0) {
-//                log.error("插入ipad主机失败");
-//            }
-//        } else {
-//            log.error("查询没有数据");
-//        }
-//    }
-//
-//    public void payment(){
-//        List<FsStorePayment> fsStorePayments = fsStorePaymentService.selectAllPayment();
-//        for (FsStorePayment fsStorePayment : fsStorePayments) {
-//            try{
-//                fsStorePaymentService.updateFsStorePaymentByDecryptForm(fsStorePayment.getPaymentId());
-//            }catch (Exception e){
-//                logger.error("同步支付失败:"+fsStorePayment.getPaymentId());
-//            }
-//
-//        }
-//
-//    }
-//
-//    public void paymentScrm() {
-//
-//        List<FsStorePaymentScrm> fsStorePaymentScrms = paymentScrmService.selectFsStorePaymentByAll();
-//        fsStorePaymentScrms.forEach(payment -> {
-//            try {
-//                String payMode = payment.getPayMode();
-//                logger.info("手动查询"+payment);
-//                if (payMode.equals("hf")){
-//                    V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
-//                    request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-//                    request.setOrgHfSeqId(payment.getTradeNo());
-//                    request.setAppId(payment.getAppId());
-//                    HuiFuQueryOrderResult o = null;
-//                    try {
-//                        o = huiFuService.queryOrder(request);
-//                    } catch (Exception e) {
-//                        throw new RuntimeException(e);
-//                    }
-//                    logger.info("汇付返回"+o);
-//                    if ("00000000".equals(o.getResp_code())) {
-//                        if (o.getTrans_stat().equals("S")) {
-//                            String[] order=o.getOrg_req_seq_id().split("-");
-//                            switch (order[0]) {
-//                                case "store":
-//                                    orderScrmService.payConfirm(1,null,order[1], o.getOrg_hf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
-//                                    break;
-//                                case "store_remain":
-//                                    orderScrmService.payRemainConfirm( order[1], o.getOrg_hf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
-//                                    break;
-//                                case "payment":
-//                                    fsStorePaymentService.payConfirm(order[1],o.getOrg_hf_seq_id(),o.getOut_trans_id(),o.getParty_order_id());
-//                                    break;
-//                            }
-//                        }
-//                    }
-//                }
-//            }catch (Exception e){
-//                logger.error("当前订单同步失败-"+payment+":"+e.getMessage());
-//            }
-//
-//        });
-//
-//
-//    }
-//
-//
-//    public void addQwUserName() {
-//        QwCompany qwCompany = new QwCompany();
-//        List<QwCompany> companyList = qwCompanyService.selectQwCompanyList(qwCompany);
-//        for (QwCompany company : companyList) {
-//            qwUserService.syncQwUserName(company.getCorpId());
-//        }
-//    }
-//
-//    public void videoTranscode() throws Exception {
-//
-//        tencentCloudCosService.videoTranscode();
-//    }
-//
-//    public void updateUrl() throws Exception {
-//
-//        tencentCloudCosService.updateUrl();
-//    }
-//
-//    public void addPrescribeImg() throws Exception {
-//        List<Long> ids = fsPrescribeService.selectFsPrescribeByPrescribeIdByOrderType();
-//        for (Long id : ids) {
-//            System.out.println(id);
-//            fsPrescribeService.PrescribeStoreImg(id);
-//        }
-//    }
-//
-//    public void addQwWatchLog() throws Exception {
-//        LocalDateTime now = LocalDateTime.now().withSecond(0);
-//        fsCourseWatchLogService.addCourseWatchLogDay();
-//    }
-//
-//
-//    public void addQwWatchLogMinute(Integer minute) throws Exception{
-//        log.info("定时更新看课111");
-//        if(minute == null) minute = 30;
-//        LocalDateTime now = LocalDateTime.now().withSecond(0);
-//        LocalDateTime start = now.minusMinutes(minute);
-//        LocalDateTime end = now.minusSeconds(1);
-//        fsCourseWatchLogService.addCourseWatchLogDayMinute(start, end);
-//    }
-//
-//    public void transferLog() throws Exception {
-//        qwExternalContactTransferLogService.updateQwExternalContactTransferLogByStatus();
-//
-//
-//    }
-//
-//    public void isArtificial() throws Exception {
-//        fastGptChatSessionMapper.updateFastGptChatSessionByIsReply();
-//
-//    }
-//
-//    public void expirationQwAppCountWay() {
-//        qwAppContactWayService.expirationQwAppCountWay();
-//
-//    }
-//
-//    public void sendOrderMsg() throws Exception {
-//        List<FsStoreOrder> fsStoreOrders = fsStoreOrderMapper.selectStoreOrderIdByFollow();
-//        for (FsStoreOrder fsStoreOrder : fsStoreOrders) {
-//
-//            fsStoreOrderService.addOrderEatMsg(fsStoreOrder);
-//        }
-//
-//    }
-//
-//    public void redPacketSubMoney() throws Exception {
-//        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
-//        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-//            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
-//        }
-//    }
-//
-//
-//    public void redPacketAddMoney() throws Exception {
-//        // 这个地方真加的是company money字段 xgb 红包余额独立后这个方法弃用
-//        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
-//        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-//            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
-//        }
-//    }
-//
-//    public void updateCompanyUserStatus() {
-//        CompanyUser user = new CompanyUser();
-//        user.setStatus("0");
-//        user.setDelFlag("0");
-//        List<CompanyUser> companyUsers = companyUserMapper.selectCompanyUserList(user);
-//        for (CompanyUser companyUser : companyUsers) {
-//            if (SecurityUtils.matchesPassword("123456", companyUser.getPassword())) {
-//                companyUser.setStatus("1");
-//                companyUserMapper.updateCompanyUser(companyUser);
-//                logger.info("密码为123456 停用账号:" + companyUser.getUserId() + ":" + companyUser.getNickName());
-//            }
-//        }
-//    }
-//
-//    public void couponStatus() {
-//        fsUserCouponMapper.updateFsUserCouponStatusByLimtTime();
-//    }
-//
-//    //每10秒执行一次
-//    public void auditPrescribe() {
-//        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.inquiryConfig");
-//        String configValue = sysConfig.getConfigValue();
-//        Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
-//        boolean isAudit = (boolean) config.get("isAutoPrescribeAudit");
-//        if (isAudit) {
-//            fsPrescribeService.auditPrescribe();
-//        }
-//    }
-//
-//    public void deliveryOp() {
-//        IErpOrderService erpOrderService = getErpService();
-//        List<FsStoreOrder> orders = null;
-//        if (erpOrderService == gyOrderService) {
-//            orders = fsStoreOrderMapper.selectOmsOrderdeliveryOp();
-//        } else if (erpOrderService == wdtOrderService || erpOrderService == dfOrderService || erpOrderService == jSTOrderService) {
-//            orders = fsStoreOrderMapper.selectWdtOmsOrderdeliveryOp();
-//        }
-//        for(FsStoreOrder order:orders){
-//            ErpOrderQueryRequert request=new ErpOrderQueryRequert();
-//            request.setCode(order.getExtendOrderId());
-//            if (erpOrderService != null) {
-//                ErpOrderQueryResponse response = erpOrderService.getOrder(request);
-//                if (erpOrderService != dfOrderService) {
-//                    if (response.getOrders() != null && response.getOrders().size() > 0) {
-//                        for (ErpOrderQuery orderQuery : response.getOrders()) {
-//                            if (orderQuery.getDeliverys() != null && orderQuery.getDeliverys().size() > 0) {
-//                                for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-//                                    if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-//                                        //更新商订单状态 删除REDIS
-//                                        fsStoreOrderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(), delivery.getExpress_code(), delivery.getExpress_name());
-//                                        redisCache.deleteObject("delivery" + ":" + order.getExtendOrderId());
-//                                    }
-//                                }
-//                            }
-//                        }
-//                    }
-//                }
-//            }
-//        }
-//    }
-//
-//    @Autowired
-//    private FsIntegralOrderDfMapper integralOrderDfMapper;
-//
-//
-//    /**
-//     * 创建了erp的订单,但是等待回调修改物流状态的定时任务
-//     * */
-//    public void deliveryIntegralOp() {
-//        IErpOrderService erpOrderService = getErpService();
-//        //查询没有物流字段但是创建过的,如果有则把待发货状态改成待收货
-//        List<FsIntegralOrderDf> integralDf = integralOrderDfMapper.selectByIsPush();
-//        if (integralDf.isEmpty()) {
-//            log.info("⏹️ 没有需要推送的订单明细,流程结束");
-//            return;
-//        }
-//        log.info("📊 查询到 {} 条未查询的订单明细", integralDf.size());
-//        //只判断类型,给个对象
-//        OrderContextHolder.setIntegralOrder(new FsIntegralOrder());
-//        for (FsIntegralOrderDf df : integralDf) {
-//            log.info("🔄 开始处理订单明细,订单号: {}, orderId: {}", df.getOrderCode(), df.getOrderId());
-//            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-//            request.setCode(df.getOrderCode());
-//            erpOrderService.getOrder(request);
-//        }
-//        OrderContextHolder.clear();
-//    }
-//    /**
-//     * 对待收货的订单,定时去更新物流状态
-//     * */
-//    public void getIntegralOrderDeliveryStatus() {
-//        /*erp物流流程:
-//        1.请求顺丰接口添加物流订单
-//        2.修改df推送标识为1
-//        3.查询订单结果更新order,或者回滚df表*/
-//        //目的是查询创建成功erp的订单,应该在第三部之后改动的数据来作为查询条件;即为待收货订单and拥有deliverySn的数据;
-//        List<FsIntegralOrder> orders = fsIntegralOrderMapper.selectList(Wrappers.<FsIntegralOrder>lambdaQuery().eq(FsIntegralOrder::getStatus, 2).isNotNull(FsIntegralOrder::getDeliverySn));
-//        IErpOrderService erpOrderService = getErpService();
-//        List<CompletableFuture<Void>> futures = new ArrayList<>();
-//        for (FsIntegralOrder order : orders) {
-//            // 创建局部final变量副本
-//            final FsIntegralOrder currentOrder = order;
-//            FsStoreOrder order1 = new FsStoreOrder();
-//            order1.setDeliverySn(currentOrder.getDeliverySn());
-//            order1.setOrderCode(currentOrder.getOrderCode());
-//
-//            // 异步执行,使用局部变量副本
-//            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
-//                OrderContextHolder.setIntegralOrder(currentOrder);
-//                try {
-//                    erpOrderService.getOrderDeliveryStatus(order1);
-//                } finally {
-//                    OrderContextHolder.clear();
-//                }
-//            });
-//            futures.add(future);
-//        }
-//        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
-//    }
-//
-//    public void deliveryOpScrm()
-//    {
-//        IErpOrderService erpOrderService = getErpService();
-//        List<FsStoreOrderScrm> orders = null;
-//        if (erpOrderService == gyOrderService){
-//            orders = fsStoreOrderMapper.selectOmsOrderdeliveryOpScrm();
-//        } else if (erpOrderService == wdtOrderService || erpOrderService == dfOrderService || erpOrderService == jSTOrderService){
-//            orders = fsStoreOrderMapper.selectWdtOmsOrderdeliveryOpScrm();
-//        }
-//        for(FsStoreOrderScrm order:orders){
-//            ErpOrderQueryRequert request=new ErpOrderQueryRequert();
-//            request.setCode(order.getExtendOrderId());
-//            if (erpOrderService != null){
-//                ErpOrderQueryResponse response=erpOrderService.getScrmOrder(request);
-//                if (erpOrderService != dfOrderService){
-//                    if(response.getOrders()!=null&&response.getOrders().size()>0){
-//                        for(ErpOrderQuery orderQuery : response.getOrders()){
-//                            if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
-//                                for(ErpDeliverys delivery:orderQuery.getDeliverys()){
-//                                    if(delivery.getDelivery()&& StringUtils.isNotEmpty(delivery.getMail_no())){
-//                                        //更新商订单状态 删除REDIS
-//                                        fsStoreOrderService.deliveryOrderScrm(order.getOrderCode(),delivery.getMail_no(),delivery.getExpress_code(),delivery.getExpress_name());
-//                                        redisCache.deleteObject("delivery"+":"+order.getExtendOrderId());
-//                                    }
-//                                }
-//                            }
-//                        }
-//                    }
-//                }
-//            }
-//        }
-//
-//
-//    }
-//
-//
-//    public void getOrderDeliveryStatus()
-//    {
-//        IErpOrderService erpOrderService = getErpService();
-//        List<FsStoreOrder> orders = null;
-//        if (erpOrderService != null && erpOrderService == dfOrderService) {
-//            orders = fsStoreOrderMapper.selectShippedOrder();
-//            if (orders != null && !orders.isEmpty()) {
-//                List<CompletableFuture<Void>> futures = new ArrayList<>();
-//                for (FsStoreOrder order : orders) {
-//                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
-//                        erpOrderService.getOrderDeliveryStatus(order);
-//                    });
-//                    futures.add(future);
-//                }
-//                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
-//            }
-//        }
-//    }
-//
-//    public void CreateOmsAndHis() {
-//        List<Long> omsList = fsStoreOrderMapper.selectFsStoreOrderNoCreateOms();
-//        logger.info("推送订单id====>{}", omsList);
-//        for (Long l : omsList) {
-//            try {
-//                fsStoreOrderService.createOmsOrder(l);
-//            } catch (Exception e) {
-//                logger.error("推送订单异常:", e);
-//            }
-//        }
-////        List<Long> tuiOrderList = fsStoreOrderMapper.selectFsStoreOrderNoTuiOrder();
-////        for (Long l : tuiOrderList) {
-////            try {
-////                fsStoreOrderService.tuiOrder(l);
-////            } catch (Exception e) {
-////            }
-////
-////        }
-//    }
-//
-//    public void createFollow() {
-//        List<FsStoreOrder> orders = fsStoreOrderMapper.selectStoreOrderIdByFollow();
-//        for (FsStoreOrder order : orders) {
-//            try {
-//
-//                fsStoreOrderService.addFsFollowByStoreOrder(order);
-//            } catch (Exception e) {
-//                logger.info("创建随访错误:" + order);
-//            }
-//        }
-//    }
-//
-//    @Autowired
-//    IFsStoreSubOrderService fsStoreSubOrderService;
-//
-//
-//    public void puSubStoreOrder() {
-//        List<Long> longs = fsStoreSubOrderService.selectFsStoreSubOrderByNoPush();
-//        int i = 0;
-//        for (Long aLong : longs) {
-//            FsSubOrderResultVO fsSubOrderResultVO = fsStoreSubOrderService.TuiFsStoreSubOrderByStoreOrder(aLong);
-//            if (fsSubOrderResultVO != null && fsSubOrderResultVO.getCode() != null && fsSubOrderResultVO.getCode() == 1) {
-//                i++;
-//                if (i > 65) {
-//                    return;
-//                }
-//            }
-//
-//        }
-//    }
-//
-//    /**
-//     * 推送河山医院
-//     */
-//    public void puSubStoreOrderHsyy() {
-//        // 获取时间并格式化为字符串
-//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-//
-//        String todayStartStr = LocalDateTime.now()
-//                .withHour(0)
-//                .withMinute(0)
-//                .withSecond(0)
-//                .withNano(0)
-//                .format(formatter);
-//
-//        String yesterdayStartStr = LocalDateTime.now()
-//                .minusDays(1)
-//                .withHour(0)
-//                .withMinute(0)
-//                .withSecond(0)
-//                .withNano(0)
-//                .format(formatter);
-//
-//        List<FsStoreSubOrder> list = fsStoreSubOrderService.selectFsStoreSubOrderListByCreateTime(yesterdayStartStr, todayStartStr);
-//        log.info("------>>>>>>"+todayStartStr+"推送" + yesterdayStartStr+"的子订单数据共:" + list.size() + "条");
-//        if(CollectionUtil.isNotEmpty(list)){
-//            fsStoreSubOrderService.pushHsyy(list);
-//        }
-//    }
-//
-//    public void refundOp() {
-//        List<FsStoreAfterSales> list = fsStoreAfterSalesService.selectFsStoreAfterSalesByDoAudit();
-//        if (list != null) {
-//            for (FsStoreAfterSales afterSales : list) {
-//                try {
-//                    fsStoreAfterSalesService.auditing(afterSales);
-//                } catch (Exception e) {
-//
-//                }
-//
-//            }
-//        }
-//
-//    }
-//
-//    public void isAfterSales() {
-//        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
-//        String configValue = sysConfig.getConfigValue();
-//        Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
-//        Integer storeAfterSalesDay = (Integer) config.get("storeAfterSalesDay");
-//        List<FsStoreOrder> fsStoreOrders = fsStoreOrderMapper.selectFsStoreOrderNoIsAfterSales(storeAfterSalesDay);
-//        for (FsStoreOrder fsStoreOrder : fsStoreOrders) {
-//            try {
-//                fsStoreOrderService.addIntegralAndShareByStoreOrder(fsStoreOrder);
-//            } catch (Exception e) {
-//                logger.info("分账错误: " + fsStoreOrder.getOrderCode());
-//            }
-//        }
-//
-//    }
-//
-//
-//    public void integralOrderStatus() {
-//        integralOrderMapper.updatePackageOrderStatusByDeliveryTime();
-//    }
-//
-//    public void packageStatus() {
-//        fsPackageOrderMapper.updatePackageOrderStatusByFinishTime();
-//        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
-//        String configValue = sysConfig.getConfigValue();
-//        Map<String, Object> config = (Map<String, Object>) JSON.parse(configValue);
-//        Integer unPayTime = (Integer) config.get("unPayTime");
-//        fsPackageOrderMapper.updatePackageOrderStatusByStatus(unPayTime);
-//    }
-//
-//    public void endFollow() {
-//        fsStoreOrderService.endFollow();
-//    }
-//
-//
-//    public void erDelivery() {
-//        fsStoreOrderService.endDeliveryOrder();
-//    }
-//
-//
-//
-//    @Autowired
-//    private ICompanyService companyService;
-//
-//    public void addCompanyMoney() {
-//        List<FsStoreOrder> orders = fsStoreOrderMapper.selectOrderIds();
-//        for (FsStoreOrder order : orders) {
-//            CompanyMoneyLogs moneyLog1 = moneyLogsMapper.selectCompanyMoneyLogsByOrderId(order.getOrderId(), 5);
-//            CompanyMoneyLogs moneyLog2 = moneyLogsMapper.selectCompanyMoneyLogsByOrderId(order.getOrderId(), 3);
-//            if (moneyLog1 == null) {
-//                companyService.subtractCompanyMoney(order);
-//            }
-//            if (moneyLog2 == null) {
-//                companyService.addCompanyMoney(order);
-//                FsStoreOrder orderMap = new FsStoreOrder();
-//                orderMap.setOrderId(order.getOrderId());
-//                orderMap.setTuiMoneyTime(new Date());
-//                fsStoreOrderMapper.updateFsStoreOrder(orderMap);
-//            }
-//        }
-//    }
-//
-//    //每天执行一次
-//    public void syncExpress() {
-//        List<Long> ids = fsStoreOrderMapper.selectSyncExpressIds();
-//        for (Long id : ids) {
-//            fsStoreOrderService.syncExpress(id);
-//        }
-//
-//    }
-//
-//    public void refundCompanyMoney() {
-//        List<FsStoreOrder> list = fsStoreOrderMapper.selectOrders();
-//        for (FsStoreOrder order : list) {
-//            companyService.refundCompanyMoney(order);
-//        }
-//    }
-//
-//    public void subIntegral() {
-//        fsUserIntegralLogsService.subFsUserIntegralLogsByOrder5();
-//    }
-//
-//    public void finishInquiry() {
-//        List<FsInquiryOrder> orders = inquiryOrderMapper.selectFsInquiryOrderByFinish();
-//        for (FsInquiryOrder order : orders) {
-//            // 订单已超过48小时,执行关闭操作
-//            FsInquiryOrderFinishParam param = new FsInquiryOrderFinishParam();
-//            param.setOrderId(order.getOrderId());
-//            param.setDoctorId(order.getDoctorId());
-//            try {
-//                iFsInquiryOrderService.autoFinishOrder(param);
-//            } catch (Exception e) {
-//                logger.info("订单已超过48小时关闭异常" + param);
-//            }
-//
-//        }
-//    }
-//
-//
-//    public void finishStoreOrderByXN() {
-//        List<FsStoreOrder> orders = fsStoreOrderMapper.selectFinishStoreOrderByXN();
-//        if (orders != null && orders.size() > 0) {
-//            for (FsStoreOrder o : orders) {
-//                FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderByOrderId(o.getOrderId());
-//                if (order.getStatus() != 2) {
-//                    continue;
-//                }
-//                FsStoreOrder o1 = new FsStoreOrder();
-//                o1.setUpdateTime(new DateTime());
-//                o1.setFinishTime(new Date());
-//                o1.setOrderId(o.getOrderId());
-//                o1.setStatus(FsStoreOrderStatusEnum.STATUS_4.getValue());
-//                int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
-//                fsStoreOrderLogsService.create(order.getOrderId(), FsStoreOrderLogEnum.FINISH_ORDER.getValue(),
-//                        FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
-//                if (order.getCompanyId() != null && order.getTuiMoneyStatus() == 0 && order.getPayType() == 1) {
-//                    companyService.addCompanyMoney(order);
-//                }
-//            }
-//        }
-//    }
-//
-//    public void inquirySendSms() {
-//        List<FsInquiryOrder> orders = inquiryOrderMapper.selectFsInquiryOrderBySendSms();
-//        for (FsInquiryOrder order : orders) {
-//            FsInquiryOrderPatientDTO patientDTO = JSON.parseObject(order.getPatientJson(), FsInquiryOrderPatientDTO.class);
-//            if (patientDTO != null && patientDTO.getPatientName() != null) {
-//                FsUser fsUser = fsUserMapper.selectFsUserByUserId(order.getUserId());
-//                if (fsUser != null && fsUser.getPhone() != null) {
-//                    smsService.sendUserSms(fsUser.getPhone(), patientDTO.getPatientName(), "2");
-//                    order.setIsSendSms(1);
-//                    inquiryOrderMapper.updateFsInquiryOrder(order);
-//                }
-//
-//            }
-//        }
-//    }
-//
-//    //处理30天问题件
-//    public void clearProblemOrder() {
-//        List<FsStoreOrder> orders = fsStoreOrderMapper.selectFsStoreOrderByProblemOrder();
-//        for (FsStoreOrder order : orders) {
-//            FsStoreOrder map = new FsStoreOrder();
-//            map.setStatus(4);
-//            map.setOrderId(order.getOrderId());
-//            fsStoreOrderMapper.updateFsStoreOrder(map);
-//        }
-//
-//    }
-//
-//
-//    //30天无通话记录回收坐席
-//    public void recoverCompanyCaller() {
-//        SysConfig sysConfig = sysConfigMapper.selectConfigByConfigKey("his.store");
-//        StoreConfig fsPayConfig = new Gson().fromJson(sysConfig.getConfigValue(), StoreConfig.class);
-//        Integer days = fsPayConfig.getStoreCall();
-//        List<CompanyVoiceCaller> list = companyVoiceCallerMapper.selectCompanyVoiceCallerByRecover(days);
-//        for (CompanyVoiceCaller caller : list) {
-//            Long count = companyVoiceLogsMapper.selectCompanyVoiceLogsCountByCallerNo(caller.getCallerNo(), caller.getBindTime());
-//            if (count == 0) {
-//                caller.setCompanyId(0l);
-//                caller.setCompanyUserId(0l);
-//                caller.setMobile("");
-//                caller.setStatus(1);
-//                caller.setBindTime(null);
-//                companyVoiceCallerMapper.updateCompanyVoiceCaller(caller);
-//            }
-//        }
-//    }
-//
-//
-//    public void tb() {
-//        packageOrderService.payConfirm("", "1780763211956486144", "1075999515888117190", "14", 1, null, null);
-//    }
-//
-//
-//    public void addSend() {
-//        String userId = "4048905872";
-//        String doctorId = "147";
-//        String storeOrderId = "470920";
-//        String followId = "1062986";
-//        //发送给用户
-//        MsgDTO msgDTO = new MsgDTO();
-//        MsgCustomDTO customDTO = new MsgCustomDTO();
-//        customDTO.setType("startDrugReport");
-//        customDTO.setImType(2);
-//        customDTO.setOrderId(storeOrderId);
-//        customDTO.setFollowId(followId);
-//        msgDTO.setCloudCustomData(JSONUtil.toJsonStr(customDTO));
-//        msgDTO.setFrom_Account("U-" + userId);
-//        msgDTO.setTo_Account("D-" + doctorId);
-//        List<MsgDataDTO> msgs = new ArrayList<>();
-//        MsgDataDTO msg = new MsgDataDTO();
-//        msg.setMsgType("TIMTextElem");
-//        msg.setMsgContent(new MsgDataFormatDTO("您好"));
-//        msgs.add(msg);
-//        msgDTO.setMsgBody(msgs);
-//        MsgResponseDTO msgResponseDTO = imService.sendMsg(msgDTO);
-//        System.out.println(msgResponseDTO);
-//    }
-//
-//    @Autowired
-//    FsStorePaymentScrmMapper fsStorePaymentScrmMapper;
-//
-//    @Autowired
-//    HuiFuService huiFuService;
-//
-//    /**
-//     * 查询同步商城订单的支付转台
-//     */
-//    public void syncOrderPayStatus(){
-//        //查询支付状态是待支付的数据
-//        FsStorePaymentScrm paymentScrm = new FsStorePaymentScrm();
-//        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
-//        paymentScrm.setStatus(0);
-//        List<FsStorePaymentScrm> fsStorePaymentScrms = fsStorePaymentScrmMapper.selectFsStorePaymentList(paymentScrm);
-//        if(null != fsStorePaymentScrms && !fsStorePaymentScrms.isEmpty()){
-//            for (FsStorePaymentScrm payment : fsStorePaymentScrms) {
-//                if(StringUtils.isBlank(payment.getTradeNo())){
-//                    continue;
-//                }
-//                V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
-//                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-//                request.setOrgHfSeqId(payment.getTradeNo());
-//                request.setAppId(payment.getAppId());
-//                HuiFuQueryOrderResult o = null;
-//                try {
-//                    o = huiFuService.queryOrder(request);
-//                } catch (Exception e) {
-//                    log.error("查询失败:"+e.getMessage());
-//                    continue;
-//                }
-//                log.info("汇付返回" + o);
-//                if ("00000000".equals(o.getResp_code()) && "S".equals(o.getTrans_stat())) {
-//                    try {
-//                        Date payTime = formatter.parse(o.getEnd_time());
-//                        FsStorePaymentScrm payUpdate = new FsStorePaymentScrm();
-//                        payUpdate.setPaymentId(payment.getPaymentId());
-//                        payUpdate.setPayTime(payTime);
-//                        payUpdate.setStatus(1);
-//                        payUpdate.setTradeNo(o.getOrg_hf_seq_id());
-//                        payUpdate.setBankSerialNo(o.getParty_order_id());
-//                        payUpdate.setBankTransactionId(o.getOut_trans_id());
-//                        fsStorePaymentScrmMapper.updateFsStorePayment(payUpdate);
-//                    } catch (ParseException e) {
-//                        log.error("更新失败 payment:{}",payment ,e);
-////                        throw new RuntimeException(e);
-//                    }
-//
-//
-//                }
-//            }
-//        }
-//    }
-//
-////    @Autowired
-////    private FsStoreMapper fsStoreMapper;
-////    @Autowired
-////    private IFsExpressService expressService;
-////
-////    public void task() {
-////        List<FsStoreOrder> list = fsStoreOrderMapper.selectOrders();
-////        for (FsStoreOrder order : list){
-////            FsStore store = fsStoreMapper.selectFsStoreByStoreId(order.getStoreId());
-////            if (order.getStatus()==3){
-////                //订阅物流回调
-////                String lastFourNumber = "";
-////                if (order.getDeliveryCode().equals(ShipperCodeEnum.SF.getValue())) {
-////                    if (store.getSendPhone()!=null){
-////                        lastFourNumber = store.getSendPhone();
-////                    }else {
-////                        lastFourNumber = order.getUserPhone();
-////                    }
-////                    if (lastFourNumber.length() == 11) {
-////                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
-////                    }
-////                }
-////                expressService.subscribeEspress(order.getOrderCode(),order.getDeliveryCode(),order.getDeliverySn(),lastFourNumber);
-////            }
-////        }
-////    }
-//
-//    //    public void task() {
-////        List<FsPackage> fsPackages = fsPackageMapper.selectFsPackageList(new FsPackage());
-////        for (FsPackage fsPackage : fsPackages) {
-////            String productJson = fsPackage.getProductJson();
-////            if (productJson != null && productJson != "") {
-////                JSONArray objects = JSONUtil.parseArray(fsPackage.getProductJson());
-////                List<FsPackagePruductDTO> products = JSONUtil.toList(objects, FsPackagePruductDTO.class);
-////                if (products != null && products.size() > 0) {
-////                    for (FsPackagePruductDTO product : products) {
-////                        FsStoreProduct fsStoreProduct = fsStoreProductMapper.selectFsStoreProductByProductId(product.getProductId());
-////                        product.setPrescribeSpec(fsStoreProduct.getPrescribeSpec());
-////                    }
-////                    String jsonStr = JSONUtil.toJsonStr(products);
-////                    fsPackage.setProductJson(jsonStr);
-////                    fsPackageService.updateFsPackage(fsPackage);
-////                }
-////            }
-////        }
-////    }
-//
-//
-////    public void task(){
-////        String filePath = "C:\\home\\ex.xlsx";
-////        try {
-////            InputStream inputStream = new FileInputStream(new File(filePath));
-////            ExcelUtil<FsStoreProduct> util = new ExcelUtil<>(FsStoreProduct.class);
-////            List<FsStoreProduct> list = util.importExcel(inputStream);
-////            for (FsStoreProduct fsStoreProduct : list) {
-////                String barCode = fsStoreProduct.getBarCode();
-////                List<FsStoreProduct> p= fsStoreProductMapper.selectCode(barCode);
-////                if (p!=null&&p.size()>0){
-////                    for (FsStoreProduct storeProduct : p) {
-////                        FsStoreProduct s = new FsStoreProduct();
-////                        s.setProductId(storeProduct.getProductId());
-////                        s.setProductName(fsStoreProduct.getProductName());
-////                        s.setPrescribeSpec(fsStoreProduct.getPrescribeSpec());
-////                        fsStoreProductMapper.updateFsStoreProduct(s);
-////                        logger.info( "更新商品:"+storeProduct.getProductName()+"规格"+fsStoreProduct.getPrescribeSpec());
-////                    }
-////                }
-////            }
-////        }catch (Exception e){
-////
-////        }
-////        logger.info("更新商品完成");
-////
-////    }
-////    public void task(){
-////        FsPatient p = new FsPatient();
-////        p.setIsDel(0);
-////        List<FsPatient> fsPatients = fsPatientMapper.selectFsPatientList(p);
-////        Long num=0L;
-////        for (FsPatient fsPatient : fsPatients) {
-////            boolean b=false;
-////            if (fsPatient.getIdCard()!=null){
-////
-////                String idCardNumber = fsPatient.getIdCard();
-////                if (idCardNumber == null || idCardNumber.length() != 18) {
-////                    b=true;
-////                }else {
-////                    String regex = "\\d{17}[0-9Xx]";
-////                    if (!Pattern.matches(regex, idCardNumber)) {
-////                        b=true;
-////                    }else {
-////                        try {
-////                            String birthDateString = idCardNumber.substring(6, 14);
-////                            LocalDate birthDate = LocalDate.parse(birthDateString, DateTimeFormatter.ofPattern("yyyyMMdd"));
-////                            LocalDate currentDate = LocalDate.now();
-////                            int age = currentDate.getYear() - birthDate.getYear();
-////                            if (currentDate.getMonthValue() < birthDate.getMonthValue()
-////                                    || (currentDate.getMonthValue() == birthDate.getMonthValue()
-////                                    && currentDate.getDayOfMonth() < birthDate.getDayOfMonth())) {
-////                                age--;
-////                            }
-////                            if (age < 18) {
-////                                b=true;
-////                            }
-////                        }catch (Exception e){
-////                            b=true;
-////                        }
-////
-////                    }
-////                }
-////            }
-////            if (b==true){
-////                FsPatient fsPatient1 = new FsPatient();
-////                fsPatient1.setPatientId(fsPatient.getPatientId());
-////                fsPatient1.setIsDel(1);
-////                fsPatientMapper.updateFsPatient(fsPatient1);
-////                num++;
-////                logger.info("删除病人:"+fsPatient.getPatientName()+":"+fsPatient.getIdCard());
-////                logger.info("数量:"+num);
-////            }
-////        }
-////    }
-//
-////    public void aa(){
-////        String[] numbers = {
-////                "1774771531176476672",
-////                "1774747581851631616",
-////                "1774735879609253888",
-////                "1774728203970019328",
-////                "1774721325441482752",
-////                "1774706058258808832",
-////                "1774691294237425664",
-////                "1774686009271779328",
-////                "1774679466350477312",
-////                "1774674516987871232"
-////        };
-////
-////        for (String number : numbers) {
-////            FsStoreOrder fsStoreOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(number);
-////            Long orderId = fsStoreOrder.getOrderId();
-////            List<FsStoreOrderItem> fsStoreOrderItems = fsStoreOrderItemMapper.selectFsStoreOrderItemListByOrderId(orderId);
-////            for (FsStoreOrderItem fsStoreOrderItem : fsStoreOrderItems) {
-////                fsStoreOrderItemMapper.deleteFsStoreOrderItemByItemId(fsStoreOrderItem.getItemId()+"");
-////            }
-////            FsPrescribeDrug fsPrescribeDrug = new FsPrescribeDrug();
-////            fsPrescribeDrug.setPrescribeId(fsStoreOrder.getPrescribeId());
-////            List<FsPrescribeDrug> fsPrescribeDrugs = fsPrescribeDrugMapper.selectFsPrescribeDrugList(fsPrescribeDrug);
-////            if (fsPrescribeDrugs!=null){
-////                for (FsPrescribeDrug prescribeDrug : fsPrescribeDrugs) {
-////                    String drugName = prescribeDrug.getDrugName();
-////                    FsStoreProduct fsStoreProduct = fsPrescribeDrugMapper.selectFsPrescribeDrugCode(drugName, fsStoreOrder.getStoreId());
-////                    List<FsStoreProductAttrValue> fsStoreProductAttrValues = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueByProductId(fsStoreProduct.getProductId());
-////                    if (fsStoreProductAttrValues!=null&&fsStoreProductAttrValues.size()>0){
-////                        FsStoreProductAttrValue fsStoreProductAttrValue = fsStoreProductAttrValues.get(0);
-////                        prescribeDrug.setProductId(fsStoreProduct.getProductId());
-////                        prescribeDrug.setProductAttrValueId(fsStoreProductAttrValue.getId());
-////                        fsPrescribeDrugMapper.updateFsPrescribeDrug(prescribeDrug);
-////                    }
-////
-////                }
-////            }
-////
-////            FsPrescribe prescribe=fsPrescribeService.selectFsPrescribeByPrescribeId(fsStoreOrder.getPrescribeId());
-////            List<FsPrescribeDrug> drugs=fsPrescribeDrugMapper.selectFsPrescribeDrugList(fsPrescribeDrug);
-////            List<FsStoreOrderItem> items=new ArrayList<>();
-////            Long totalNum=0l;
-////            BigDecimal totalPrice=new BigDecimal(0);
-////            BigDecimal totalCostPrice = new BigDecimal("0");
-////            for(FsPrescribeDrug drug:drugs){
-////                totalPrice=totalPrice.add(drug.getDrugPrice().multiply(BigDecimal.valueOf(drug.getDrugNum())));
-////                totalNum=totalNum+drug.getDrugNum();
-////                FsStoreOrderItem item=new FsStoreOrderItem();
-////                item.setProductId(drug.getProductId());
-////                item.setIsDrug(drug.getIsDrug());
-////                item.setStoreId(prescribe.getStoreId());
-////                item.setProductAttrValueId(drug.getProductAttrValueId());
-////                if (drug.getProductAttrValueId()!=null){
-////                    FsStoreProductAttrValue value = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueById(drug.getProductAttrValueId());
-////                    if (value.getCost()!=null){
-////                        if (drug.getDrugNum()!=null){
-////                            totalCostPrice=totalCostPrice.add(value.getCost().multiply(BigDecimal.valueOf(drug.getDrugNum())));
-////                        }
-////                    }
-////                }
-////
-////                item.setNum(drug.getDrugNum());
-////                FsStoreOrderItemDTO dto=new FsStoreOrderItemDTO();
-////                dto.setImage(drug.getDrugImgUrl());
-////                dto.setNum(drug.getDrugNum());
-////                FsStoreProduct product=fsStoreProductMapper.selectFsStoreProductByProductId(drug.getProductId());
-////                if(product!=null){
-////                    dto.setProductName(product.getProductName());
-////                    dto.setProductId(product.getProductId());
-////                }
-////                FsStoreProductAttrValue value=fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueById(drug.getProductAttrValueId());
-////                if(value!=null){
-////                    dto.setSku(value.getSku());
-////                    dto.setBarCode(value.getBarCode());
-////                    dto.setPrice(value.getPrice());
-////                    dto.setNum(drug.getDrugNum());
-////                    dto.setImage(value.getImage());
-////                }
-////                item.setIsPrescribe(1);
-////                item.setJsonInfo(JSON.toJSONString(dto));
-////                items.add(item);
-////            }
-////            //中药总价处理
-////            if(prescribe.getPrescribeType().equals(2)){
-////                FsPrescribeUsageDTO dto=JSONUtil.toBean(prescribe.getUsageJson(),FsPrescribeUsageDTO.class);
-////                totalPrice=totalPrice.multiply(BigDecimal.valueOf(dto.getCounts()));
-////                totalNum=dto.getCounts();
-////                totalCostPrice=totalCostPrice.multiply(BigDecimal.valueOf(dto.getCounts()));
-////            }
-////            FsStoreOrder order = new FsStoreOrder();
-////            order.setOrderId(fsStoreOrder.getOrderId());
-////            order.setCostPrice(totalCostPrice);
-////            order.setItemJson(JSONUtil.toJsonStr(items));
-////            fsStoreOrderMapper.updateFsStoreOrder(order);
-////            for(FsStoreOrderItem item:items){
-////                item.setOrderId(fsStoreOrder.getOrderId());
-////                fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
-////            }
-////        }
-////
-////
-////    }
-//
-////    public void task()
-////    {
-////
-////        List<FsPackageOrder> fsPackageOrders = fsPackageOrderMapper.selectFsPackageOrderallList();
-////        Integer num=0;
-////        for (FsPackageOrder fsPackageOrder : fsPackageOrders) {
-////            FsPackageOrder o = fsPackageOrderMapper.selectFsPackageOrderByOrderId(fsPackageOrder.getOrderId());
-////            if (o.getPackageJson()!=null){
-////                System.out.println("更改订单:"+o.getOrderId());
-////                List<FsPackagePruductDTO> products=null;
-////                try {
-////                    Map<String,Object> packageJson = (Map)JSON.parse(o.getPackageJson());
-////                    String json = (String)packageJson.get("productJson");
-////                    JSONArray objects =JSONUtil.parseArray(json);
-////                     products=JSONUtil.toList(objects,FsPackagePruductDTO.class);
-////
-////                }catch (Exception e){
-////                    System.out.println("json解析错误"+o.getPackageJson());
-////                }
-////               BigDecimal toal = new BigDecimal(0);
-////                for (FsPackagePruductDTO product : products) {
-////                    if (product.getCount()==null){
-////                        product.setCount(0);
-////                    }
-////                    if (product.getCostPrice()==null){
-////                        product.setCostPrice(new BigDecimal("0"));
-////                    }
-////                    toal= toal.add(product.getCostPrice().multiply(new BigDecimal(product.getCount())));
-////                }
-////                Integer followRate = 6;
-////                BigDecimal in=new BigDecimal("0");
-////                if (o.getCycle()!=null){
-////                    in= new BigDecimal((o.getCycle()/followRate) *300);
-////                }
-////
-////                FsPackageOrder order = new FsPackageOrder();
-////                order.setOrderId(o.getOrderId());
-////                order.setInquiryCostPrice(in);
-////                order.setProductCostPrice(toal);
-////                order.setTotalCostPrice(toal.add(in));
-////                iFsPackageOrderService.updateFsPackageOrder(order);
-////                num++;
-////            }
-//    /// /
-////        }
-////
-////        logger.info("所有订单同步完成:"+num);
-////
-////
-////    }
-//
-//
-////    @Autowired
-////    private TzBankService tzBankService;
-//
-////    public void task(){
-////        List<FsStorePayment> fsStorePayments = fsStorePaymentMapper.selectFsStorePaymentbyshare();
-////        //交易金额
-////       String s="";
-////        for (FsStorePayment fsStorePayment : fsStorePayments) {
-////            String busType="";
-////            if (fsStorePayment.getBusinessType()==1){
-////                busType ="inquiry";
-////            }else if(fsStorePayment.getBusinessType()==2){
-////                busType ="store";
-////            }else {
-////                busType ="package";
-////            }
-////            //交易金额
-////            BigDecimal payMoney = fsStorePayment.getPayMoney();
-////            BigDecimal share = payMoney.multiply(new BigDecimal(0.001)).setScale(2, RoundingMode.HALF_UP);
-////
-////                OrderShareParam orderShareParam = new OrderShareParam();
-////                //// 传的分账订单号
-////                orderShareParam.setOutOrderNo("share"+fsStorePayment.getPayCode());
-////                //旧的支付外部订单号 支付时上上传的
-////                orderShareParam.setOldPayOutOrderNo(busType+fsStorePayment.getPayCode());
-////                orderShareParam.setTrxAmt(fsStorePayment.getPayMoney().doubleValue());
-////                OrderShareParam.sharers sharer = new OrderShareParam.sharers();
-////                //分账金额
-////            if (share.compareTo(BigDecimal.ZERO)!=0){
-////                sharer.setShareAmt(share.doubleValue());
-////                sharer.setSharerCstName("重庆云联融智科技有限公司");
-////                sharer.setSharerCstNo("943103603046907709");
-////                List<OrderShareParam.sharers> sharers = new ArrayList<>();
-////                sharers.add(sharer);
-////                orderShareParam.setSharers(sharers);
-////            }
-////                TzBankResult<OrderShareResult> r = tzBankService.orderShare(orderShareParam);
-////                if (r.getRetType().equals("S")){
-////                    if (r.getBody().getShareOrdStatus().equals("90")||r.getBody().getShareOrdStatus().equals("60")){
-////                        FsStorePayment sharePayment = new FsStorePayment();
-////                        sharePayment.setPaymentId(fsStorePayment.getPaymentId());
-////                        sharePayment.setShareStatus(1);
-////                        sharePayment.setShareCode(r.getBody().getShareOrderNo());
-////                        sharePayment.setShareMoney(new BigDecimal(r.getBody().getTrxAmt()));
-////                        fsStorePaymentMapper.updateFsStorePayment(sharePayment);
-////                        logger.info("分账完成:"+r);
-////                        FsStoreOrder fsStoreOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(fsStorePayment.getBusinessCode());
-////                        if (fsStoreOrder!=null){
-////                            FsStoreOrder fsStoreOrder1 = new FsStoreOrder();
-////                            fsStoreOrder1.setOrderId(fsStoreOrder.getOrderId());
-////                            fsStoreOrder1.setIsAfterSales(0);
-////                            fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder1);
-////                        }
-////                    }else {
-////                        logger.info("分账失败:"+fsStorePayment);
-////                        s+="/n 分账失败"+fsStorePayment.getPayCode()+r.getRetMsg();
-////                    }
-////                }else {
-////                    logger.info("分账请求失败:"+fsStorePayment+r.getRetMsg());
-////                    s+="/n 分账失败"+fsStorePayment.getPayCode()+r.getRetMsg();
-////                }
-////
-////        }
-////        logger.info("分账请求完成:"+s);
-////}
-//
-//
-//    //同步流水
-////    public void task(){
-////        CompanyMoneyLogs item = moneyLogsMapper.selectCompanyMoneyLogsById(248884L);
-////        String logsId=item.getLogsId().toString();
-////        Long companyId=item.getCompanyId();
-////        BigDecimal companyMoney= item.getBalance();
-////        List<CompanyMoneyLogs> logs=moneyLogsMapper.selectCompanyMoneyLogsByCompanyId(companyId,logsId);
-////        if(logs!=null){
-////            for(CompanyMoneyLogs log:logs){
-////                companyMoney=companyMoney.add(log.getMoney());
-////                CompanyMoneyLogs logMap=new CompanyMoneyLogs();
-////                logMap.setLogsId(log.getLogsId());
-////                logMap.setBalance(companyMoney);
-////                moneyLogsMapper.updateCompanyMoneyLogs(logMap);
-////            }
-////            Company company = new Company();
-////            company.setCompanyId(companyId);
-////            company.setMoney(companyMoney);
-////            companyMapper.updateCompany(company);
-////        }
-////
-////    }
-//
-//
-////    public String upTp(String s)  {
-////        BufferedImage img = null;
-////        InputStream is =null;
-////        try {
-////            URL url = new URL(s);
-////            URLConnection connection = url.openConnection();
-////            is = connection.getInputStream();
-////        } catch (IOException e) {
-////            return s;
-////        }
-////        String caselsh  = s.substring(s.lastIndexOf(".")+1);
-////        CloudStorageService storage = OSSFactory.build();
-////        System.out.println(s);
-////        String url = storage.uploadSuffix(is, "."+caselsh);
-////        try {
-////            is.close();
-////        } catch (IOException e) {
-////        }
-////        return url;
-////
-////    }
-////public void st() throws Exception
-////{
-////    String destinationFolder = "E:/st/";
-////    int i=1;
-////    List<String> strings = fsInquiryOrderMapper.selectTongueImages();
-////    for (String string : strings) {
-////        String[] split = string.split(",");
-////        for (String imageUrl : split) {
-////            String fileName = i+".jpg";
-////            try {
-////                URL url = new URL(imageUrl);
-////                InputStream is = url.openStream();
-////                File destinationDir = new File(destinationFolder);
-////                if (!destinationDir.exists()) {
-////                    destinationDir.mkdirs();
-////                }
-////                FileOutputStream fos = new FileOutputStream(destinationFolder + fileName);
-////
-////                byte[] buffer = new byte[4096];
-////                int bytesRead;
-////                while ((bytesRead = is.read(buffer)) != -1) {
-////                    fos.write(buffer, 0, bytesRead);
-////                }
-////                System.out.println(i);
-////                i++;
-////                fos.close();
-////                is.close();
-////            } catch (IOException e) {
-////                System.out.println("错误: ");
-////            }
-////        }
-////    }
-////
-////}
-//    @Autowired
-//    @Qualifier("erpOrderServiceImpl")
-//    private IErpOrderService gyOrderService;
-//
-//    @Autowired
-//    @Qualifier("wdtErpOrderServiceImpl")
-//    private IErpOrderService wdtOrderService;
-//    @Autowired
-//    @Qualifier("hzOMSErpOrderServiceImpl")
-//    private IErpOrderService hzOMSErpOrderService;
-//    @Autowired
-//    @Qualifier("dfOrderServiceImpl")
-//    private IErpOrderService dfOrderService;
-//
-//    @Autowired
-//    @Qualifier("JSTErpOrderServiceImpl")
-//    private IErpOrderService jSTOrderService;
-//    @Autowired
-//    @Qualifier("k9OrderScrmServiceImpl")
-//    private IErpOrderService k9OrderService;
-//
-//    private IErpOrderService getErpService() {
-//        FsSysConfig sysConfig = configUtil.getSysConfig();
-//        Integer erpOpen = sysConfig.getErpOpen();
-//        if (erpOpen != null && erpOpen == 1) {
-//            //判断erp类型
-//            Integer erpType = sysConfig.getErpType();
-//            if (erpType != null) {
-//                IErpOrderService erpOrderService = null;
-//                if (erpType == 1) {
-//                    //管易
-//                    erpOrderService = gyOrderService;
-//                } else if (erpType == 2) {
-//                    //旺店通
-//                    erpOrderService = wdtOrderService;
-//                } else if (erpType == 3) {
-//                    //
-//                    erpOrderService = hzOMSErpOrderService;
-//                } else if (erpType == 4) {
-//                    //代服
-//                    erpOrderService = dfOrderService;
-//                } else if (erpType == 5) {
-//                    erpOrderService = jSTOrderService;
-//                } else if (erpType == 6) {
-//                    erpOrderService = k9OrderService;
-//                }
-//                return erpOrderService;
-//
-//
-//            }
-//        }
-//        return null;
-//    }
-//
-//
-//    /**
-//     * 定时任务-im会员定时发课,每一分钟执行一次
-//     */
-//    public void sendOpenImCourse(){
-//        String redisKey = "openIm:batchSendMsg:sendCourse";
-//        Map<String, BatchSendCourseAllDTO> cacheMap = redisCache.getCacheMap(redisKey);
-//        if(cacheMap == null || cacheMap.isEmpty()){
-//            logger.info("=====================会员IM定时发课,不存在对应的redisKey==================");
-//            return;
-//        }
-//        List<Map.Entry<String, BatchSendCourseAllDTO>> toSendMap = cacheMap.entrySet().parallelStream().filter((v) -> {
-//            String[] split = v.getKey().split(":");
-//            long timestamp = Long.parseLong(split[2]);
-//            return timestamp < System.currentTimeMillis();
-//        }).collect(Collectors.toList());
-//
-//        if(toSendMap.isEmpty()){
-//            logger.info("=====================会员IM定时发课,不存在可执行的发课任务==================");
-//            return;
-//        }
-//        for (Map.Entry<String, BatchSendCourseAllDTO> entry : toSendMap) {
-//            //执行发送消息任务
-//            BatchSendCourseAllDTO batchSendCourseAllDTO = entry.getValue();
-//            openIMService.batchSendCourseTask(batchSendCourseAllDTO.getBatchSendCourseDTO(), batchSendCourseAllDTO.getOpenImBatchMsgDTO(), batchSendCourseAllDTO.getProject(), batchSendCourseAllDTO.getImMsgSendDetailList());
-//
-//            // 执行结束,删除
-//            this.redisTemplate.<String, BatchSendCourseAllDTO>opsForHash().delete(redisKey, entry.getKey());
-//
-//        }
-//
-//    }
-//
-//
-//    /**
-//     * 定时任务-im 会员催课,每一分钟执行一次
-//     */
-//    public void urgeOpenImCourse(){
-//        String redisKey = "openIm:batchSendMsg:urgeCourse";
-//        Map<String, BatchSendCourseAllDTO> cacheMap = redisCache.getCacheMap(redisKey);
-//        if(cacheMap == null || cacheMap.isEmpty()){
-//            logger.info("===================== 会员-IM发消息催课,不存在对应的redisKey==================");
-//            return;
-//        }
-//        List<Map.Entry<String, BatchSendCourseAllDTO>> toSendMap = cacheMap.entrySet().parallelStream().filter((v) -> {
-//            String[] split = v.getKey().split(":");
-//            long timestamp = Long.parseLong(split[2]);
-//            return timestamp < System.currentTimeMillis();
-//        }).collect(Collectors.toList());
-//
-//        if(toSendMap.isEmpty()){
-//            logger.info("===================== 会员-IM发消息催课,不存在可发送的消息==================");
-//            return;
-//        }
-//        for (Map.Entry<String, BatchSendCourseAllDTO> entry : toSendMap) {
-//            //执行发送消息任务
-//            BatchSendCourseAllDTO batchSendCourseAllDTO = entry.getValue();
-//            openIMService.batchUrgeCourseTask(batchSendCourseAllDTO.getOpenImBatchMsgDTO(), batchSendCourseAllDTO.getImMsgSendDetailList());
-//
-//            // 执行结束,删除
-//            this.redisTemplate.<String, BatchSendCourseAllDTO>opsForHash().delete(redisKey, entry.getKey());
-//
-//        }
-//    }
-//
-//    /** 定时删除行为轨迹记录 (数据量太大 默认保留一天的)。SaaS 开启时按租户执行。 */
-//    @Scheduled(cron = "0 0 1 * * ?")
-////    @Scheduled(cron = "0 * * * * ?") //测试每分钟执行一次
-//    public void deleteUserOperationLog() {
-//        if (saasTaskEnabled && tenantTaskRunner != null) {
-//            tenantTaskRunner.runForEachTenant("deleteUserOperationLog", this::doDeleteUserOperationLog);
-//        } else {
-//            doDeleteUserOperationLog();
-//        }
-//    }
-//
-//    private void doDeleteUserOperationLog() {
-//        LambdaQueryWrapper<FsUserOperationLog> wrapper = new LambdaQueryWrapper<>();
-//        wrapper.lt(FsUserOperationLog::getCreateTime, DateUtils.addDays(new Date(), -1));
-//        int deleteCount = fsUserOperationLogMapper.delete(wrapper);
-//        log.info("定时删除行为轨迹记录 {} 条", deleteCount);
-//    }
-//
-//    //同步支付状态
-//    public void synchronizePayStatus(){
-//        fsStorePaymentService.synchronizePayStatus();
-//    }
-//
-//    /**
-//     * 超时取消订单
-//     */
-//    public void cancelOrder(){
-//        //查询超时订单
-//        SysConfig sysConfig= sysConfigService.selectConfigByConfigKey("his.store");
-//        StoreConfig config= JSONUtil.toBean(sysConfig.getConfigValue(),StoreConfig.class);
-//        Integer unPayTime = config.getUnPayTime(); //分钟
-//        if (unPayTime == null){
-//            return ;
-//        }
-//        //1.处方订单
-//        //查询超时未支付订单
-//        List<FsStoreOrder> orderList = orderService.selectOutTimeOrderList(unPayTime);
-//        //取消订单
-//        List<CompletableFuture<Void>> orderFutures = cancelOrdersAsync(orderList, order -> {
-//            orderService.cancelOrder(order.getOrderId());
-//        });
-//
-////        //2.课程订单
-////        //查询超时未支付订单
-////        List<FsUserCourseOrder> courseOrderlist = userCourseOrderService.selectOutTimeOrderList(unPayTime);
-////        //取消订单
-////        courseOrderlist.forEach(order->{
-////            userCourseOrderService.cancelOrder(order.getOrderId());
-////        });
-//        //3.服务包订单
-//        //查询超时未支付订单
-//        List<FsPackageOrder> packageOrderList = packageOrderService.selectOutTimeOrderList(unPayTime);
-//        //取消订单
-//        List<CompletableFuture<Void>> packageOrderFutures = cancelOrdersAsync(packageOrderList, order -> {
-//            FsPackageOrderCancelParam param = new FsPackageOrderCancelParam();
-//            param.setOrderId(order.getOrderId());
-//            packageOrderService.cancel(param);
-//        });
-//
-//        // 等待所有任务完成
-//        waitForAllTasksToComplete(orderFutures);
-//        waitForAllTasksToComplete(packageOrderFutures);
-//    }
-//
-//    /**
-//     * 异步取消订单
-//     * @param orders 订单列表
-//     * @param cancelAction 取消订单的逻辑
-//     * @param <T> 订单类型
-//     * @return CompletableFuture列表
-//     */
-//    private <T> List<CompletableFuture<Void>> cancelOrdersAsync(List<T> orders, Consumer<T> cancelAction) {
-//        List<CompletableFuture<Void>> futures = new ArrayList<>();
-//        for (T order : orders) {
-//            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
-//                try {
-//                    cancelAction.accept(order);
-//                } catch (Exception e) {
-//                    // 记录异常日志
-//                    System.err.println("Failed to cancel order: " + order + ", Error: " + e.getMessage());
-//                }
-//            }, threadPoolTaskExecutor);
-//            futures.add(future);
-//        }
-//        return futures;
-//    }
-//
-//    /**
-//     * 等待所有任务完成
-//     * @param futures CompletableFuture列表
-//     */
-//    private void waitForAllTasksToComplete(List<CompletableFuture<Void>> futures) {
-//        CompletableFuture<Void> allFutures = CompletableFuture.allOf(
-//                futures.toArray(new CompletableFuture[0])
-//        );
-//        allFutures.join(); // 等待所有任务完成
-//    }
-//
-//
-//}

+ 0 - 56
fs-service/src/main/java/com/fs/his/task/WatchCourseTask.java

@@ -1,56 +0,0 @@
-//package com.fs.his.task;
-//
-//import com.fs.course.service.IFsUserWatchCourseStatisticsService;
-//import com.fs.course.service.IFsUserWatchStatisticsService;
-//import com.fs.erp.service.IErpOrderService;
-//import com.fs.his.service.IFsUserOnlineStateService;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Component;
-//
-///**
-// * 定时任务调度测试
-// *
-// * @author fs
-// */
-//@Component("storeTask")
-//public class WatchCourseTask
-//{
-//    @Autowired
-//    IErpOrderService erpOrderService;
-//
-//    @Autowired
-//    private IFsUserWatchCourseStatisticsService fsUserWatchCourseStatisticsService;
-//
-//    @Autowired
-//    private IFsUserWatchStatisticsService fsUserWatchStatisticsService;
-//
-//    @Autowired
-//    private IFsUserOnlineStateService fsUserOnlineStateService;
-//
-//
-//    /**
-//     * 添加看课汇总统计
-//     */
-//    public void insertWatchStatistics(){
-//        /***************************************进入营期会员看课汇总统计定时任务****************************************/
-//        fsUserWatchStatisticsService.insertStatistics();
-//        /***************************************营期会员看课汇总统计定时任务结束***************************************/
-//    }
-//
-//    /**
-//     * 添加看课明细统计
-//     */
-//    public void insertWatchCourseStatistics(){
-//        /***************************************进入营期会员看课明细统计定时任务*******************************/
-//        fsUserWatchCourseStatisticsService.insertWatchCourseStatistics();
-//        /***************************************进入营期会员看课明细统计定时任务结束**********************************************/
-//    }
-//
-//    /**
-//     * 定时查询未上线的用户
-//     */
-//    public void insertUserNotOnline(){
-//        fsUserOnlineStateService.insertUserNotOnline();
-//    }
-//
-//}

+ 0 - 20
fs-service/src/main/java/com/fs/his/task/trafficlog/TrafficlogTask.java

@@ -1,20 +0,0 @@
-//package com.fs.his.task.trafficlog;
-//
-//import com.fs.course.service.IFsCourseTrafficLogService;
-//import org.slf4j.Logger;
-//import org.slf4j.LoggerFactory;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.stereotype.Service;
-//
-//@Service("trafficlogTask")
-//public class TrafficlogTask {
-//    private static final Logger log = LoggerFactory.getLogger(TrafficlogTask.class);
-//    @Autowired
-//    private IFsCourseTrafficLogService fsCourseTrafficLogService;
-//    /**
-//     * 红包流量统计
-//     */
-//    public void sumTrafficlog(){
-//        fsCourseTrafficLogService.sumTrafficlog();
-//    }
-//}

+ 0 - 20
fs-service/src/main/java/com/fs/hisStore/task/CrmTask.java

@@ -1,20 +0,0 @@
-package com.fs.hisStore.task;
-
-import com.fs.crm.service.ICrmCustomerService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-@Service("crmTask")
-public class CrmTask {
-    private static final Logger log = LoggerFactory.getLogger(CrmTask.class);
-    @Autowired
-    private ICrmCustomerService crmCustomerService;
-    /**
-     * 汇总crm订单成交总额
-     */
-    public void computePayMoney(){
-        crmCustomerService.computePayMoney();
-    }
-}

+ 0 - 110
fs-service/src/main/java/com/fs/hisStore/task/ErpTask.java

@@ -1,110 +0,0 @@
-package com.fs.hisStore.task;
-
-import com.fs.erp.domain.ErpOrder;
-import com.fs.erp.domain.FsErpFinishPush;
-import com.fs.erp.dto.ErpOrderResponse;
-import com.fs.erp.mapper.FsErpFinishPushMapper;
-import com.fs.erp.service.IErpOrderService;
-import com.fs.hisStore.domain.FsStoreOrderScrm;
-import com.fs.hisStore.service.IFsStoreOrderScrmService;
-import com.fs.live.domain.LiveOrder;
-import com.fs.live.service.ILiveOrderService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.Date;
-import java.util.List;
-
-@Service("erpTask")
-public class ErpTask {
-    private static final Logger log = LoggerFactory.getLogger(ErpTask.class);
-
-    @Autowired
-    private FsErpFinishPushMapper fsErpFinishPushMapper;
-    @Autowired
-    private IErpOrderService erpOrderService;
-
-    @Autowired
-    private IFsStoreOrderScrmService fsStoreOrderService;
-
-    @Autowired
-    private ILiveOrderService liveOrderService;
-
-
-    /**
-     * 推送完成订单到ERP
-     */
-    public void pushFinishOrderToErp(){
-        List<FsErpFinishPush> fsErpFinishPushes = fsErpFinishPushMapper.queryPenddingOrder();
-        for (FsErpFinishPush fsErpFinishPush : fsErpFinishPushes) {
-            FsStoreOrderScrm fsStoreOrder = fsStoreOrderService.selectFsStoreOrderById(fsErpFinishPush.getOrderId());
-            if (fsStoreOrder != null) {
-                try {
-
-                    ErpOrder erpOrder = fsStoreOrderService.getErpOrder(fsStoreOrder);
-
-                    ErpOrderResponse erpOrderResponse = erpOrderService.finishOrder(erpOrder);
-
-                    fsErpFinishPush.setParams(erpOrderResponse.getRequestRawData());
-                    fsErpFinishPush.setResult(erpOrderResponse.getResponseRawData());
-                    fsErpFinishPush.setUpdateTime(new Date());
-
-                    if(erpOrderResponse.getSuccess()!= null && erpOrderResponse.getSuccess()){
-                        fsErpFinishPush.setTaskStatus(1);
-
-                        log.error("推送完成订单到ERP成功! 订单号: {}",fsErpFinishPush.getOrderId());
-                    } else {
-                        fsErpFinishPush.setTaskStatus(2);
-                        fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount()+1);
-                        log.error("推送完成订单到ERP失败! 订单号: {}",fsErpFinishPush.getOrderId());
-                    }
-                } catch (Throwable e) {
-                    fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount()+1);
-                    fsErpFinishPush.setErrorMessage(ExceptionUtils.getStackTrace(e));
-                    fsErpFinishPush.setTaskStatus(2);
-                    log.error("订单推送失败!原因: {}", ExceptionUtils.getStackTrace(e),e);
-                    continue;
-                }
-            } else {
-                LiveOrder liveOrder = liveOrderService.selectLiveOrderByOrderId(String.valueOf(fsErpFinishPush.getOrderId()));
-                if (liveOrder != null) {
-                    try {
-                        ErpOrder erpOrder = liveOrderService.getErpOrder(liveOrder);
-
-                        ErpOrderResponse erpOrderResponse = erpOrderService.finishOrder(erpOrder);
-
-                        fsErpFinishPush.setParams(erpOrderResponse.getRequestRawData());
-                        fsErpFinishPush.setResult(erpOrderResponse.getResponseRawData());
-                        fsErpFinishPush.setUpdateTime(new Date());
-
-                        if (erpOrderResponse.getSuccess() != null && erpOrderResponse.getSuccess()) {
-                            fsErpFinishPush.setTaskStatus(1);
-
-                            log.error("推送完成订单到ERP成功! 订单号: {}", fsErpFinishPush.getOrderId());
-                        } else {
-                            fsErpFinishPush.setTaskStatus(2);
-                            fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount() + 1);
-                            log.error("推送完成订单到ERP失败! 订单号: {}", fsErpFinishPush.getOrderId());
-                        }
-                    } catch (Throwable e) {
-                        fsErpFinishPush.setRetryCount(fsErpFinishPush.getRetryCount() + 1);
-                        fsErpFinishPush.setErrorMessage(ExceptionUtils.getStackTrace(e));
-                        fsErpFinishPush.setTaskStatus(2);
-                        log.error("订单推送失败!原因: {}", ExceptionUtils.getStackTrace(e), e);
-                        continue;
-                    }
-                } else {
-                    log.error("订单不存在! 订单号: {}",fsErpFinishPush.getOrderId());
-                    continue;
-                }
-            }
-
-            fsErpFinishPushMapper.updateById(fsErpFinishPush);
-        }
-
-    }
-
-}

+ 0 - 30
fs-service/src/main/java/com/fs/hisStore/task/ExpressTask.java

@@ -1,30 +0,0 @@
-package com.fs.hisStore.task;
-
-
-import com.fs.hisStore.service.IFsStoreOrderScrmService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-/**
- * 物流信息定时任务
- */
-@Component("expressTask")
-public class ExpressTask {
-    private static final Logger log = LoggerFactory.getLogger(ExpressTask.class);
-
-    @Autowired
-    private IFsStoreOrderScrmService fsStoreOrderScrmService;
-
-    public void syncExpressToWx(){
-        fsStoreOrderScrmService.syncExpressToWx();
-    }
-
-
-    //定时任务刷新订单结算状态
-    public void refreshOrderSettlementStatus(){
-        fsStoreOrderScrmService.refreshOrderSettlementStatus();
-    }
-
-}

+ 0 - 667
fs-service/src/main/java/com/fs/hisStore/task/LiveTask.java

@@ -1,667 +0,0 @@
-package com.fs.hisStore.task;
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
-import com.fs.common.core.domain.R;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.utils.DateUtils;
-import com.fs.company.service.ICompanyService;
-import com.fs.company.vo.RedPacketMoneyVO;
-import com.fs.course.mapper.FsCourseRedPacketLogMapper;
-import com.fs.erp.domain.ErpDeliverys;
-import com.fs.erp.domain.ErpOrderQuery;
-import com.fs.erp.dto.ErpOrderQueryRequert;
-import com.fs.erp.dto.ErpOrderQueryResponse;
-import com.fs.erp.service.FsJstAftersalePushScrmService;
-import com.fs.erp.service.IErpOrderService;
-import com.fs.his.config.FsSysConfig;
-import com.fs.his.dto.ExpressInfoDTO;
-import com.fs.his.service.IFsExpressService;
-import com.fs.his.service.IFsUserService;
-import com.fs.his.utils.ConfigUtil;
-import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
-import com.fs.hisStore.dto.DateComparisonConfigDTO;
-import com.fs.hisStore.enums.ShipperCodeEnum;
-import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
-import com.fs.hisStore.param.FsStoreOrderAddTuiMoneyParam;
-import com.fs.hisStore.service.IFsStoreOrderScrmService;
-import com.fs.hisStore.service.IFsStoreProductScrmService;
-import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
-import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
-import com.fs.huifuPay.service.HuiFuService;
-import com.fs.live.domain.LiveAfterSales;
-import com.fs.live.domain.LiveOrder;
-import com.fs.live.domain.LiveOrderItem;
-import com.fs.live.domain.LiveOrderPayment;
-import com.fs.live.mapper.LiveOrderItemMapper;
-import com.fs.live.mapper.LiveOrderMapper;
-import com.fs.live.mapper.LiveOrderPaymentMapper;
-import com.fs.live.param.LiveAfterSalesAudit1Param;
-import com.fs.live.param.LiveAfterSalesParam;
-import com.fs.live.param.LiveAfterSalesProductParam;
-import com.fs.live.service.*;
-import com.fs.pay.pay.dto.OrderQueryDTO;
-import com.fs.pay.service.IPayService;
-import com.fs.store.config.StoreConfig;
-import com.fs.system.service.ISysConfigService;
-import com.fs.ybPay.domain.OrderResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Component;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-import static com.fs.hisStore.constants.StoreConstants.DELIVERY;
-
-/**
- * 定时任务调度测试
- *
- * @author fs
- */
-@Component("liveTask")
-public class LiveTask {
-    private static final Logger log = LoggerFactory.getLogger(LiveTask.class);
-    @Autowired
-    private RedisTemplate redisTemplate;
-    @Autowired
-    private RedisCache redisCache;
-    @Autowired
-    private ILiveOrderService liveOrderService;
-
-    @Autowired
-    private ILiveCouponService liveCouponService;
-
-    @Autowired
-    private ILiveCouponIssueService liveCouponIssueService;
-    @Autowired
-    private IFsStoreProductScrmService fsStoreProductScrmService;
-
-    @Autowired
-    private ILiveAfterSalesService liveAfterSalesService;
-
-    @Autowired
-    private ILiveOrderItemService liveOrderItemService;
-
-    @Autowired
-    private ILiveOrderPaymentService liveOrderPaymentService;
-
-    @Autowired
-    private ICompanyService companyService;
-
-    @Autowired
-    @Qualifier("erpOrderServiceImpl")
-    private IErpOrderService gyOrderService;
-
-    @Autowired
-    @Qualifier("wdtErpOrderServiceImpl")
-    private IErpOrderService wdtOrderService;
-
-    @Autowired
-    @Qualifier("hzOMSErpOrderServiceImpl")
-    private IErpOrderService hzOMSOrderService;
-
-    @Autowired
-    @Qualifier("dfOrderServiceImpl")
-    private IErpOrderService dfOrderService;
-
-    @Autowired
-    @Qualifier("JSTErpOrderServiceImpl")
-    private IErpOrderService jSTOrderService;
-
-    @Autowired
-    @Qualifier("k9OrderScrmServiceImpl")
-    private IErpOrderService k9OrderService;
-
-    @Autowired
-    private ConfigUtil configUtil;
-
-    @Autowired
-    IErpOrderService erpOrderService;
-
-    @Autowired
-    private LiveOrderMapper liveOrderMapper;
-
-    @Autowired
-    private LiveOrderItemMapper liveOrderItemMapper;
-
-    @Autowired
-    private LiveOrderPaymentMapper liveOrderPaymentMapper;
-
-    @Autowired
-    private IPayService ybPayService;
-
-    @Autowired
-    private ISysConfigService configService;
-
-    @Autowired
-    private IFsExpressService expressService;
-
-    @Autowired
-    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
-
-    @Autowired
-    private JdbcTemplate jdbcTemplate;
-
-    @Autowired
-    private HuiFuService huiFuService;
-
-    @Autowired
-    private IFsStoreOrderScrmService orderService;
-
-    @Autowired
-    private FsJstAftersalePushScrmService fsJstAftersalePushScrmService;
-
-    /**
-     * 查询被拆分的订单,然后查询拆分订单的物流信息
-     */
-    public void querySplitOrderDelivery() {
-        try {
-            // 查询状态为6(被拆分)的订单
-            List<LiveOrder> splitOrders = liveOrderMapper.selectSplitOrders();
-            if (splitOrders == null || splitOrders.isEmpty()) {
-                log.debug("没有找到被拆分的订单");
-                return;
-            }
-
-            log.info("找到 {} 个被拆分的订单,开始查询拆分订单的物流信息", splitOrders.size());
-
-            IErpOrderService erpOrderService = getErpOrderService();
-            if (erpOrderService == null) {
-                log.warn("ERP服务未配置,无法查询拆分订单物流信息");
-                return;
-            }
-
-            for (LiveOrder splitOrder : splitOrders) {
-                try {
-                    // 查询该订单的所有拆分订单(通过原订单号查询)
-                    List<LiveOrder> childOrders = liveOrderMapper.selectChildOrdersByParentOrderCode(splitOrder.getOrderCode());
-                    if (childOrders == null || childOrders.isEmpty()) {
-                        log.debug("订单 {} 没有找到拆分订单", splitOrder.getOrderCode());
-                        continue;
-                    }
-
-                    // 遍历拆分订单,查询物流信息
-                    for (LiveOrder childOrder : childOrders) {
-                        if (StringUtils.isEmpty(childOrder.getExtendOrderId())) {
-                            log.debug("拆分订单 {} 没有扩展订单ID,跳过", childOrder.getOrderCode());
-                            continue;
-                        }
-
-                        // 查询ERP订单信息
-                        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-                        request.setCode(childOrder.getExtendOrderId());
-                        ErpOrderQueryResponse response = erpOrderService.getLiveOrder(request);
-
-                        if (!response.getSuccess()) {
-                            if ("429".equals(response.getCode())) {
-                                log.warn("ERP接口限流,停止查询");
-                                break;
-                            }
-                            log.warn("查询拆分订单物流信息失败, orderCode={}, error={}", childOrder.getOrderCode(), response.getCode());
-                            continue;
-                        }
-
-                        // 更新物流信息
-                        if (response.getOrders() != null && !response.getOrders().isEmpty()) {
-                            for (ErpOrderQuery orderQuery : response.getOrders()) {
-                                if (orderQuery.getDeliverys() != null && !orderQuery.getDeliverys().isEmpty()) {
-                                    for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                                        if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-                                            // 更新订单物流信息
-                                            childOrder.setDeliverySn(delivery.getMail_no());
-                                            childOrder.setDeliveryCode(delivery.getExpress_code());
-                                            childOrder.setDeliveryName(delivery.getExpress_name());
-                                            if (childOrder.getStatus() == 2) { // 待发货状态
-                                                childOrder.setStatus(3); // 更新为待收货
-                                            }
-                                            childOrder.setUpdateTime(new Date());
-                                            liveOrderMapper.updateLiveOrder(childOrder);
-                                            log.info("拆分订单物流信息已更新, orderCode={}, deliverySn={}, expressName={}",
-                                                    childOrder.getOrderCode(), delivery.getMail_no(), delivery.getExpress_name());
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } catch (Exception e) {
-                    log.error("处理拆分订单物流信息异常, orderCode={}", splitOrder.getOrderCode(), e);
-                }
-            }
-
-            log.info("拆分订单物流信息查询完成");
-        } catch (Exception e) {
-            log.error("查询拆分订单物流信息任务异常", e);
-        }
-    }
-
-    // 聚水潭 推送售后信息
-    public void pushJst(){
-        fsJstAftersalePushScrmService.pushJst();
-    }
-
-
-    // 订单银行回调数据丢失补偿
-    public void recoveryBankOrder() {
-        // 查询出来最近15分钟的订单 待支付 未退款
-        List<LiveOrder> list = liveOrderService.selectBankOrder();
-        if(list == null || list.isEmpty()) return;
-        for (LiveOrder liveOrder : list) {
-            List<LiveOrderPayment> liveOrderPayments = liveOrderPaymentMapper.selectLiveOrderPaymentByOrderId(liveOrder.getOrderId());
-            if(liveOrderPayments == null || liveOrderPayments.isEmpty()) continue;
-            for (LiveOrderPayment payment : liveOrderPayments) {
-                V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
-                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-                request.setOrgHfSeqId(payment.getTradeNo());
-                request.setAppId(payment.getAppId());
-                HuiFuQueryOrderResult o = null;
-                try {
-                    o = huiFuService.queryOrder(request);
-                } catch (Exception e) {
-                    log.error("查询失败:"+e.getMessage());
-                    continue;
-                }
-                log.info("汇付返回"+o);
-                if ("00000000".equals(o.getResp_code()) && "S".equals(o.getTrans_stat())) {
-                    String[] order=o.getOrg_req_seq_id().split("-");
-                    if ("live".equals(order[0])) {
-                        liveOrderService.payConfirm(1, null, order[1], o.getOrg_hf_seq_id(), o.getOut_trans_id(), o.getParty_order_id());
-                    }
-                }
-            }
-        }
-    }
-
-
-    public void PushErp() throws ParseException {
-        List<Long> ids = liveOrderMapper.selectOrderIdByNoErp();
-        if(ids == null) return;
-        if (ids.size() > 50) {
-            ids = ids.subList(0, 50);
-        }
-//        liveOrderService.batchUpdateTimeIds(ids);
-        // 单个异常影响全部,跳过异常单子
-        for (Long id : ids) {
-            try {
-                liveOrderService.createOmsOrder(id);
-            } catch (Exception e) {
-                log.error("创建直播oms订单失败:"+id);
-                log.error("创建直播oms订单失败:"+e.getMessage());
-            }
-
-        }
-    }
-
-    public void redPacketSubMoney() throws Exception {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-    public void redPacketAddMoney() throws Exception {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(), redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-
-    //定时任务刷新微信订单结算状态
-    public void refreshOrderSettlementStatus(){
-        liveOrderService.refreshOrderSettlementStatus();
-    }
-
-
-
-    //每5分钟执行一次
-    public void deliveryOp() {
-        List<LiveOrder> list = liveOrderService.selectUpdateExpress();
-        if(list == null || list.isEmpty()) return;
-        Date now = new Date();
-        for (LiveOrder order : list) {
-            order.setUpdateTime(now);
-            liveOrderService.updateTime(order);
-            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-            request.setCode(order.getExtendOrderId());
-            IErpOrderService erpOrderService = getErpOrderService();
-            ErpOrderQueryResponse response = erpOrderService.getLiveOrder(request);
-            if (erpOrderService != dfOrderService) {
-                if (response.getOrders() != null && !response.getOrders().isEmpty()) {
-                    for (ErpOrderQuery orderQuery : response.getOrders()) {
-                        if (orderQuery.getDeliverys() != null && !orderQuery.getDeliverys().isEmpty()) {
-                            for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                                if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-                                    //更新商订单状态 删除REDIS
-                                    liveOrderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(), delivery.getExpress_code(), delivery.getExpress_name());
-                                    redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-    }
-
-    public void couponOp() {
-        // 直播优惠券过期处理,如果有对应方法则调用
-        // liveCouponService.updateFsCouponByExpire();
-    }
-
-    //退款自动处理 24小时未审核自动审核通过 每小时执行一次
-    public void refundOp() {
-        //获取所有退款申请
-        List<LiveAfterSales> list = liveAfterSalesService.selectLiveAfterSalesByDoAudit();
-        if (list != null) {
-            for (LiveAfterSales afterSales : list) {
-                //仅退款
-                if (afterSales.getRefundType().equals(0)) {
-                    LiveAfterSalesAudit1Param audit1Param = new LiveAfterSalesAudit1Param();
-                    audit1Param.setSalesId(afterSales.getId());
-                    audit1Param.setOperator("平台");
-                    liveAfterSalesService.audit1(audit1Param);
-                }
-            }
-        }
-    }
-
-    //每天执行一次
-    public void userMoneyOp() {
-        // 直播订单完成7天后给用户返现,如果有对应方法则调用
-        // List<LiveOrder> list = liveOrderService.selectLiveOrderListByFinish7Day();
-        // if (list != null) {
-        //     for (LiveOrder order : list) {
-        //         userService.addMoney(order);
-        //     }
-        // }
-    }
-
-    //每30秒执行一次
-    public void orderItemSyncOp() {
-//         同步订单项JSON,如果有对应方法则调用
-         List<LiveOrder> list = liveOrderService.selectLiveOrderItemJson();
-         for (LiveOrder storeOrder : list) {
-             LiveOrderItem parmOrderItem = new LiveOrderItem();
-             parmOrderItem.setOrderId(storeOrder.getOrderId());
-             List<LiveOrderItem> listOrderItem = liveOrderItemService.selectLiveOrderItemList(parmOrderItem);
-             if (listOrderItem.size() > 0) {
-                 String itemJson = JSONUtil.toJsonStr(listOrderItem);
-                 storeOrder.setItemJson(itemJson);
-                 liveOrderMapper.updateLiveOrderItemJson(storeOrder);
-             }
-         }
-    }
-
-    public void returnDeliveryId() {
-        IErpOrderService erpOrderService = getErpOrderService();
-        // 获取ERP订单号列表,如果有对应方法则调用
-        // List<String> list = liveOrderMapper.selectErpCode();
-        // for (String s : list) {
-        //     ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-        //     request.setCode(s);
-        //     ErpOrderQueryResponse response = erpOrderService.getOrder(request);
-        //     if (response.getOrders() != null && response.getOrders().size() > 0) {
-        //         for (ErpOrderQuery orderQuery : response.getOrders()) {
-        //             if (orderQuery.getDeliverys() != null && orderQuery.getDeliverys().size() > 0) {
-        //                 for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-        //                     if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-        //                         LiveOrder order = new LiveOrder();
-        //                         order.setExtendOrderId(s);
-        //                         order.setDeliverySn(delivery.getMail_no());
-        //                         order.setStatus(2);
-        //                         liveOrderMapper.updateDelivery(order);
-        //                     }
-        //                 }
-        //             }
-        //         }
-        //     }
-        // }
-    }
-
-    public void changeStatus() {
-//         获取需要更新物流状态的订单ID列表,如果有对应方法则调用
-//         List<Long> list = liveOrderMapper.selectOrderId();
-//         for (Long orderId : list) {
-//             LiveOrder order = liveOrderMapper.selectLiveOrderByOrderId(String.valueOf(orderId));
-//             String lastFourNumber = "";
-//             if (order.getDeliverySn() != null && order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
-//                 lastFourNumber = order.getUserPhone();
-//                 if (lastFourNumber != null && lastFourNumber.length() == 11) {
-//                     lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
-//                 }
-//             }
-//             ExpressInfoDTO dto = expressService.getExpressInfo(order.getOrderCode(), order.getDeliverySn(), order.getDeliverySn(), lastFourNumber);
-//             LiveOrder map = new LiveOrder();
-//             map.setDeliveryStatus(Integer.parseInt(dto.getState()));
-//             map.setOrderId(orderId);
-//             map.setDeliveryType(dto.getStateEx());
-//             liveOrderMapper.updateLiveOrder(map);
-//         }
-    }
-
-    public void subCompanyMoney() {
-        // 获取需要扣减公司金额的支付ID列表,如果有对应方法则调用
-        // List<Long> list = liveOrderPaymentMapper.selectPaymentIds();
-        // for (Long paymentId : list) {
-        //     LiveOrderPayment payment = liveOrderPaymentService.selectLiveOrderPaymentByPaymentId(paymentId);
-        //     if (payment.getCompanyId() != null && payment.getCompanyId() > 0) {
-        //         companyService.subCompanyPaymentMoney(payment);
-        //     }
-        // }
-    }
-
-    public void updateOrderItem() throws ParseException {
-//        List<Long> ids = liveOrderService.selectOrderIdByNoErp();
-//        for (Long id : ids) {
-//            liveOrderService.createOmsOrder(id);
-//        }
-    }
-
-    //每天执行一次
-    public void syncExpress() {
-        List<Long> ids = liveOrderService.selectSyncExpressIds();
-        for (Long id : ids) {
-            liveOrderService.syncExpress(id);
-        }
-    }
-
-    public void returnPayStatus() {
-        // 获取需要查询支付状态的支付ID列表,如果有对应方法则调用
-        // List<String> ids = liveOrderPaymentMapper.selectPayStatusIds();
-        // for (String id : ids) {
-        //     OrderQueryDTO o = new OrderQueryDTO();
-        //     o.setUpOrderId(id);
-        //     OrderResult orderResult = ybPayService.getOrder(o);
-        //     if ("0".equals(orderResult.getState())) {
-        //         String[] order = orderResult.getLowOrderId().split("-");
-        //         if (orderResult.getStatus().equals("100")) {
-        //             switch (order[0]) {
-        //                 case "live":
-        //                     liveOrderService.payConfirm(1, null, order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
-        //                 case "live_remain":
-        //                     liveOrderService.payConfirm(1, null, order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
-        //                 case "payment":
-        //                     liveOrderPaymentService.payConfirm(order[1], o.getUpOrderId(), orderResult.getBankTrxId(), orderResult.getBankOrderId());
-        //             }
-        //         }
-        //     }
-        // }
-    }
-
-    public void AddTuiMoney() {
-        // 获取需要添加推荐金额的订单ID列表,如果有对应方法则调用
-        // List<Long> ids = liveOrderMapper.selectAddTuiMoney();
-        // for (Long id : ids) {
-        //     FsStoreOrderAddTuiMoneyParam param = new FsStoreOrderAddTuiMoneyParam();
-        //     param.setOrderId(id);
-        //     liveOrderService.addTuiMoney(param);
-        // }
-    }
-
-    public void selectPayMoneyLessOne() {
-        // 获取支付金额小于1的订单列表,如果有对应方法则调用
-        // List<LiveOrder> list = liveOrderMapper.selectPayMoneyLessOne();
-        // for (LiveOrder order : list) {
-        //     LiveAfterSalesParam param = new LiveAfterSalesParam();
-        //     param.setOrderCode(order.getOrderCode());
-        //     param.setServiceType(0);
-        //     param.setRefundAmount(order.getPayMoney());
-        //     param.setReasons("超时未处理,自动申请退款");
-        //     List<LiveAfterSalesProductParam> productParams = new ArrayList<>();
-        //     List<LiveOrderItem> items = liveOrderItemMapper.selectLiveOrderItemByOrderId(order.getOrderId());
-        //     for (LiveOrderItem item : items) {
-        //         LiveAfterSalesProductParam param1 = new LiveAfterSalesProductParam();
-        //         param1.setProductId(item.getProductId());
-        //         param1.setNum(item.getNum());
-        //         productParams.add(param1);
-        //     }
-        //     param.setProductList(productParams);
-        //     liveAfterSalesService.applyForAfterSales(order.getUserId(), param);
-        // }
-    }
-
-    public void deleteCustomer() {
-        // 删除客户逻辑
-    }
-
-    private IErpOrderService getErpOrderService() {
-        //判断是否开启erp
-        IErpOrderService erpOrderService = null;
-        FsSysConfig erpConfig = configUtil.getSysConfig();
-        Integer erpOpen = erpConfig.getErpOpen();
-        if (erpOpen != null && erpOpen == 1) {
-            //判断erp类型
-            Integer erpType = erpConfig.getErpType();
-            if (erpType != null) {
-                if (erpType == 1) {
-                    //管易
-                    erpOrderService = gyOrderService;
-                } else if (erpType == 2) {
-                    //旺店通
-                    erpOrderService = wdtOrderService;
-                } else if (erpType == 3) {
-                    //代服
-                    erpOrderService = hzOMSOrderService;
-                } else if (erpType == 4) {
-                    //瀚智
-                    erpOrderService = dfOrderService;
-                } else if (erpType == 5) {
-                    erpOrderService = jSTOrderService;
-                } else if (erpType == 6) {
-                    erpOrderService = k9OrderService;
-                }
-            }
-        }
-        return erpOrderService;
-    }
-
-    /**
-     * 提醒证件到期任务
-     */
-    public void remindCertValidation() {
-        log.info("提醒店铺证件到期任务执行... 当前时间: {}", LocalTime.now());
-
-        // 从配置表获取需要比较的表和字段
-        List<DateComparisonConfigDTO> tablesToCheck = jdbcTemplate.query(
-                "SELECT table_name, date_column,in_advance,user_column,phone_column,remind_words,platform,cert_type" +
-                        " FROM date_comparison_config", (rs, rowNum) -> {
-                    return DateComparisonConfigDTO.builder()
-                            .tableName(rs.getString("table_name"))//表名
-                            .certType(rs.getString("cert_type"))//证件类型
-                            .dateColumn(rs.getString("date_column"))//日期字段
-                            .userColumn(rs.getString("user_column"))//用户字段
-                            .remindWords(rs.getString("remindWords"))//提醒内容
-                            .phoneColumn(rs.getString("phone_column"))//提醒手机
-                            .inAdvance(rs.getInt("inAdvance"))//提前天数
-                            .platform(rs.getString("platform")).build();//平台
-                });
-
-        tablesToCheck.forEach(dto -> {
-            //获取证件失效日期字段小于当前时间加提前天数的用户和电话号码
-            String sql = String.format("SELECT %s , %s " +
-                            "FROM %s " +
-                            "WHERE %s >= DATE_SUB(CURDATE(), INTERVAL %d DAY)",
-                    dto.getUserColumn(),
-                    dto.getPhoneColumn(),
-                    dto.getTableName(),
-                    dto.getDateColumn(),
-                    dto.getInAdvance()
-            );
-            List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
-            users.forEach(user -> {
-                String userName = (String) user.get(dto.getUserColumn());
-                String phone = (String) user.get(dto.getPhoneColumn());
-                String remindWords = String.format("【%s平台提示】尊敬的%s用户,店铺%s证件即将到期,请及时处理!",
-                        dto.getPlatform(),
-                        userName,
-                        dto.getCertType());
-                // 使用phone发送remindWords短信
-                // TODO 发送通知
-            });
-        });
-    }
-
-    /**
-     * 禁用店铺
-     */
-    public void disable() {
-        log.info("禁用店铺任务执行... 当前时间: {}", LocalTime.now());
-        // 从配置表获取需要禁用的表和字段
-        List<DateComparisonConfigDTO> toDisable = jdbcTemplate.query(
-                "SELECT table_name, date_column,invalid_expression,status_column" +
-                        " FROM date_comparison_config " +
-                        " WHERE is_do_invalid = '1'", (rs, rowNum) -> DateComparisonConfigDTO.builder()
-                        .tableName(rs.getString("table_name"))//表名
-                        .dateColumn(rs.getString("date_column"))//日期字段
-                        .invalidExpression(rs.getString("invalid_expression"))//失效表达式
-                        .statusColumn(rs.getString("status_column"))//状态字段
-                        .build());
-
-        toDisable.forEach(dto -> {
-            //更新证件失效日期字段小于当前时间的数据
-            String sql = String.format("UPDATE %s " +
-                            "SET %s = %s " +
-                            "WHERE %s < CURDATE()",
-                    dto.getTableName(),
-                    dto.getStatusColumn(),
-                    dto.getInvalidExpression(),
-                    dto.getDateColumn());
-            jdbcTemplate.update(sql);
-        });
-    }
-
-    public void getOrderDeliveryStatus() {
-        IErpOrderService erpOrderService = getErpOrderService();
-        List<LiveOrder> orders = null;
-        if (erpOrderService != null && erpOrderService == dfOrderService) {
-            // 获取已发货订单列表,如果有对应方法则调用
-             orders = liveOrderMapper.selectShippedOrder();
-             if (orders != null && !orders.isEmpty()) {
-                 List<CompletableFuture<Void>> futures = new ArrayList<>();
-                 for (LiveOrder order : orders) {
-                     CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
-                         erpOrderService.getOrderLiveDeliveryStatus(order);
-                     });
-                     futures.add(future);
-                 }
-                 CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
-             }
-        }
-    }
-}

+ 0 - 713
fs-service/src/main/java/com/fs/hisStore/task/MallStoreTask.java

@@ -1,713 +0,0 @@
-package com.fs.hisStore.task;
-
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
-import com.fs.common.core.domain.R;
-import com.fs.common.core.redis.RedisCache;
-import com.fs.common.utils.DateUtils;
-import com.fs.company.service.ICompanyService;
-import com.fs.company.vo.RedPacketMoneyVO;
-import com.fs.course.mapper.FsCourseRedPacketLogMapper;
-import com.fs.erp.domain.ErpDeliverys;
-import com.fs.erp.domain.ErpGoods;
-import com.fs.erp.domain.ErpOrderQuery;
-import com.fs.erp.dto.ErpGoodsQueryRequert;
-import com.fs.erp.dto.ErpGoodsQueryResponse;
-import com.fs.erp.dto.ErpOrderQueryRequert;
-import com.fs.erp.dto.ErpOrderQueryResponse;
-import com.fs.erp.service.IErpGoodsService;
-import com.fs.erp.service.IErpOrderService;
-import com.fs.his.config.FsSysConfig;
-import com.fs.his.domain.FsStoreProductAttrValue;
-import com.fs.his.dto.ExpressInfoDTO;
-import com.fs.his.mapper.FsStoreProductAttrValueMapper;
-import com.fs.his.service.IFsExpressService;
-import com.fs.his.service.IFsUserService;
-import com.fs.his.utils.ConfigUtil;
-import com.fs.hisStore.domain.*;
-import com.fs.hisStore.dto.DateComparisonConfigDTO;
-import com.fs.hisStore.enums.ShipperCodeEnum;
-import com.fs.hisStore.mapper.FsStoreOrderItemScrmMapper;
-import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
-import com.fs.hisStore.mapper.FsStorePaymentScrmMapper;
-import com.fs.hisStore.mapper.FsStoreProductAttrValueScrmMapper;
-import com.fs.hisStore.param.*;
-import com.fs.hisStore.service.*;
-import com.fs.huifuPay.domain.HuiFuQueryOrderResult;
-import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayQueryRequest;
-import com.fs.huifuPay.service.HuiFuService;
-import com.fs.live.domain.LiveOrder;
-import com.fs.live.domain.LiveOrderPayment;
-import com.fs.pay.pay.dto.OrderQueryDTO;
-import com.fs.pay.service.IPayService;
-import com.fs.store.config.StoreConfig;
-import com.fs.system.service.ISysConfigService;
-import com.fs.ybPay.domain.OrderResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.stereotype.Component;
-
-import java.math.BigDecimal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.LocalTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-import static com.fs.hisStore.constants.StoreConstants.DELIVERY;
-
-/**
- * 定时任务调度测试
- *
- * @author fs
- */
-@Component("mallStoreTask")
-public class MallStoreTask
-{
-    private static final Logger log = LoggerFactory.getLogger(MallStoreTask.class);
-    @Autowired
-    private RedisTemplate redisTemplate;
-    @Autowired
-    private RedisCache redisCache;
-    @Autowired
-    private IFsStoreOrderScrmService orderService;
-    @Autowired
-    private IFsStoreCouponUserScrmService couponUserService;
-    @Autowired
-    private IFsStoreAfterSalesScrmService afterSalesService;
-    @Autowired
-    private IFsUserService userService;
-    @Autowired
-    private IPayService ybPayService;
-    @Autowired
-    private FsStoreOrderScrmMapper fsStoreOrderMapper;
-
-    @Autowired
-    private IFsStoreOrderScrmService fsStoreOrderService;
-
-    @Autowired
-    private IFsStoreOrderItemScrmService storeOrderItemService;
-
-    @Autowired
-    private FsStorePaymentScrmMapper fsStorePaymentMapper;
-
-
-    @Autowired
-    private IErpGoodsService erpGoodsService;
-    @Autowired
-    private ISysConfigService configService;
-    @Autowired
-    private FsStoreProductAttrValueMapper fsStoreProductAttrValueMapper;
-    @Autowired
-    private FsStorePaymentScrmMapper paymentMapper;
-    @Autowired
-    private IFsStorePaymentScrmService fsStorePaymentService;
-    @Autowired
-    private ICompanyService companyService;
-
-
-    @Autowired
-    private IFsExpressService expressService;
-
-    @Autowired
-    private FsStoreOrderItemScrmMapper itemMapper;
-
-    @Autowired
-    private IFsStoreAfterSalesScrmService fsStoreAfterSalesService;
-
-    @Autowired
-    @Qualifier("erpOrderServiceImpl")
-    private IErpOrderService gyOrderService;
-
-    @Autowired
-    @Qualifier("wdtErpOrderServiceImpl")
-    private IErpOrderService wdtOrderService;
-
-    @Autowired
-    @Qualifier("hzOMSErpOrderServiceImpl")
-    private IErpOrderService hzOMSOrderService;
-
-    @Autowired
-    @Qualifier("dfOrderServiceImpl")
-    private IErpOrderService dfOrderService;
-
-    @Autowired
-    @Qualifier("JSTErpOrderServiceImpl")
-    private IErpOrderService jSTOrderService;
-
-    @Autowired
-    @Qualifier("k9OrderScrmServiceImpl")
-    private IErpOrderService k9OrderService;
-
-    @Autowired
-    private ConfigUtil configUtil;
-
-    @Autowired
-    private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
-
-
-    @Autowired
-    IErpOrderService erpOrderService;
-
-    //@Autowired
-    //private IFsUserWatchCourseStatisticsService fsUserWatchCourseStatisticsService;
-
-    //@Autowired
-    //private IFsUserWatchStatisticsService fsUserWatchStatisticsService;
-
-    //@Autowired
-    //private IFsUserOnlineStateService fsUserOnlineStateService;
-    @Autowired
-    private HuiFuService huiFuService;
-
-    // 订单银行回调数据丢失补偿
-    public void recoveryBankOrder() {
-        // 查询出来最近30分钟的订单 待支付 未退款
-        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectBankOrder();
-        if(list == null || list.isEmpty()) return;
-        for (FsStoreOrderScrm order : list) {
-            List<FsStorePaymentScrm> orderPayments = fsStorePaymentMapper.selectNoPayByOrderId(order.getId());
-            if(orderPayments == null || orderPayments.isEmpty()) continue;
-            for (FsStorePaymentScrm payment : orderPayments) {
-                V2TradePaymentScanpayQueryRequest request = new V2TradePaymentScanpayQueryRequest();
-                request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
-                request.setOrgHfSeqId(payment.getTradeNo());
-                request.setAppId(payment.getAppId());
-                HuiFuQueryOrderResult o = null;
-                try {
-                    o = huiFuService.queryOrder(request);
-                } catch (Exception e) {
-                    log.error("查询失败:"+e.getMessage());
-                    continue;
-                }
-                log.info("汇付返回"+o);
-                if ("00000000".equals(o.getResp_code()) && "S".equals(o.getTrans_stat())) {
-                    String[] orderSpilt=o.getOrg_req_seq_id().split("-");
-                    if ("store".equals(orderSpilt[0])) {
-                        orderService.payConfirm(1, null, orderSpilt[1], o.getOrg_hf_seq_id(), o.getOut_trans_id(), o.getParty_order_id());
-                    }
-                }
-            }
-        }
-    }
-
-    public void PushErp() throws ParseException {
-        List<Long> ids;
-        // 开启审核
-        if (getAuditSwitch()) {
-            ids = fsStoreOrderMapper.selectFsStoreOrderNoCreateOmsAndReviewed();
-        } else {
-            ids = fsStoreOrderMapper.selectFsStoreOrderNoCreateOms();
-        }
-        if (!ids.isEmpty() && ids.size() > 50) {
-            ids = ids.subList(0, 50);
-        }
-        // 单个异常影响全部,跳过异常单子
-        for (Long id : ids) {
-            try {
-                R omsOrder = fsStoreOrderService.createOmsOrder(id);
-                if ("500".equals(omsOrder.get("code"))) {
-
-                }
-            } catch (Exception e) {
-                log.error("创建商城oms订单失败:"+id);
-                log.error("创建商城oms订单失败:"+e.getMessage());
-            }
-
-        }
-    }
-
-    /**
-     * 获取是否需要订单审核
-     * @return boolean
-     */
-    private boolean getAuditSwitch() {
-        try {
-            String json = configService.selectConfigByKey("store.config");
-            StoreConfig config = JSONUtil.toBean(json,StoreConfig.class);
-            return config.getAuditSwitch() == 1;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    public void redPacketSubMoney() throws Exception
-    {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.subtractCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-    public void redPacketAddMoney() throws Exception
-    {
-        List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
-        for (RedPacketMoneyVO redPacketMoneyVO : redPacketMoneyVOS) {
-            companyService.addRedPacketCompanyMoney(redPacketMoneyVO.getMoney(),redPacketMoneyVO.getCompanyId());
-        }
-    }
-
-    //每5分钟执行一次
-    public void deliveryOp()
-    {
-        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectUpdateExpress();
-        Date nowDate = DateUtils.getNowDate();
-        for (FsStoreOrderScrm order : list){
-            order.setUpdateTime(new Date());
-            orderService.updateFsStoreOrderDb(order);
-            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-            request.setCode(order.getExtendOrderId());
-            IErpOrderService erpOrderService = getErpOrderService();
-            ErpOrderQueryResponse response = erpOrderService.getScrmOrder(request);
-            if (erpOrderService != dfOrderService) {
-                if(response.getOrders()!=null && !response.getOrders().isEmpty()){
-                    for(ErpOrderQuery orderQuery : response.getOrders()){
-                        if (orderQuery.getDeliverys() != null && !orderQuery.getDeliverys().isEmpty()) {
-                            for (ErpDeliverys delivery : orderQuery.getDeliverys()) {
-                                if (delivery.getDelivery() && StringUtils.isNotEmpty(delivery.getMail_no())) {
-                                    //更新商订单状态 删除REDIS
-                                    orderService.deliveryOrder(order.getOrderCode(), delivery.getMail_no(), delivery.getExpress_code(), delivery.getExpress_name());
-                                    redisCache.deleteObject(DELIVERY + ":" + order.getExtendOrderId());
-                                }
-                            }
-
-                        }
-                    }
-
-                }
-            }
-        }
-
-    }
-
-
-    //定时任务刷新微信订单结算状态
-    public void refreshOrderSettlementStatus(){
-        fsStoreOrderService.refreshOrderSettlementStatus();
-    }
-
-
-    public void storeProdUpdateCostPrice()
-    {
-        String json=configService.selectConfigByKey("store.config");
-        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
-
-        List<FsStoreProductAttrValue> values = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueList(new FsStoreProductAttrValue());
-        for (FsStoreProductAttrValue value : values) {
-            ErpGoodsQueryRequert query = new ErpGoodsQueryRequert();
-            query.setCode(value.getBarCode());
-            ErpGoodsQueryResponse goods = erpGoodsService.getGoods(query);
-            List<ErpGoods> items = goods.getItems();
-
-            if (items!=null&&items.size()>0){
-                ErpGoods erpGoods = items.get(0);
-                BigDecimal salesPrice = erpGoods.getSales_price();
-                if (salesPrice!=null&&salesPrice.compareTo(BigDecimal.ZERO) != 0){
-                    BigDecimal divide = salesPrice.multiply(new BigDecimal(config.getSalesPriceRate())).divide(new BigDecimal("100"));
-                    System.out.println("代理价格"+divide);
-                    System.out.println("成本价"+salesPrice);
-                    FsStoreProductAttrValue va = new FsStoreProductAttrValue();
-                    va.setCost(salesPrice);
-                    va.setAgentPrice(divide);
-                    va.setId(value.getId());
-                    fsStoreProductAttrValueMapper.updateFsStoreProductAttrValue(va);
-                }
-            }
-            System.out.println(goods);
-        }
-    }
-
-
-    @Autowired
-    private FsStoreProductAttrValueScrmMapper fsStoreProductAttrValueScrmMapper;
-
-    public void storeProdUpdateCostPriceScrm()
-    {
-        String json=configService.selectConfigByKey("store.config");
-        StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
-
-        List<FsStoreProductAttrValueScrm> values = fsStoreProductAttrValueScrmMapper.selectFsStoreProductAttrValueList(new FsStoreProductAttrValueScrm());
-        for (FsStoreProductAttrValueScrm value : values) {
-            ErpGoodsQueryRequert query = new ErpGoodsQueryRequert();
-            query.setCode(value.getBarCode());
-            ErpGoodsQueryResponse goods = erpGoodsService.getGoodsScrm(query);
-            List<ErpGoods> items = goods.getItems();
-
-            if (items!=null&&items.size()>0){
-                ErpGoods erpGoods = items.get(0);
-                BigDecimal salesPrice = erpGoods.getSales_price();
-                if (salesPrice!=null&&salesPrice.compareTo(BigDecimal.ZERO) != 0){
-                    BigDecimal divide = salesPrice.multiply(new BigDecimal(config.getSalesPriceRate())).divide(new BigDecimal("100"));
-                    System.out.println("代理价格"+divide);
-                    System.out.println("成本价"+salesPrice);
-                    FsStoreProductAttrValueScrm va = new FsStoreProductAttrValueScrm();
-                    va.setCost(salesPrice);
-                    va.setAgentPrice(divide);
-                    va.setId(value.getId());
-                    fsStoreProductAttrValueScrmMapper.updateFsStoreProductAttrValue(va);
-                }
-            }
-            System.out.println(goods);
-        }
-    }
-    public void couponOp()
-    {
-        couponUserService.updateFsCouponByExpire();
-
-    }
-
-
-    //退款自动处理 24小时未审核自动审核通过 每小时执行一次
-    public void refundOp()
-    {
-        //获取所有退款申请
-        List<FsStoreAfterSalesScrm> list=afterSalesService.selectFsStoreAfterSalesByDoAudit();
-        if(list!=null){
-            for(FsStoreAfterSalesScrm afterSales:list){
-                //仅退款
-                if(afterSales.getServiceType().equals(0)){
-                    FsStoreAfterSalesAudit1Param audit1Param=new FsStoreAfterSalesAudit1Param();
-                    audit1Param.setSalesId(afterSales.getId());
-                    audit1Param.setOperator("平台");
-                    afterSalesService.audit1(audit1Param);
-                }
-            }
-        }
-    }
-
-
-    //每天执行一次
-    public void userMoneyOp()
-    {
-        List<FsStoreOrderScrm> list=orderService.selectFsStoreOrderListByFinish7Day();
-        if(list!=null){
-            for(FsStoreOrderScrm order:list){
-                userService.addMoney(order);
-            }
-        }
-    }
-
-
-    //每30秒执行一次
-    public void orderItemSyncOp(){
-        List<FsStoreOrderScrm> list = fsStoreOrderService.selectFsStoreOrderItemJson();
-        for(FsStoreOrderScrm storeOrder:list){
-            FsStoreOrderItemScrm parmOrderItem=new FsStoreOrderItemScrm();
-            parmOrderItem.setOrderId(storeOrder.getId());
-            List<FsStoreOrderItemScrm> listOrderItem=storeOrderItemService.selectFsStoreOrderItemList(parmOrderItem);
-            if(listOrderItem.size()>0){
-                String itemJson= JSONUtil.toJsonStr(listOrderItem);
-                storeOrder.setItemJson(itemJson);
-                fsStoreOrderMapper.uploadItemJson(storeOrder);
-            }
-        }
-    }
-
-    public void returnDeliveryId(){
-        IErpOrderService erpOrderService = getErpOrderService();
-        List<String> list = fsStoreOrderMapper.selectErpCode();
-        for (String s : list) {
-            ErpOrderQueryRequert request = new ErpOrderQueryRequert();
-            request.setCode(s);
-            ErpOrderQueryResponse response = erpOrderService.getOrder(request);
-            if(response.getOrders()!=null&&response.getOrders().size()>0){
-                    for(ErpOrderQuery orderQuery : response.getOrders()){
-                        if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
-                            for(ErpDeliverys delivery:orderQuery.getDeliverys()){
-                                if(delivery.getDelivery()&&StringUtils.isNotEmpty(delivery.getMail_no())){
-                                    FsStoreOrderScrm order = new FsStoreOrderScrm();
-                                    order.setExtendOrderId(s);
-                                    order.setDeliveryId(delivery.getMail_no());
-                                    order.setStatus(2);
-                                    fsStoreOrderMapper.updateDelivery(order);
-                                }
-                            }
-                        }
-                    }
-                }
-
-
-        }
-
-    }
-
-    public void changeStatus(){
-        List<Long> list  = fsStoreOrderMapper.selectOrderId();
-        for (Long orderId : list){
-            FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
-            String lastFourNumber = "";
-            if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())  || order.getDeliverySn().equals(ShipperCodeEnum.ZTO.getValue())) {
-                lastFourNumber = order.getUserPhone();
-                if (lastFourNumber.length() == 11) {
-                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
-                }
-            }
-            ExpressInfoDTO dto=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
-            FsStoreOrderScrm map=new FsStoreOrderScrm();
-            map.setDeliveryStatus(Integer.parseInt(dto.getState()));
-            map.setId(order.getId());
-            map.setDeliveryType(dto.getStateEx());
-            fsStoreOrderMapper.updateFsStoreOrder(map);
-        }
-    }
-
-
-
-    public void subCompanyMoney(){
-        List<Long> list = paymentMapper.selectPaymentIds();
-        for (Long paymentId : list){
-            FsStorePaymentScrm payment=fsStorePaymentService.selectFsStorePaymentById(paymentId);
-            if(payment.getCompanyId()!=null&&payment.getCompanyId()>0){
-                companyService.subCompanyPaymentMoney(payment);
-            }
-        }
-    }
-
-
-    public void updateOrderItem() throws ParseException {
-        List <Long> ids = itemMapper.selectOrderIdByNoErp();
-        for (Long id:ids){
-            fsStoreOrderService.createOmsOrder(id);
-        }
-    }
-
-
-
-    //每天执行一次
-    public void syncExpress()
-    {
-        List<Long> ids =fsStoreOrderMapper.selectSyncExpressIdsNoDate();
-
-        for (Long id : ids) {
-            FsStoreOrderExpressEditParam param =new FsStoreOrderExpressEditParam();
-            param.setOrderId(id);
-            fsStoreOrderService.syncExpress(param);
-        }
-
-    }
-
-    public void returnPayStatus() {
-        List<String> ids =fsStorePaymentMapper.selectPayStatusIds();
-        for (String id : ids) {
-            OrderQueryDTO o = new OrderQueryDTO();
-            o.setUpOrderId(id);
-            OrderResult orderResult = ybPayService.getOrder(o);
-            if ("0".equals(orderResult.getState())){
-                String[] order=orderResult.getLowOrderId().split("-");
-                if(orderResult.getStatus().equals("100")){
-                    switch (order[0]) {
-                        case "store":
-                            orderService.payConfirm(1,null,order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
-                        case "store_remain":
-                            orderService.payRemainConfirm( order[1], o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
-                        case "payment":
-                            fsStorePaymentService.payConfirm(order[1],o.getUpOrderId(),orderResult.getBankTrxId(),orderResult.getBankOrderId());
-                    }
-
-                }
-            }
-
-        }
-
-    }
-
-    public void AddTuiMoney()
-    {
-        List<Long> ids =fsStoreOrderMapper.selectAddTuiMoney();
-        for (Long id : ids) {
-            FsStoreOrderAddTuiMoneyParam param = new FsStoreOrderAddTuiMoneyParam();
-            param.setOrderId(id);
-            fsStoreOrderService.addTuiMoney(param);
-        }
-
-    }
-
-
-    public void selectPayMoneyLessOne(){
-        List<FsStoreOrderScrm> list = fsStoreOrderMapper.selectPayMoneyLessOne();
-        for (FsStoreOrderScrm order : list){
-            FsStoreAfterSalesParam param = new FsStoreAfterSalesParam();
-            param.setOrderCode(order.getOrderCode());
-            param.setServiceType(0);
-            param.setRefundAmount(order.getPayMoney());
-            param.setReasons("超时未处理,自动申请退款");
-            List<FsStoreAfterSalesProductParam> productParams = new ArrayList<>();
-            List <FsStoreOrderItemScrm> items = fsStoreOrderMapper.selectOrderItem(order.getId());
-            for (FsStoreOrderItemScrm item : items){
-                FsStoreAfterSalesProductParam param1 = new FsStoreAfterSalesProductParam();
-                param1.setProductId(item.getProductId());
-                param1.setNum(item.getNum());
-                productParams.add(param1);
-            }
-            param.setProductList(productParams);
-            fsStoreAfterSalesService.autoApplyForAfterSales(order.getUserId(),param);
-        }
-    }
-
-    public  void deleteCustomer(){
-
-    }
-
-    private IErpOrderService getErpOrderService(){
-        //判断是否开启erp
-        IErpOrderService erpOrderService = null;
-        FsSysConfig erpConfig = configUtil.getSysConfig();
-        Integer erpOpen = erpConfig.getErpOpen();
-        if (erpOpen != null && erpOpen == 1) {
-            //判断erp类型
-            Integer erpType = erpConfig.getErpType();
-            if (erpType != null) {
-                if (erpType == 1) {
-                    //管易
-                    erpOrderService = gyOrderService;
-                } else if (erpType == 2) {
-                    //旺店通
-                    erpOrderService = wdtOrderService;
-                } else if (erpType == 3) {
-                    //代服
-                    erpOrderService = hzOMSOrderService;
-                } else if (erpType == 4) {
-                    //瀚智
-                    erpOrderService = dfOrderService;
-                } else if (erpType == 5) {
-                    erpOrderService = jSTOrderService;
-                }else if (erpType == 6) {
-                    erpOrderService = k9OrderService;
-                }
-            }
-        }
-        return erpOrderService;
-    }
-
-    /**
-     * 添加看课汇总统计
-     */
-    /*public void insertWatchStatistics(){
-        *//***************************************进入营期会员看课汇总统计定时任务****************************************//*
-        fsUserWatchStatisticsService.insertStatistics();
-        *//***************************************营期会员看课汇总统计定时任务结束***************************************//*
-    }*/
-
-    /**
-     * 添加看课明细统计
-     */
-    /*public void insertWatchCourseStatistics(){
-        *//***************************************进入营期会员看课明细统计定时任务*******************************//*
-        fsUserWatchCourseStatisticsService.insertWatchCourseStatistics();
-        *//***************************************进入营期会员看课明细统计定时任务结束**********************************************//*
-    }*/
-
-    /**
-     * 定时查询未上线的用户
-     */
-    /*public void insertUserNotOnline(){
-        fsUserOnlineStateService.insertUserNotOnline();
-    }*/
-
-    /**
-     * 提醒证件到期任务
-     * */
-    @Autowired
-    private JdbcTemplate jdbcTemplate;
-    public void remindCertValidation() {
-        log.info("提醒店铺证件到期任务执行... 当前时间: {}", LocalTime.now());
-
-        // 从配置表获取需要比较的表和字段
-        List<DateComparisonConfigDTO> tablesToCheck = jdbcTemplate.query(
-                "SELECT table_name, date_column,in_advance,user_column,phone_column,remind_words,platform,cert_type" +
-                        " FROM date_comparison_config",(rs, rowNum)->{
-                    return DateComparisonConfigDTO.builder()
-                            .tableName(rs.getString("table_name"))//表名
-                            .certType(rs.getString("cert_type"))//证件类型
-                            .dateColumn(rs.getString("date_column"))//日期字段
-                            .userColumn(rs.getString("user_column"))//用户字段
-                            .remindWords(rs.getString("remindWords"))//提醒内容
-                            .phoneColumn(rs.getString("phone_column"))//提醒手机
-                            .inAdvance(rs.getInt("inAdvance"))//提前天数
-                            .platform(rs.getString("platform")).build();//平台
-                });
-
-        tablesToCheck.forEach(dto -> {
-            //获取证件失效日期字段小于当前时间加提前天数的用户和电话号码
-            String sql = String.format("SELECT %s , %s " +
-                            "FROM %s " +
-                            "WHERE %s >= DATE_SUB(CURDATE(), INTERVAL %d DAY)",
-                            dto.getUserColumn(),
-                            dto.getPhoneColumn(),
-                            dto.getTableName(),
-                            dto.getDateColumn(),
-                            dto.getInAdvance()
-                            );
-            List<Map<String, Object>> users = jdbcTemplate.queryForList(sql);
-            users.forEach(user -> {
-                String userName = (String) user.get(dto.getUserColumn());
-                String phone = (String) user.get(dto.getPhoneColumn());
-                String remindWords = String.format("【%s平台提示】尊敬的%s用户,店铺%s证件即将到期,请及时处理!",
-                        dto.getPlatform(),
-                        userName,
-                        dto.getCertType());
-                // 使用phone发送remindWords短信
-                // TODO 发送通知
-            });
-        });
-
-    }
-
-    /**
-     * 禁用店铺
-     * */
-    public void disable() {
-        log.info("禁用店铺任务执行... 当前时间: {}", LocalTime.now());
-        // 从配置表获取需要禁用的表和字段
-        List<DateComparisonConfigDTO> toDisable = jdbcTemplate.query(
-                "SELECT table_name, date_column,invalid_expression,status_column" +
-                        " FROM date_comparison_config " +
-                        " WHERE is_do_invalid = '1'",(rs, rowNum)-> DateComparisonConfigDTO.builder()
-                                .tableName(rs.getString("table_name"))//表名
-                                .dateColumn(rs.getString("date_column"))//日期字段
-                                .invalidExpression(rs.getString("invalid_expression"))//失效表达式
-                                .statusColumn(rs.getString("status_column"))//状态字段
-                                .build());
-
-        toDisable.forEach(dto -> {
-            //更新证件失效日期字段小于当前时间的数据
-            String sql = String.format("UPDATE %s " +
-                    "SET %s = %s " +
-                    "WHERE %s < CURDATE()",
-                    dto.getTableName(),
-                    dto.getStatusColumn(),
-                    dto.getInvalidExpression(),
-                    dto.getDateColumn());
-            jdbcTemplate.update(sql);
-        });
-    }
-
-    public void getOrderDeliveryStatus()
-    {
-        IErpOrderService erpOrderService = getErpOrderService();
-        List<FsStoreOrderScrm> orders = null;
-        if (erpOrderService != null && erpOrderService == dfOrderService) {
-            orders = fsStoreOrderMapper.selectShippedOrder();
-            if (orders != null && !orders.isEmpty()) {
-                List<CompletableFuture<Void>> futures = new ArrayList<>();
-                for (FsStoreOrderScrm order : orders) {
-                    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
-                        erpOrderService.getOrderScrmDeliveryStatus(order);
-                    });
-                    futures.add(future);
-                }
-                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
-            }
-        }
-    }
-
-}

+ 0 - 19
fs-service/src/main/java/com/fs/hisStore/task/stats/FsStatsMemberDailyTask.java

@@ -1,19 +0,0 @@
-package com.fs.hisStore.task.stats;
-
-import com.fs.statis.service.IFsStatsMemberDailyService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class FsStatsMemberDailyTask {
-    private static final Logger log = LoggerFactory.getLogger(FsStatsMemberDailyTask.class);
-
-    @Autowired
-    private IFsStatsMemberDailyService fsStatsMemberDailyService;
-
-    public void refreshMemberDailyData() {
-        fsStatsMemberDailyService.refreshMemberDailyData();
-    }
-}

+ 3 - 7
fs-service/src/main/java/com/fs/proxy/service/impl/PlatformStatisticsServiceImpl.java

@@ -15,13 +15,12 @@ import com.fs.proxy.mapper.PlatformStatisticsMapper;
 import com.fs.proxy.service.PlatformStatisticsService;
 import com.fs.proxy.service.TenantConsumeService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
  * 平台统计统一Service实现
- * 
+ *
  * @author fs
  * @date 2024-01-01
  */
@@ -50,7 +49,6 @@ public class PlatformStatisticsServiceImpl implements PlatformStatisticsService
 
     /** 每小时整点执行 */
     @Override
-    @Scheduled(cron = "0 0 * * * ?")
     @Transactional(rollbackFor = Exception.class)
     public void executeHourlyStats() {
         Calendar cal = Calendar.getInstance();
@@ -99,7 +97,6 @@ public class PlatformStatisticsServiceImpl implements PlatformStatisticsService
 
     /** 每日凌晨1点汇总小时→日报 */
     @Override
-    @Scheduled(cron = "0 0 1 * * ?")
     @Transactional(rollbackFor = Exception.class)
     public void executeDailySummary() {
         Calendar cal = Calendar.getInstance();
@@ -118,7 +115,7 @@ public class PlatformStatisticsServiceImpl implements PlatformStatisticsService
         Map<String, PlatformStatistics> dailyMap = new HashMap<>();
         for (PlatformStatistics h : hourList) {
             String key = buildKey(h.getStatDimension(), h.getProxyId(), h.getTenantId(), h.getConsumeType());
-            dailyMap.computeIfAbsent(key, k -> newStat("DAY", statDate, null, 
+            dailyMap.computeIfAbsent(key, k -> newStat("DAY", statDate, null,
                 h.getStatDimension(), h.getProxyId(), h.getTenantId(), h.getConsumeType()));
             merge(dailyMap.get(key), h);
         }
@@ -134,7 +131,6 @@ public class PlatformStatisticsServiceImpl implements PlatformStatisticsService
 
     /** 每月1号凌晨2点汇总日→月 */
     @Override
-    @Scheduled(cron = "0 0 2 1 * ?")
     @Transactional(rollbackFor = Exception.class)
     public void executeMonthlySummary() {
         Calendar cal = Calendar.getInstance();
@@ -288,4 +284,4 @@ public class PlatformStatisticsServiceImpl implements PlatformStatisticsService
         c.set(Calendar.MILLISECOND, 0);
         return new java.sql.Date(c.getTimeInMillis());
     }
-}
+}

+ 0 - 135
fs-service/src/main/java/com/fs/proxy/task/AccountFeeTask.java

@@ -1,135 +0,0 @@
-package com.fs.proxy.task;
-
-import com.fs.proxy.domain.TenantBalance;
-import com.fs.proxy.domain.TenantConsumeRecord;
-import com.fs.proxy.enums.ConsumeTypeEnum;
-import com.fs.proxy.mapper.TenantBalanceMapper;
-import com.fs.proxy.mapper.TenantConsumeRecordMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.math.BigDecimal;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * 账户费定时扣费任务
- * 每月1号凌晨执行,扣除租户账户费
- */
-@Component
-@Slf4j
-public class AccountFeeTask {
-
-    @Autowired
-    private TenantBalanceMapper balanceMapper;
-
-    @Autowired
-    private TenantConsumeRecordMapper recordMapper;
-
-    /**
-     * 账户费标准:50元/月
-     */
-    private static final BigDecimal ACCOUNT_FEE = new BigDecimal("50");
-
-    /**
-     * 每月1号凌晨1:00执行账户费扣费
-     * cron表达式:秒 分 时 日 月 周
-     */
-    @Scheduled(cron = "0 0 1 1 * ?")
-    @Transactional(rollbackFor = Exception.class)
-    public void deductAccountFee() {
-        log.info("开始执行账户费定时扣费任务");
-        
-        try {
-            // 查询所有租户余额记录
-            List<TenantBalance> balances = balanceMapper.selectList(null);
-            
-            for (TenantBalance balance : balances) {
-                Long tenantId = balance.getTenantId();
-                String tenantName = balance.getTenantName();
-                BigDecimal beforeBalance = balance.getTotalBalance();
-                
-                // 判断余额是否足够
-                if (beforeBalance.compareTo(ACCOUNT_FEE) < 0) {
-                    log.warn("租户 {} (ID: {}) 余额不足,账户费扣费失败,当前余额: {}", 
-                            tenantName, tenantId, beforeBalance);
-                    // 记录失败记录
-                    recordFailure(tenantId, tenantName, beforeBalance, "余额不足");
-                    continue;
-                }
-                
-                // 扣除账户费
-                BigDecimal afterBalance = beforeBalance.subtract(ACCOUNT_FEE);
-                balance.setTotalBalance(afterBalance);
-                balance.setTotalConsume(balance.getTotalConsume().add(ACCOUNT_FEE));
-                
-                // 更新余额
-                int updateResult = balanceMapper.updateBalance(balance);
-                if (updateResult <= 0) {
-                    log.error("租户 {} (ID: {}) 余额更新失败", tenantName, tenantId);
-                    continue;
-                }
-                
-                // 创建消费记录
-                TenantConsumeRecord record = new TenantConsumeRecord();
-                record.setTenantId(tenantId);
-                record.setTenantName(tenantName);
-                record.setConsumeType(ConsumeTypeEnum.ACCOUNT_FEE.getCode());
-                record.setConsumeTypeName(ConsumeTypeEnum.ACCOUNT_FEE.getName());
-                record.setAmount(ACCOUNT_FEE);
-                record.setUnitPrice(ACCOUNT_FEE);
-                record.setQuantity(1);
-                record.setBeforeBalance(beforeBalance);
-                record.setAfterBalance(afterBalance);
-                record.setOrderNo(UUID.randomUUID().toString().replace("-", "").substring(0, 20));
-                record.setStatus(1);
-                record.setConsumeTime(new Date());
-                record.setRemark("账户费自动扣除(月费)");
-                
-                int insertResult = recordMapper.insertTenantConsumeRecord(record);
-                if (insertResult <= 0) {
-                    log.error("租户 {} (ID: {}) 消费记录插入失败", tenantName, tenantId);
-                }
-                
-                log.info("租户 {} (ID: {}) 账户费扣费成功,扣除金额: {}, 扣费前余额: {}, 扣费后余额: {}", 
-                        tenantName, tenantId, ACCOUNT_FEE, beforeBalance, afterBalance);
-            }
-            
-            log.info("账户费定时扣费任务执行完成");
-            
-        } catch (Exception e) {
-            log.error("账户费定时扣费任务执行异常", e);
-        }
-    }
-
-    /**
-     * 记录扣费失败记录
-     */
-    private void recordFailure(Long tenantId, String tenantName, BigDecimal beforeBalance, String failReason) {
-        TenantConsumeRecord record = new TenantConsumeRecord();
-        record.setTenantId(tenantId);
-        record.setTenantName(tenantName);
-        record.setConsumeType(ConsumeTypeEnum.ACCOUNT_FEE.getCode());
-        record.setConsumeTypeName(ConsumeTypeEnum.ACCOUNT_FEE.getName());
-        record.setAmount(ACCOUNT_FEE);
-        record.setUnitPrice(ACCOUNT_FEE);
-        record.setQuantity(1);
-        record.setBeforeBalance(beforeBalance);
-        record.setAfterBalance(beforeBalance);
-        record.setOrderNo(UUID.randomUUID().toString().replace("-", "").substring(0, 20));
-        record.setStatus(0); // 0表示失败
-        record.setFailReason(failReason);
-        record.setConsumeTime(new Date());
-        record.setRemark("账户费自动扣除(月费)");
-        
-        try {
-            recordMapper.insertTenantConsumeRecord(record);
-        } catch (Exception e) {
-            log.error("记录扣费失败记录异常,tenantId: {}", tenantId, e);
-        }
-    }
-}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor