Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master' into master

chenkening před 4 roky
rodič
revize
7f92febe7d
100 změnil soubory, kde provedl 6264 přidání a 0 odebrání
  1. 7 0
      .gitignore
  2. 0 0
      derby.log
  3. 104 0
      pom.xml
  4. 115 0
      report-core/pom.xml
  5. 27 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/ReportApplication.java
  6. 25 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/base/BaseController.java
  7. 15 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/base/BaseService.java
  8. 68 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/code/ResponseCode.java
  9. 29 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/config/BusinessAutoConfiguration.java
  10. 14 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/constant/BusinessConstant.java
  11. 64 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/ReportDashboardController.java
  12. 51 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/dto/ChartDto.java
  13. 55 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/dto/ReportDashboardDto.java
  14. 32 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/dto/ReportDashboardObjectDto.java
  15. 20 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/param/ReportDashboardParam.java
  16. 16 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/dao/ReportDashboardMapper.java
  17. 58 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/dao/entity/ReportDashboard.java
  18. 26 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/ChartStrategy.java
  19. 38 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/ReportDashboardService.java
  20. 81 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/BarChartServiceImpl.java
  21. 108 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/BarLineChartServiceImpl.java
  22. 43 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/GaugeChartServiceImpl.java
  23. 52 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/PieChartServiceImpl.java
  24. 314 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/ReportDashboardServiceImpl.java
  25. 47 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/util/DateUtil.java
  26. 28 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/controller/dto/ReportDashboardWidgetDto.java
  27. 42 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/controller/dto/ReportDashboardWidgetValueDto.java
  28. 20 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/controller/param/ReportDashboardWidgetParam.java
  29. 16 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/dao/ReportDashboardWidgetMapper.java
  30. 45 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/dao/entity/ReportDashboardWidget.java
  31. 21 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/service/ReportDashboardWidgetService.java
  32. 34 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/service/impl/ReportDashboardWidgetServiceImpl.java
  33. 149 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/DataSetController.java
  34. 58 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/dto/DataSetDto.java
  35. 32 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/dto/OriginalDataDto.java
  36. 30 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/param/DataSetParam.java
  37. 34 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/param/DataSetTestTransformParam.java
  38. 16 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/dao/DataSetMapper.java
  39. 45 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/dao/entity/DataSet.java
  40. 70 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/service/DataSetService.java
  41. 343 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/service/impl/DataSetServiceImpl.java
  42. 62 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/DataSetParamController.java
  43. 48 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/dto/DataSetParamDto.java
  44. 17 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/param/DataSetParamParam.java
  45. 22 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/param/DataSetParamValidationParam.java
  46. 15 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/dao/DataSetParamMapper.java
  47. 48 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/dao/entity/DataSetParam.java
  48. 52 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/service/DataSetParamService.java
  49. 136 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/service/impl/DataSetParamServiceImpl.java
  50. 36 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/util/ParamsResolverHelper.java
  51. 44 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/controller/DataSetTransformController.java
  52. 36 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/controller/dto/DataSetTransformDto.java
  53. 17 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/controller/param/DataSetTransformParam.java
  54. 15 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/dao/DataSetTransformMapper.java
  55. 36 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/dao/entity/DataSetTransform.java
  56. 21 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/DataSetTransformService.java
  57. 25 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/TransformStrategy.java
  58. 71 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/impl/DataSetTransformServiceImpl.java
  59. 56 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/impl/DictTransformServiceImpl.java
  60. 62 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/impl/JsTransformServiceImpl.java
  61. 214 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/config/HttpClientConfig.java
  62. 53 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/config/HttpClientPoolConfig.java
  63. 67 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/DataSourceController.java
  64. 74 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/dto/DataSourceDto.java
  65. 21 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/param/ConnectionParam.java
  66. 31 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/param/DataSourceParam.java
  67. 16 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/dao/DataSourceMapper.java
  68. 42 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/dao/entity/DataSource.java
  69. 39 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/IConfig.java
  70. 13 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/IDataSourceConfig.java
  71. 21 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/ILifeCycle.java
  72. 93 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/IPooledDataSourceConfig.java
  73. 56 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/connection/IPooledConnection.java
  74. 457 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/connection/PooledConnection.java
  75. 71 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/constant/JdbcConstants.java
  76. 71 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/constant/PooledConst.java
  77. 68 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/AbstractDataSourceConfig.java
  78. 159 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/AbstractPooledDataSourceConfig.java
  79. 82 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/DataSourceConfigAdaptor.java
  80. 240 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/PooledDataSource.java
  81. 26 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/UnPooledDataSource.java
  82. 28 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/exception/JdbcPoolException.java
  83. 13 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/util/DataSourceHandleUtil.java
  84. 89 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/util/DriverClassUtil.java
  85. 100 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/util/JdbcUtil.java
  86. 48 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/service/DataSourceService.java
  87. 384 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/service/impl/DataSourceServiceImpl.java
  88. 25 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/constant/ExpConstant.java
  89. 60 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/controller/ReportController.java
  90. 44 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/controller/dto/ReportDto.java
  91. 30 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/controller/param/ReportParam.java
  92. 13 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/dao/ReportMapper.java
  93. 41 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/dao/entity/Report.java
  94. 17 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/service/ReportService.java
  95. 45 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/service/impl/ReportServiceImpl.java
  96. 97 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/controller/ReportExcelController.java
  97. 43 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/controller/dto/ReportExcelDto.java
  98. 18 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/controller/param/ReportExcelParam.java
  99. 11 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/dao/ReportExcelMapper.java
  100. 33 0
      report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/dao/entity/ReportExcel.java

+ 7 - 0
.gitignore

@@ -0,0 +1,7 @@
+.idea
+target
+*.iml
+/view/flutter/**/gen/*
+**/*.log
+dist
+logs

+ 0 - 0
derby.log


+ 104 - 0
pom.xml

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.anji-plus</groupId>
+        <artifactId>spring-boot-gaea-parent</artifactId>
+        <version>1.0.0.RELEASE</version>
+    </parent>
+
+    <groupId>com.anjiplus.template.gaea</groupId>
+    <artifactId>template-gaea</artifactId>
+    <description>anjiplus-template-gaea</description>
+    <version>1.0.0-SNAPSHOT</version>
+    <name>template-gaea</name>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>report-core</module>
+    </modules>
+
+    <properties>
+        <gaea.version>1.0.0-SNAPSHOT</gaea.version>
+        <gaea.security.version>1.0.0-SNAPSHOT</gaea.security.version>
+        <gaea.export.version>1.0.0-SNAPSHOT</gaea.export.version>
+        <gaea.generator.version>1.0.0-SNAPSHOT</gaea.generator.version>
+        <gaea.log.version>1.0.0-SNAPSHOT</gaea.log.version>
+        <maven.test.skip>true</maven.test.skip>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>com.anjiplus.template.gaea</groupId>
+                <artifactId>template-gaea-auth</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.anjiplus.template.gaea</groupId>
+                <artifactId>template-gaea-business</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.anjiplus.template.gaea</groupId>
+                <artifactId>template-gaea-common</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.anjiplus.template.gaea</groupId>
+                <artifactId>template-gaea-generator</artifactId>
+                <version>${gaea.generator.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.anji-plus</groupId>
+                <artifactId>spring-boot-gaea</artifactId>
+                <version>${gaea.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.anji-plus</groupId>
+                <artifactId>spring-boot-starter-gaea-security</artifactId>
+                <version>${gaea.security.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.anji-plus</groupId>
+                <artifactId>spring-boot-starter-gaea-export</artifactId>
+                <version>${gaea.export.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.anji-plus</groupId>
+                <artifactId>spring-boot-starter-gaea-log</artifactId>
+                <version>${gaea.log.version}</version>
+            </dependency>
+
+        </dependencies>
+    </dependencyManagement>
+
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <properties>
+                <spring.profiles.active>dev</spring.profiles.active>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+    </profiles>
+
+    <distributionManagement>
+        <repository>
+            <id>nexus-releases</id>
+            <url>http://nexus.anji-plus.com:8081/repository/maven-releases/</url>
+        </repository>
+        <snapshotRepository>
+            <id>nexus-snapshots</id>
+            <url>http://nexus.anji-plus.com:8081/repository/maven-snapshots/</url>
+        </snapshotRepository>
+    </distributionManagement>
+</project>

+ 115 - 0
report-core/pom.xml

@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>com.anjiplus.template.gaea</groupId>
+        <artifactId>template-gaea</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>aj-report</artifactId>
+    <name>aj-report</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.anjiplus.template.gaea</groupId>
+            <artifactId>template-gaea-common</artifactId>
+<!--            <exclusions>-->
+<!--                <exclusion>-->
+<!--                    <groupId>com.alibaba.cloud</groupId>-->
+<!--                    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
+<!--                </exclusion>-->
+<!--                <exclusion>-->
+<!--                    <groupId>com.alibaba.cloud</groupId>-->
+<!--                    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
+<!--                </exclusion>-->
+<!--            </exclusions>-->
+        </dependency>
+
+        <dependency>
+            <groupId>com.anjiplus.template.gaea</groupId>
+            <artifactId>template-gaea-generator</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+<!--        <dependency>-->
+<!--            <groupId>com.alibaba.cloud</groupId>-->
+<!--            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>com.alibaba.cloud</groupId>-->
+<!--            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>com.anji-plus</groupId>
+            <artifactId>spring-boot-starter-gaea-export</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.anji-plus</groupId>
+            <artifactId>spring-boot-starter-gaea-log</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.1.22</version>
+        </dependency>
+
+        <!--kudu impala驱动-->
+        <dependency>
+            <groupId>owinfo</groupId>
+            <artifactId>impalajdbc41</artifactId>
+            <version>1.0.0</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/src/main/resources/lib/ImpalaJDBC41.jar</systemPath>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.hive</groupId>
+            <artifactId>hive-jdbc</artifactId>
+            <version>1.2.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.eclipse.jetty.aggregate</groupId>
+                    <artifactId>jetty-all</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 27 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/ReportApplication.java

@@ -0,0 +1,27 @@
+package com.anjiplus.template.gaea.business;
+
+import com.anji.plus.gaea.annotation.enabled.EnabledGaeaConfiguration;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * 业务模板
+ * @author lr
+ * @since 2021-02-03
+ */
+@EnabledGaeaConfiguration
+@SpringBootApplication(scanBasePackages = {
+        "com.anjiplus.template.gaea",
+        "com.anji.plus"
+})
+@MapperScan(basePackages = {
+        "com.anjiplus.template.gaea.business.modules.*.dao",
+        "com.anjiplus.template.gaea.business.modules.*.**.dao",
+        "com.anji.plus.gaea.*.module.*.dao"
+})
+public class ReportApplication {
+    public static void main( String[] args ) {
+        SpringApplication.run(ReportApplication.class);
+    }
+}

+ 25 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/base/BaseController.java

@@ -0,0 +1,25 @@
+package com.anjiplus.template.gaea.business.base;
+
+import org.springframework.context.i18n.LocaleContextHolder;
+
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.dto.BaseDTO;
+import com.anji.plus.gaea.curd.entity.BaseEntity;
+import com.anji.plus.gaea.curd.params.PageParam;
+
+/**
+ * 项目级的Controller公共处理基类
+ *
+ * @author WongBin
+ * @date 2021/3/26
+ */
+public abstract class BaseController<P extends PageParam, T extends BaseEntity, D extends BaseDTO>
+        extends GaeaBaseController<P,T,D> {
+    /**
+     * 获取当前语言类型
+     * @return
+     */
+    public String getI18nLang(){
+        return LocaleContextHolder.getLocale().getLanguage();
+    }
+}

+ 15 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/base/BaseService.java

@@ -0,0 +1,15 @@
+package com.anjiplus.template.gaea.business.base;
+
+import com.anji.plus.gaea.curd.entity.BaseEntity;
+import com.anji.plus.gaea.curd.params.PageParam;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import org.springframework.context.i18n.LocaleContextHolder;
+
+/**
+ * 项目级的Service公共处理基类
+ * @author WongBin
+ * @date 2021/3/26
+ */
+public interface BaseService<P extends PageParam, T extends BaseEntity> extends GaeaBaseService<P, T> {
+
+}

+ 68 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/code/ResponseCode.java

@@ -0,0 +1,68 @@
+package com.anjiplus.template.gaea.business.code;
+
+/**
+ * 响应码
+ * @author lr
+ * @since 2021-02-22
+ */
+public interface ResponseCode {
+
+    /**
+     * 字典项重复
+     */
+    String DICT_ITEM_REPEAT = "Dict.item.code.exist";
+
+    /**
+     * 数字字典国际化标识不能为null
+     */
+    String DICT_CODE_LOCALE_NULL = "500-00002";
+
+    /**
+     * 参数为空
+     */
+    String PARAM_IS_NULL = "Rule.execute.param.null";
+
+    /**
+     * 规则编译不通过
+     */
+    String RULE_CONTENT_COMPILE_ERROR = "Rule.content.compile.error";
+
+    /**
+     * 规则执行不通过
+     */
+    String RULE_CONTENT_EXECUTE_ERROR = "Rule.content.execute.error";
+
+    /**
+     * 规则编码已存在
+     */
+    String RULE_CODE_EXIST = "Rule.code.exist";
+
+    /**
+     * 对应规则内容不存在
+     */
+    String RULE_CONTENT_NOT_EXIST = "Rule.content.not.exist";
+
+    /**
+     * 对应规则字段值不存在
+     */
+    String RULE_FIELDS_NOT_EXIST = "Rule.fields.not.exist";
+
+    /**
+     * 规则字段必填
+     */
+    String RULE_FIELD_VALUE_IS_REQUIRED = "Rule.field.value.is.required";
+
+    /**
+     * 规则字段值类型错误
+     */
+    String RULE_FIELD_VALUE_TYPE_ERROR = "Rule.field.value.type.error";
+
+    /**
+     * 规则参数校验不通过
+     */
+    String RULE_FIELDS_CHECK_ERROR = "Rule.fields.check.error";
+    /**
+     * 组件未加载
+     */
+    String COMPONENT_NOT_LOAD = "Component.load.check.error";
+}

+ 29 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/config/BusinessAutoConfiguration.java

@@ -0,0 +1,29 @@
+package com.anjiplus.template.gaea.business.config;
+
+import com.anjiplus.template.gaea.business.runner.ApplicationInitRunner;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * business配置类
+ * @author lr
+ * @since 2021-04-08
+ */
+@Configuration
+@MapperScan(basePackages = {
+        "com.anjiplus.template.gaea.business.modules.*.dao",
+        "com.anjiplus.template.gaea.business.modules.*.**.dao"
+})
+public class BusinessAutoConfiguration {
+
+    /**
+     * 系统启动完执行
+     * @return
+     */
+    @Bean
+    public ApplicationInitRunner applicationInitRunner() {
+        return new ApplicationInitRunner();
+    }
+}

+ 14 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/constant/BusinessConstant.java

@@ -0,0 +1,14 @@
+package com.anjiplus.template.gaea.business.constant;
+
+/**
+ * 常量
+ * @author lr
+ * @since 2021-03-26
+ */
+public interface BusinessConstant {
+
+    /**
+     * 字典项重复
+     */
+    String DICT_ITEM_EXIST_GROUP = "dictItemExist";
+}

+ 64 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/ReportDashboardController.java

@@ -0,0 +1,64 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboard.controller;
+
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardObjectDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ReportDashboardService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+* @desc 大屏设计 controller
+* @website https://gitee.com/anji-plus/gaea
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@RestController
+@Api(tags = "大屏设计管理")
+@RequestMapping("/reportDashboard")
+public class ReportDashboardController {
+
+    @Autowired
+    private ReportDashboardService reportDashboardService;
+
+    /**
+     * 预览、查询大屏详情
+     * @param reportCode
+     * @return
+     */
+    @GetMapping({"/{reportCode}"})
+    @Permission(code = "DETAIL", name = "明细")
+    public ResponseBean detail(@PathVariable("reportCode") String reportCode) {
+        return ResponseBean.builder().data(reportDashboardService.getDetail(reportCode)).build();
+    }
+
+    /**
+     * 保存大屏设计
+     * @param dto
+     * @return
+     */
+    @PostMapping
+    @Permission(code = "INSERT", name = "新增")
+    @GaeaAuditLog(pageTitle = "新增")
+    public ResponseBean insert(@RequestBody ReportDashboardObjectDto dto) {
+        reportDashboardService.insertDashboard(dto);
+        return ResponseBean.builder().build();
+    }
+
+
+    /**
+     * 获取去单个图层数据
+     * @param dto
+     * @return
+     */
+    @PostMapping("/getData")
+    @Permission(code = "DETAIL", name = "明细图表数据")
+    public ResponseBean getData(@RequestBody ChartDto dto) {
+        return ResponseBean.builder().data(reportDashboardService.getChartData(dto)).build();
+    }
+
+}

+ 51 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/dto/ChartDto.java

@@ -0,0 +1,51 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+
+/**
+*
+* @description 大屏设计 dto
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ChartDto implements Serializable {
+
+    private String chartType;
+
+    /**数据集编码*/
+    private String setCode;
+
+    /** 传入的自定义参数*/
+    private Map<String, Object> contextData;
+
+    /**图表属性*/
+    private Map<String, String> chartProperties;
+
+    /**时间字段*/
+    private String timeLineFiled;
+
+    /**时间颗粒度*/
+    private String particles;
+
+    /**时间格式化*/
+    private String dataTimeFormat;
+
+    /**时间展示层*/
+    private String timeLineFormat;
+
+    private int timeUnit;
+
+    /**时间区间*/
+    private String startTime;
+
+    /**时间区间*/
+    private String endTime;
+
+
+}

+ 55 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/dto/ReportDashboardDto.java

@@ -0,0 +1,55 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+*
+* @description 大屏设计 dto
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ReportDashboardDto extends GaeaBaseDTO implements Serializable {
+    /** 报表编码 */
+    private String reportCode;
+
+    /** 看板标题 */
+    private String title;
+
+    /** 宽度px */
+    private Long width;
+
+    /** 高度px */
+    private Long height;
+
+    /** 背景色 */
+    private String backgroundColor;
+
+    /** 背景图片 */
+    private String backgroundImage;
+
+    /** 工作台中的辅助线 */
+    private String presetLine;
+
+    /** 自动刷新间隔秒,数据字典REFRESH_TYPE */
+    private Integer refreshSeconds;
+
+    /** 0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG */
+    private Integer enableFlag;
+
+    /**  0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+    private Integer deleteFlag;
+
+    /** 排序,降序 */
+    private Integer sort;
+
+    private List<ReportDashboardWidgetDto> widgets;
+
+}

+ 32 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/dto/ReportDashboardObjectDto.java

@@ -0,0 +1,32 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto;
+
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+*
+* @description 大屏设计 dto
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ReportDashboardObjectDto implements Serializable {
+
+    /** 报表编码 */
+    private String reportCode;
+    /**
+     * 报表编码
+     */
+    private ReportDashboardDto dashboard;
+
+    /**
+     * 大屏画布中的组件
+     */
+    private List<ReportDashboardWidgetDto> widgets;
+
+}

+ 20 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/controller/param/ReportDashboardParam.java

@@ -0,0 +1,20 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.data.dashboard.controller.param;
+
+import lombok.Data;
+import java.io.Serializable;
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+
+import java.util.List;
+
+
+/**
+* @desc ReportDashboard 大屏设计查询输入类
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Data
+public class ReportDashboardParam extends PageParam implements Serializable{
+}

+ 16 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/dao/ReportDashboardMapper.java

@@ -0,0 +1,16 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboard.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity.ReportDashboard;
+
+/**
+* ReportDashboard Mapper
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@Mapper
+public interface ReportDashboardMapper extends GaeaBaseMapper<ReportDashboard> {
+
+}

+ 58 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/dao/entity/ReportDashboard.java

@@ -0,0 +1,58 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity;
+
+import com.anji.plus.gaea.annotation.Unique;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import lombok.Data;
+import io.swagger.annotations.ApiModelProperty;
+
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import javax.validation.constraints.*;
+import java.sql.Timestamp;
+
+/**
+* @description 大屏设计 entity
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+@TableName(value="gaea_report_dashboard")
+@Data
+public class ReportDashboard extends GaeaBaseEntity {
+    @ApiModelProperty(value = "报表编码")
+    @Unique(code = RespCommonCode.REPORT_CODE_ISEXIST)
+    private String reportCode;
+
+    @ApiModelProperty(value = "看板标题")
+    private String title;
+
+    @ApiModelProperty(value = "宽度px")
+    private Long width;
+
+    @ApiModelProperty(value = "高度px")
+    private Long height;
+
+    @ApiModelProperty(value = "背景色")
+    private String backgroundColor;
+
+    @ApiModelProperty(value = "背景图片")
+    private String backgroundImage;
+
+    @ApiModelProperty(value = "工作台中的辅助线")
+    private String presetLine;
+
+    @ApiModelProperty(value = "自动刷新间隔秒,数据字典REFRESH_TYPE")
+    private Integer refreshSeconds;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "排序,降序")
+    private Integer sort;
+
+
+}

+ 26 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/ChartStrategy.java

@@ -0,0 +1,26 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboard.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+
+import java.util.List;
+
+/**
+ * Created by raodeming on 2021/4/26.
+ */
+public interface ChartStrategy {
+
+    /**
+     * 图表类型
+     * @return
+     */
+    String type();
+
+    /**
+     * 针对每种图表类型做单独的数据转换解析
+     *
+     * @param dto
+     * @return
+     */
+    Object transform(ChartDto dto, List<JSONObject> data);
+}

+ 38 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/ReportDashboardService.java

@@ -0,0 +1,38 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboard.service;
+
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardObjectDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.param.ReportDashboardParam;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity.ReportDashboard;
+
+/**
+* @desc ReportDashboard 大屏设计服务接口
+* @author Raod
+* @date 2021-04-12 14:52:21.761
+**/
+public interface ReportDashboardService extends GaeaBaseService<ReportDashboardParam, ReportDashboard> {
+
+    /***
+     * 查询详情
+     *
+     * @param reportCode
+     */
+    ReportDashboardObjectDto getDetail(String reportCode);
+
+    /***
+     * 保存大屏设计
+     *
+     * @param dto
+     */
+    void insertDashboard(ReportDashboardObjectDto dto);
+
+
+    /**
+     * 获取单个图表数据
+     * @param dto
+     * @return
+     */
+    Object getChartData(ChartDto dto);
+}

+ 81 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/BarChartServiceImpl.java

@@ -0,0 +1,81 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 柱状体或者折线图
+ * Created by raodeming on 2021/4/26.
+ */
+@Component
+public class BarChartServiceImpl implements ChartStrategy {
+    /**
+     * 图表类型
+     *
+     * @return
+     */
+    @Override
+    public String type() {
+        return "widget-barchart|widget-linechart";
+    }
+
+    /**
+     * 针对每种图表类型做单独的数据转换解析
+     *
+     * @param dto
+     * @param data
+     * @return
+     */
+    @Override
+    public Object transform(ChartDto dto, List<JSONObject> data) {
+//        JSONObject json = new JSONObject();
+//        List<Object> xAxis = new ArrayList<>();
+//        List<Object> series = new ArrayList<>();
+//        data.forEach(jsonObject -> {
+//            jsonObject.forEach((s, o) -> {
+//                if ("xAxis".equals(s)) {
+//                    xAxis.add(o);
+//                } else {
+//                    series.add(o);
+//                }
+//            });
+//        });
+//
+//        json.put("xAxis", xAxis);
+//        JSONArray objects = new JSONArray();
+//        JSONObject jsonObject = new JSONObject();
+//        jsonObject.put("data", series);
+//        objects.add(jsonObject);
+//        json.put("series", objects);
+//        return json.toJSONString();
+        return data;
+    }
+
+
+/*    {
+        "xAxis": [
+                "哈哈",
+                "洗洗",
+                "来了",
+                "问问",
+                "天天"
+    ],
+        "series": [
+            {
+                "data": [
+                    1,
+                    2,
+                    3,
+                    4,
+                    5
+            ]
+        }
+    ]
+    }*/
+}

+ 108 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/BarLineChartServiceImpl.java

@@ -0,0 +1,108 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 折柱图
+ * Created by raodeming on 2021/4/26.
+ */
+@Component
+public class BarLineChartServiceImpl implements ChartStrategy {
+    /**
+     * 图表类型
+     *
+     * @return
+     */
+    @Override
+    public String type() {
+        return "widget-barlinechart";
+    }
+
+    /**
+     * 针对每种图表类型做单独的数据转换解析
+     *
+     * @param dto
+     * @param data
+     * @return
+     */
+    @Override
+    public Object transform(ChartDto dto, List<JSONObject> data) {
+//        JSONObject json = new JSONObject();
+//        List<Object> xAxis = new ArrayList<>();
+//        Map<String, List<Object>> series = new HashMap<>();
+//        data.forEach(jsonObject -> {
+//            jsonObject.forEach((s, o) -> {
+//                if ("xAxis".equals(s)) {
+//                    xAxis.add(o);
+//                } else {
+//                    List<Object> objects;
+//                    if (series.containsKey(s)) {
+//                        objects = series.get(s);
+//                    } else {
+//                        objects = new ArrayList<>();
+//
+//                    }
+//                    objects.add(o);
+//                    series.put(s, objects);
+//
+//                }
+//            });
+//        });
+//
+//        json.put("xAxis", xAxis);
+//        List<JSONObject> result = new ArrayList<>();
+//        series.forEach((s, objects) -> {
+//            JSONObject jsonObject = new JSONObject();
+//            jsonObject.put("name", s);
+//            if (s.endsWith("bar")) {
+//                jsonObject.put("type", "bar");
+//            } else  {
+//                jsonObject.put("type", "line");
+//            }
+//            jsonObject.put("data", objects);
+//            result.add(jsonObject);
+//        });
+//        json.put("series", result);
+//        return json.toJSONString();
+        return data;
+    }
+
+
+    /*{
+        "xAxis": [
+                "1月",
+                "2月",
+                "3月"
+        ],
+        "series": [
+            {
+                "name": "指标1", //暂时用不上
+                "type": "bar",   //需要处理
+                "data": [
+                    2,
+                    49,
+                    2
+                ]
+            },
+            {
+                 "name": "指标2",
+                "type": "line",
+                "yAxisIndex": 1,
+                "data": [
+                      2,
+                     32,
+                      4
+            ]
+        }
+    ]
+    }*/
+
+}

+ 43 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/GaugeChartServiceImpl.java

@@ -0,0 +1,43 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 饼图或者空心饼图或者漏斗图
+ * Created by raodeming on 2021/4/26.
+ */
+@Component
+public class GaugeChartServiceImpl implements ChartStrategy {
+    /**
+     * 图表类型
+     *
+     * @return
+     */
+    @Override
+    public String type() {
+        return "widget-gauge";
+    }
+
+    /**
+     * 针对每种图表类型做单独的数据转换解析
+     *
+     * @param dto
+     * @param data
+     * @return
+     */
+    @Override
+    public Object transform(ChartDto dto, List<JSONObject> data) {
+
+//        return "{\"value\": 50, \"name\": \"名称1\", \"unit\": \"%\"}";
+        return data;
+    }
+
+
+
+
+}

+ 52 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/PieChartServiceImpl.java

@@ -0,0 +1,52 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 饼图或者空心饼图或者漏斗图
+ * Created by raodeming on 2021/4/26.
+ */
+@Component
+public class PieChartServiceImpl implements ChartStrategy {
+    /**
+     * 图表类型
+     *
+     * @return
+     */
+    @Override
+    public String type() {
+        return "widget-piechart|widget-hollow-piechart|widget-funnel";
+    }
+
+    /**
+     * 针对每种图表类型做单独的数据转换解析
+     *
+     * @param dto
+     * @param data
+     * @return
+     */
+    @Override
+    public Object transform(ChartDto dto, List<JSONObject> data) {
+
+        return data;
+    }
+
+/*    [
+        {
+            "value": 11,
+                "name": "指标1"
+        },
+        {
+            "value": 10,
+                "name": "指标2"
+        }
+    ]*/
+
+
+
+}

+ 314 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/service/impl/ReportDashboardServiceImpl.java

@@ -0,0 +1,314 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboard.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anji.plus.gaea.utils.GaeaAssert;
+import com.anji.plus.gaea.utils.GaeaBeanUtils;
+import com.anjiplus.template.gaea.business.code.ResponseCode;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ChartDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.controller.dto.ReportDashboardObjectDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.ReportDashboardMapper;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.dao.entity.ReportDashboard;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ChartStrategy;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.service.ReportDashboardService;
+import com.anjiplus.template.gaea.business.modules.data.dashboard.util.DateUtil;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto.ReportDashboardWidgetValueDto;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service.ReportDashboardWidgetService;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.OriginalDataDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.service.DataSetService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @author Raod
+ * @desc ReportDashboard 大屏设计服务实现
+ * @date 2021-04-12 14:52:21.761
+ **/
+@Service
+//@RequiredArgsConstructor
+public class ReportDashboardServiceImpl implements ReportDashboardService, InitializingBean, ApplicationContextAware {
+
+    @Autowired
+    private ReportDashboardMapper reportDashboardMapper;
+
+    @Autowired
+    private ReportDashboardWidgetService reportDashboardWidgetService;
+
+    @Autowired
+    private DataSetService dataSetService;
+
+    private Map<String, ChartStrategy> queryServiceImplMap = new HashMap<>();
+    private ApplicationContext applicationContext;
+
+    @Override
+    public GaeaBaseMapper<ReportDashboard> getMapper() {
+        return reportDashboardMapper;
+    }
+
+    @Override
+    public ReportDashboardObjectDto getDetail(String reportCode) {
+        ReportDashboardObjectDto result = new ReportDashboardObjectDto();
+        ReportDashboardDto reportDashboardDto = new ReportDashboardDto();
+        ReportDashboard reportDashboard = this.selectOne("report_code", reportCode);
+        GaeaAssert.notNull(reportDashboard, ResponseCode.RULE_CONTENT_NOT_EXIST, "reportDashboard");
+        GaeaBeanUtils.copyAndFormatter(reportDashboard, reportDashboardDto);
+
+        List<ReportDashboardWidget> list = reportDashboardWidgetService.list(
+                new QueryWrapper<ReportDashboardWidget>().lambda()
+                        .eq(ReportDashboardWidget::getReportCode, reportCode)
+                        .orderByAsc(ReportDashboardWidget::getSort)
+        );
+        List<ReportDashboardWidgetDto> reportDashboardWidgetDtoList = new ArrayList<>();
+        list.forEach(reportDashboardWidget -> {
+            ReportDashboardWidgetDto reportDashboardWidgetDto = new ReportDashboardWidgetDto();
+            ReportDashboardWidgetValueDto value = new ReportDashboardWidgetValueDto();
+            value.setSetup(StringUtils.isNotBlank(reportDashboardWidget.getSetup()) ? JSONObject.parseObject(reportDashboardWidget.getSetup()) : new JSONObject());
+            value.setData(StringUtils.isNotBlank(reportDashboardWidget.getData()) ? JSONObject.parseObject(reportDashboardWidget.getData()) : new JSONObject());
+            value.setPosition(StringUtils.isNotBlank(reportDashboardWidget.getPosition()) ? JSONObject.parseObject(reportDashboardWidget.getPosition()) : new JSONObject());
+            value.setCollapse(StringUtils.isNotBlank(reportDashboardWidget.getCollapse()) ? JSONObject.parseObject(reportDashboardWidget.getCollapse()) : new JSONObject());
+
+            //实时数据的替换
+            analysisData(value);
+            reportDashboardWidgetDto.setType(reportDashboardWidget.getType());
+            reportDashboardWidgetDto.setValue(value);
+            reportDashboardWidgetDtoList.add(reportDashboardWidgetDto);
+        });
+        reportDashboardDto.setWidgets(reportDashboardWidgetDtoList);
+        result.setDashboard(reportDashboardDto);
+        result.setReportCode(reportCode);
+        return result;
+    }
+
+    /***
+     * 保存大屏设计
+     *
+     * @param dto
+     */
+    @Override
+    @Transactional
+    public void insertDashboard(ReportDashboardObjectDto dto) {
+        String reportCode = dto.getReportCode();
+        GaeaAssert.notEmpty(reportCode, ResponseCode.PARAM_IS_NULL, "reportCode");
+        //查询ReportDashboard
+        ReportDashboard reportDashboard = this.selectOne("report_code", reportCode);
+        ReportDashboard dashboard = new ReportDashboard();
+        GaeaBeanUtils.copyAndFormatter(dto.getDashboard(), dashboard);
+        BeanUtils.copyProperties(dto.getDashboard(), dashboard);
+        dashboard.setReportCode(reportCode);
+        if (null == reportDashboard) {
+            //新增
+            this.insert(dashboard);
+        } else {
+            //更新
+            dashboard.setId(reportDashboard.getId());
+            this.update(dashboard);
+        }
+
+        //删除reportDashboardWidget
+        reportDashboardWidgetService.delete(new QueryWrapper<ReportDashboardWidget>()
+                .lambda().eq(ReportDashboardWidget::getReportCode, reportCode));
+        List<ReportDashboardWidgetDto> widgets = dto.getWidgets();
+
+        List<ReportDashboardWidget> reportDashboardWidgetList = new ArrayList<>();
+        for (int i = 0; i < widgets.size(); i++) {
+            ReportDashboardWidget reportDashboardWidget = new ReportDashboardWidget();
+            ReportDashboardWidgetDto reportDashboardWidgetDto = widgets.get(i);
+            String type = reportDashboardWidgetDto.getType();
+            ReportDashboardWidgetValueDto value = reportDashboardWidgetDto.getValue();
+            reportDashboardWidget.setReportCode(reportCode);
+            reportDashboardWidget.setType(type);
+            reportDashboardWidget.setSetup(value.getSetup() != null ? JSONObject.toJSONString(value.getSetup()) : "");
+            reportDashboardWidget.setData(value.getData() != null ? JSONObject.toJSONString(value.getData()) : "");
+            reportDashboardWidget.setPosition(value.getPosition() != null ? JSONObject.toJSONString(value.getPosition()) : "");
+            reportDashboardWidget.setCollapse(value.getCollapse() != null ? JSONObject.toJSONString(value.getCollapse()) : "");
+            reportDashboardWidget.setEnableFlag(1);
+            reportDashboardWidget.setDeleteFlag(0);
+            reportDashboardWidget.setSort((long) (i + 1));
+            reportDashboardWidgetList.add(reportDashboardWidget);
+        }
+        reportDashboardWidgetService.insertBatch(reportDashboardWidgetList);
+
+    }
+
+    @Override
+    public Object getChartData(ChartDto dto) {
+//        String chartType = dto.getChartType();
+        DataSetDto setDto = new DataSetDto();
+        setDto.setSetCode(dto.getSetCode());
+        setDto.setContextData(dto.getContextData());
+        OriginalDataDto result = dataSetService.getData(setDto);
+        List<JSONObject> data = result.getData();
+        //处理时间轴
+        List<JSONObject> resultData = buildTimeLine(data, dto);
+        return resultData;
+//        return getTarget(chartType).transform(dto, result.getData());
+    }
+
+    public ChartStrategy getTarget(String type) {
+        for (String s : queryServiceImplMap.keySet()) {
+            if (s.contains(type)) {
+                return queryServiceImplMap.get(s);
+            }
+        }
+        throw BusinessExceptionBuilder.build(ResponseCode.RULE_CONTENT_NOT_EXIST);
+    }
+
+    @Override
+    public void afterPropertiesSet() {
+        Map<String, ChartStrategy> beanMap = applicationContext.getBeansOfType(ChartStrategy.class);
+        //遍历该接口的所有实现,将其放入map中
+        for (ChartStrategy serviceImpl : beanMap.values()) {
+            queryServiceImplMap.put(serviceImpl.type(), serviceImpl);
+        }
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+
+
+    /**
+     * 解析图层数据
+     *
+     * @param dto
+     */
+    public void analysisData(ReportDashboardWidgetValueDto dto) {
+//        if (StringUtils.isBlank(reportDashboardWidgetDto.getSetCode())) {
+//            return;
+//        }
+//        DataSetDto dto = new DataSetDto();
+//        dto.setSetCode(reportDashboardWidgetDto.getSetCode());
+//        if (reportDashboardWidgetDto.getContextData() != null && reportDashboardWidgetDto.getContextData().size() > 0) {
+//            dto.setContextData(reportDashboardWidgetDto.getContextData());
+//        }
+//        OriginalDataDto data = dataSetService.getData(dto);
+//        reportDashboardWidgetDto.setData(JSONObject.toJSONString(data.getData()));
+    }
+
+
+    public List<JSONObject> buildTimeLine(List<JSONObject> data, ChartDto dto) {
+        Map<String, String> chartProperties = dto.getChartProperties();
+        if (null == chartProperties || chartProperties.size() < 1) {
+            return data;
+        }
+        Map<String, Object> contextData = dto.getContextData();
+        if (null == contextData || contextData.size() < 1) {
+            return data;
+        }
+        if (contextData.containsKey("startTime") && contextData.containsKey("endTime")) {
+            dto.setStartTime(contextData.get("startTime").toString());
+            dto.setEndTime(contextData.get("endTime").toString());
+        }
+        if (StringUtils.isBlank(dto.getStartTime()) || StringUtils.isBlank(dto.getEndTime())) {
+            return data;
+        }
+        //获取时间轴字段和解析时间颗粒度
+        chartProperties.forEach((key, value) -> {
+            dto.setParticles(value);
+            setTimeLineFormat(dto);
+            if (StringUtils.isNotBlank(dto.getDataTimeFormat())) {
+                dto.setTimeLineFiled(key);
+                return;
+            }
+        });
+
+        if (StringUtils.isBlank(dto.getDataTimeFormat())) {
+            return data;
+        }
+
+        Date beginTime = DateUtil.parseHmsTime(dto.getStartTime());
+        Date endTime = DateUtil.parseHmsTime(dto.getEndTime());
+        SimpleDateFormat showFormat = new SimpleDateFormat(dto.getTimeLineFormat());
+        SimpleDateFormat dataFormat = new SimpleDateFormat(dto.getDataTimeFormat());
+
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(beginTime);
+
+        Calendar calendarEnd = Calendar.getInstance();
+        calendarEnd.setTime(endTime);
+
+        List<String> timeLine = new ArrayList<>();
+        List<String> dataTimeline = new ArrayList<>();
+        timeLine.add(showFormat.format(calendar.getTime()));
+        dataTimeline.add(dataFormat.format(calendar.getTime()));
+
+        //添加时间轴数据
+        while (true) {
+            calendar.add(dto.getTimeUnit(), 1);
+            timeLine.add(showFormat.format(calendar.getTime()));
+            dataTimeline.add(dataFormat.format(calendar.getTime()));
+            if (showFormat.format(calendar.getTime()).equals(showFormat.format(calendarEnd.getTime()))) {
+                break;
+            }
+        }
+
+        //根据时间轴生成对应的时间线,数据不存在,补数据
+        List<JSONObject> result = new ArrayList<>();
+        JSONObject jsonDemo = data.get(0);
+        String timeLineFiled = dto.getTimeLineFiled();
+        for (String dateFormat : dataTimeline) {
+            boolean flag = true;
+            for (JSONObject datum : data) {
+                if (datum.containsKey(timeLineFiled) && datum.getString(timeLineFiled).equals(dateFormat)) {
+                    result.add(datum);
+                    flag = false;
+                }
+            }
+            if (flag) {
+                //补数据
+                JSONObject json = new JSONObject();
+                jsonDemo.forEach((s, o) -> {
+                    if (s.equals(timeLineFiled)) {
+                        json.put(timeLineFiled, dateFormat);
+                    } else {
+                        json.put(s, 0);
+                    }
+                });
+                result.add(json);
+            }
+
+        }
+        return result;
+    }
+
+    //设置时间格式
+    private void setTimeLineFormat(ChartDto dto) {
+        String particles = dto.getParticles();
+        if ("xAxis-hour".equals(particles)) {
+            dto.setDataTimeFormat("yyyy-MM-dd HH");
+            dto.setTimeLineFormat("MM-dd HH");
+            dto.setTimeUnit(Calendar.HOUR);
+        } else if ("xAxis-day".equals(particles)) {
+            dto.setDataTimeFormat("yyyy-MM-dd");
+            dto.setTimeLineFormat("yyyy-MM-dd");
+            dto.setTimeUnit(Calendar.DATE);
+        } else if ("xAxis-month".equals(particles)) {
+            dto.setDataTimeFormat("yyyy-MM");
+            dto.setTimeLineFormat("yyyy-MM");
+            dto.setTimeUnit(Calendar.MONTH);
+        } else if ("xAxis-year".equals(particles)) {
+            dto.setDataTimeFormat("yyyy");
+            dto.setTimeLineFormat("yyyy");
+            dto.setTimeUnit(Calendar.YEAR);
+        }
+    }
+}

+ 47 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboard/util/DateUtil.java

@@ -0,0 +1,47 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboard.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by raodeming on 2021/4/29.
+ */
+public class DateUtil {
+
+    private static String defaultDatePattern = "yyyy-MM-dd";
+
+    private static String defaultDateTimePattern = "yyyy-MM-dd HH:mm:ss.SSS";
+
+    private static String defaultyyyyMMddPattern = "yyyyMMdd";
+
+    private static String defaultYmdHmsPattern = "yyyy-MM-dd HH:mm:ss";
+
+    private static String defaultHmsPattern = "HH:mm:ss";
+    /**字符串yyyy-MM-dd HH:mm:ss转日期
+     * @param dateStr yyyy-MM-dd HH:mm:ss
+     * @return
+     */
+    public static Date parseHmsTime(String dateStr) {
+        return parse(dateStr, defaultYmdHmsPattern);
+    }
+
+    /**字符串转日期
+     * @param dateStr
+     * @param pattern
+     * @return
+     */
+    public static Date parse(String dateStr, String pattern) {
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        if (dateStr == null || "".equals(dateStr)) {
+            return null;
+        }
+        try {
+            Date d = sdf.parse(dateStr);
+            return d;
+        } catch (ParseException e) {
+            System.out.println("日期转换错误: " + e.getMessage());
+            return null;
+        }
+    }
+}

+ 28 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/controller/dto/ReportDashboardWidgetDto.java

@@ -0,0 +1,28 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+*
+* @description 大屏看板数据渲染 dto
+* @author Raod
+* @date 2021-04-12 15:12:43.724
+**/
+@Data
+public class ReportDashboardWidgetDto implements Serializable {
+
+    /**
+     * 组件类型参考字典DASHBOARD_PANEL_TYPE
+     */
+    private String type;
+
+    /**
+     * value
+     */
+    private ReportDashboardWidgetValueDto value;
+
+}

+ 42 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/controller/dto/ReportDashboardWidgetValueDto.java

@@ -0,0 +1,42 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.dto;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+*
+* @description 大屏看板数据渲染 dto
+* @author Raod
+* @date 2021-04-12 15:12:43.724
+**/
+@Data
+public class ReportDashboardWidgetValueDto implements Serializable {
+    /** 报表编码 */
+    private String reportCode;
+
+    /** 组件的渲染属性json */
+    private JSONObject setup;
+
+    /** 组件的数据属性json */
+    private JSONObject data;
+
+    /** 组件的配置属性json */
+    private JSONObject collapse;
+
+    /** 组件的大小位置属性json */
+    private JSONObject position;
+
+    /** 0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG */
+    private Integer enableFlag;
+
+    /**  0--未删除 1--已删除 DIC_NAME=DEL_FLAG */
+    private Integer deleteFlag;
+
+    /** 排序,图层的概念 */
+    private Long sort;
+
+}

+ 20 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/controller/param/ReportDashboardWidgetParam.java

@@ -0,0 +1,20 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.param;
+
+import lombok.Data;
+import java.io.Serializable;
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+
+import java.util.List;
+
+
+/**
+* @desc ReportDashboardWidget 大屏看板数据渲染查询输入类
+* @author Raod
+* @date 2021-04-12 15:12:43.724
+**/
+@Data
+public class ReportDashboardWidgetParam extends PageParam implements Serializable{
+}

+ 16 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/dao/ReportDashboardWidgetMapper.java

@@ -0,0 +1,16 @@
+package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
+
+/**
+* ReportDashboardWidget Mapper
+* @author Raod
+* @date 2021-04-12 15:12:43.724
+**/
+@Mapper
+public interface ReportDashboardWidgetMapper extends GaeaBaseMapper<ReportDashboardWidget> {
+
+}

+ 45 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/dao/entity/ReportDashboardWidget.java

@@ -0,0 +1,45 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity;
+
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+* @description 大屏看板数据渲染 entity
+* @author Raod
+* @date 2021-04-12 15:12:43.724
+**/
+@TableName(value="gaea_report_dashboard_widget")
+@Data
+public class ReportDashboardWidget extends GaeaBaseEntity {
+    @ApiModelProperty(value = "报表编码")
+    private String reportCode;
+
+    @ApiModelProperty(value = "组件类型参考字典DASHBOARD_PANEL_TYPE")
+    private String type;
+
+    @ApiModelProperty(value = "组件的渲染属性json")
+    private String setup;
+
+    @ApiModelProperty(value = "组件的数据属性json")
+    private String data;
+
+    @ApiModelProperty(value = "组件的配置属性json")
+    private String collapse;
+
+    @ApiModelProperty(value = "组件的大小位置属性json")
+    private String position;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = " 0--未删除 1--已删除 DIC_NAME=DEL_FLAG")
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "排序,图层的概念")
+    private Long sort;
+
+
+}

+ 21 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/service/ReportDashboardWidgetService.java

@@ -0,0 +1,21 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service;
+
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.controller.param.ReportDashboardWidgetParam;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+
+/**
+* @desc ReportDashboardWidget 大屏看板数据渲染服务接口
+* @author Raod
+* @date 2021-04-12 15:12:43.724
+**/
+public interface ReportDashboardWidgetService extends GaeaBaseService<ReportDashboardWidgetParam, ReportDashboardWidget> {
+
+    /***
+     * 查询详情
+     *
+     * @param id
+     */
+    ReportDashboardWidget getDetail(Long id);
+}

+ 34 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dashboardwidget/service/impl/ReportDashboardWidgetServiceImpl.java

@@ -0,0 +1,34 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service.impl;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.entity.ReportDashboardWidget;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.service.ReportDashboardWidgetService;
+import com.anjiplus.template.gaea.business.modules.data.dashboardwidget.dao.ReportDashboardWidgetMapper;
+/**
+* @desc ReportDashboardWidget 大屏看板数据渲染服务实现
+* @author Raod
+* @date 2021-04-12 15:12:43.724
+**/
+@Service
+//@RequiredArgsConstructor
+public class ReportDashboardWidgetServiceImpl implements ReportDashboardWidgetService {
+
+    @Autowired
+    private ReportDashboardWidgetMapper reportDashboardWidgetMapper;
+
+    @Override
+    public GaeaBaseMapper<ReportDashboardWidget> getMapper() {
+      return reportDashboardWidgetMapper;
+    }
+
+    @Override
+    public ReportDashboardWidget getDetail(Long id) {
+        ReportDashboardWidget reportDashboardWidget = this.selectOne(id);
+        return reportDashboardWidget;
+    }
+}

+ 149 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/DataSetController.java

@@ -0,0 +1,149 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSet.controller;
+
+import com.anji.plus.gaea.annotation.AccessKey;
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anji.plus.gaea.holder.UserContentHolder;
+import com.anji.plus.gaea.utils.GaeaUtils;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param.DataSetParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param.DataSetTestTransformParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.service.DataSetService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+* @desc 数据集 controller
+* @website https://gitee.com/anji-plus/gaea
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+@RestController
+@Api(tags = "数据集管理")
+@RequestMapping("/dataSet")
+public class DataSetController extends GaeaBaseController<DataSetParam, DataSet, DataSetDto> {
+
+    @Autowired
+    private DataSetService dataSetService;
+
+    @Override
+    public GaeaBaseService<DataSetParam, DataSet> getService() {
+        return dataSetService;
+    }
+
+    @Override
+    public DataSet getEntity() {
+        return new DataSet();
+    }
+
+    @Override
+    public DataSetDto getDTO() {
+        return new DataSetDto();
+    }
+
+    @GetMapping("/detailBysetId/{id}")
+    @Permission(
+            code = "DETAIL",
+            name = "明细"
+    )
+    public ResponseBean detailBysetId(@PathVariable("id") Long id) {
+        this.logger.info("{}根据ID查询服务开始,id为:{}", this.getClass().getSimpleName(), id);
+        ResponseBean responseBean = this.responseSuccessWithData(dataSetService.detailSet(id));
+        this.logger.info("{}根据ID查询结束,结果:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(responseBean));
+        return responseBean;
+    }
+
+    @GetMapping({"/detailBysetCode/{setCode}"})
+    @Permission(
+            code = "DETAIL",
+            name = "明细"
+    )
+    @AccessKey
+    public ResponseBean detailBysetCode(@PathVariable("setCode") String setCode) {
+        this.logger.info("{}根据setCode查询服务开始,setCode为:{}", this.getClass().getSimpleName(), setCode);
+        ResponseBean responseBean = this.responseSuccessWithData(dataSetService.detailSet(setCode));
+        this.logger.info("{}根据setCode查询结束,结果:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(responseBean));
+        return responseBean;
+    }
+
+    @PostMapping
+    @Permission(
+            code = "INSERT",
+            name = "新增"
+    )
+    @GaeaAuditLog(
+            pageTitle = "新增"
+    )
+    @Override
+    public ResponseBean insert(@RequestBody DataSetDto dto) {
+        this.logger.info("{}新增服务开始,参数:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(dto));
+        DataSetDto dataSetDto = dataSetService.insertSet(dto);
+        this.logger.info("{}新增服务结束,结果:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(dataSetDto));
+        return ResponseBean.builder().data(dataSetDto).build();
+    }
+
+    @PutMapping
+    @Permission(
+            code = "UPDATE",
+            name = "更新"
+    )
+    @GaeaAuditLog(
+            pageTitle = "修改"
+    )
+    @Override
+    public ResponseBean update(@RequestBody DataSetDto dto) {
+        String username = UserContentHolder.getContext().getUsername();
+        this.logger.info("{}更新服务开始,更新人:{},参数:{}", this.getClass().getSimpleName(), username, GaeaUtils.toJSONString(dto));
+        ResponseBean responseBean = this.responseSuccess();
+        dataSetService.updateSet(dto);
+        this.logger.info("{}更新服务结束,结果:{}", this.getClass().getSimpleName(), GaeaUtils.toJSONString(responseBean));
+        return this.responseSuccess();
+    }
+
+    @DeleteMapping({"/{id}"})
+    @Permission(
+            code = "DELETE",
+            name = "删除"
+    )
+    @GaeaAuditLog(
+            pageTitle = "删除"
+    )
+    @Override
+    public ResponseBean deleteById(@PathVariable("id") Long id) {
+        this.logger.info("{}删除服务开始,参数ID:{}", this.getClass().getSimpleName(), id);
+        dataSetService.deleteSet(id);
+        this.logger.info("{}删除服务结束", this.getClass().getSimpleName());
+        return this.responseSuccess();
+    }
+
+    /**
+     * 测试 数据转换是否正确
+     * @param param
+     * @return
+     */
+    @PostMapping("/testTransform")
+    public ResponseBean testTransform(@Validated @RequestBody DataSetTestTransformParam param) {
+        DataSetDto dto = new DataSetDto();
+        BeanUtils.copyProperties(param, dto);
+        return responseSuccessWithData(dataSetService.testTransform(dto));
+    }
+
+    /**
+     * 获取所有数据集
+     * @return
+     */
+    @GetMapping("/queryAllDataSet")
+    public ResponseBean queryAllDataSet() {
+        return responseSuccessWithData(dataSetService.queryAllDataSet());
+    }
+
+
+}

+ 58 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/dto/DataSetDto.java

@@ -0,0 +1,58 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+*
+* @description 数据集 dto
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+@Data
+public class DataSetDto extends GaeaBaseDTO implements Serializable {
+    /** 数据集编码 */
+     private String setCode;
+
+    /** 数据集名称 */
+     private String setName;
+
+    /** 数据集描述 */
+     private String setDesc;
+
+    /** 数据源编码 */
+     private String sourceCode;
+
+    /** 动态查询sql或者接口中的请求体 */
+     private String dynSentence;
+
+    /** 结果案例 */
+     private String caseResult;
+
+    /** 0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG */
+     private Integer enableFlag;
+
+    /** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
+     private Integer deleteFlag;
+
+    /** 请求参数集合 */
+    private List<DataSetParamDto> dataSetParamDtoList;
+
+    /** 数据转换集合 */
+    private List<DataSetTransformDto> dataSetTransformDtoList;
+
+    /** 传入的自定义参数*/
+    private Map<String, Object> contextData;
+
+    private Set<String> setParamList;
+
+}

+ 32 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/dto/OriginalDataDto.java

@@ -0,0 +1,32 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Created by raodeming on 2021/3/26.
+ */
+@Data
+public class OriginalDataDto implements Serializable {
+
+    /**总数*/
+    private long total;
+
+    /**获取的数据详情*/
+    private List<JSONObject> data;
+
+    public OriginalDataDto(List<JSONObject> data) {
+        this.data = data;
+    }
+
+    public OriginalDataDto(long total, List<JSONObject> data) {
+        this.total = total;
+        this.data = data;
+    }
+
+    public OriginalDataDto() {
+    }
+}

+ 30 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/param/DataSetParam.java

@@ -0,0 +1,30 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param;
+
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+* @desc DataSet 数据集查询输入类
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+@Data
+public class DataSetParam extends PageParam implements Serializable{
+    /** 数据集编码 */
+    @Query(QueryEnum.LIKE)
+    private String setCode;
+
+    /** 数据集名称 */
+    @Query(QueryEnum.LIKE)
+    private String setName;
+
+    /** 数据源编码 */
+    @Query(QueryEnum.EQ)
+    private String sourceCode;
+}

+ 34 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/controller/param/DataSetTestTransformParam.java

@@ -0,0 +1,34 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+import java.util.List;
+
+
+/**
+* @desc DataSet 数据集查询输入类
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+@Data
+public class DataSetTestTransformParam implements Serializable{
+
+    /** 数据源编码 */
+    @NotBlank(message = "sourceCode not empty")
+    private String sourceCode;
+
+    /** 动态查询sql或者接口中的请求体 */
+    private String dynSentence;
+
+    /** 请求参数集合 */
+    private List<DataSetParamDto> dataSetParamDtoList;
+
+    /** 数据转换集合 */
+    private List<DataSetTransformDto> dataSetTransformDtoList;
+
+}

+ 16 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/dao/DataSetMapper.java

@@ -0,0 +1,16 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSet.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
+
+/**
+* DataSet Mapper
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+@Mapper
+public interface DataSetMapper extends GaeaBaseMapper<DataSet> {
+
+}

+ 45 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/dao/entity/DataSet.java

@@ -0,0 +1,45 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity;
+
+import com.anji.plus.gaea.annotation.Unique;
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+* @description 数据集 entity
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+@TableName(value="gaea_report_data_set")
+@Data
+public class DataSet extends GaeaBaseEntity {
+    @ApiModelProperty(value = "数据集编码")
+    @Unique(code = RespCommonCode.SET_CODE_ISEXIST)
+    private String setCode;
+
+    @ApiModelProperty(value = "数据集名称")
+    private String setName;
+
+    @ApiModelProperty(value = "数据集描述")
+    private String setDesc;
+
+    @ApiModelProperty(value = "数据源编码")
+    private String sourceCode;
+
+    @ApiModelProperty(value = "动态查询sql或者接口中的请求体")
+    private String dynSentence;
+
+    @ApiModelProperty(value = "结果案例")
+    private String caseResult;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
+    private Integer deleteFlag;
+
+
+}

+ 70 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/service/DataSetService.java

@@ -0,0 +1,70 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSet.service;
+
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.OriginalDataDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.param.DataSetParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
+
+import java.util.List;
+
+/**
+* @desc DataSet 数据集服务接口
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+public interface DataSetService extends GaeaBaseService<DataSetParam, DataSet> {
+
+    /**
+     * 单条详情
+     * @param id
+     * @return
+     */
+    DataSetDto detailSet(Long id);
+
+    /**
+     * 单条详情
+     * @param setCode
+     * @return
+     */
+    DataSetDto detailSet(String setCode);
+
+    /**
+     * 新增数据集、添加查询参数、数据转换
+     * @param dto
+     */
+    DataSetDto insertSet(DataSetDto dto);
+
+    /**
+     * 更新数据集、添加查询参数、数据转换
+     * @param dto
+     */
+    void updateSet(DataSetDto dto);
+
+    /**
+     * 删除数据集、添加查询参数、数据转换
+     * @param id
+     */
+    void deleteSet(Long id);
+
+    /**
+     * 获取数据
+     * @param dto
+     * @return
+     */
+    OriginalDataDto getData(DataSetDto dto);
+
+    /**
+     *
+     * @param dto
+     * @return
+     */
+    OriginalDataDto testTransform(DataSetDto dto);
+
+    /**
+     * 获取所有数据集
+     * @return
+     */
+    List<DataSet> queryAllDataSet();
+}

+ 343 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSet/service/impl/DataSetServiceImpl.java

@@ -0,0 +1,343 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSet.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.constant.Enabled;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anji.plus.gaea.utils.GaeaBeanUtils;
+import com.anjiplus.template.gaea.business.code.ResponseCode;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.OriginalDataDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.DataSetMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.dao.entity.DataSet;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.service.DataSetService;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.DataSetTransformService;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.service.DataSourceService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+* @desc DataSet 数据集服务实现
+* @author Raod
+* @date 2021-03-18 12:11:31.150755900
+**/
+@Service
+//@RequiredArgsConstructor
+public class DataSetServiceImpl implements DataSetService {
+
+    @Autowired
+    private DataSetMapper dataSetMapper;
+
+    @Autowired
+    private DataSetParamService dataSetParamService;
+
+    @Autowired
+    private DataSetTransformService dataSetTransformService;
+
+    @Autowired
+    private DataSourceService dataSourceService;
+
+    @Override
+    public GaeaBaseMapper<DataSet> getMapper() {
+      return dataSetMapper;
+    }
+
+    /**
+     * 单条详情
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public DataSetDto detailSet(Long id) {
+        DataSetDto dto = new DataSetDto();
+        DataSet result = selectOne(id);
+        String setCode = result.getSetCode();
+        GaeaBeanUtils.copyAndFormatter(result, dto);
+        return getDetailSet(dto, setCode);
+    }
+
+    /**
+     * 单条详情
+     *
+     * @param setCode
+     * @return
+     */
+    @Override
+    public DataSetDto detailSet(String setCode) {
+        DataSetDto dto = new DataSetDto();
+        DataSet result = selectOne("set_code", setCode);
+        GaeaBeanUtils.copyAndFormatter(result, dto);
+        return getDetailSet(dto, setCode);
+    }
+
+    public DataSetDto getDetailSet(DataSetDto dto, String setCode) {
+        //查询参数
+        List<DataSetParam> dataSetParamList = dataSetParamService.list(
+                new QueryWrapper<DataSetParam>()
+                        .lambda()
+                        .eq(DataSetParam::getSetCode, setCode)
+        );
+        List<DataSetParamDto> dataSetParamDtoList = new ArrayList<>();
+        dataSetParamList.forEach(dataSetParam -> {
+            DataSetParamDto dataSetParamDto = new DataSetParamDto();
+            GaeaBeanUtils.copyAndFormatter(dataSetParam, dataSetParamDto);
+            dataSetParamDtoList.add(dataSetParamDto);
+        });
+        dto.setDataSetParamDtoList(dataSetParamDtoList);
+
+        //数据转换
+
+        List<DataSetTransform> dataSetTransformList = dataSetTransformService.list(
+                new QueryWrapper<DataSetTransform>()
+                    .lambda()
+                    .eq(DataSetTransform::getSetCode, setCode)
+                    .orderByAsc(DataSetTransform::getOrderNum)
+        );
+        List<DataSetTransformDto> dataSetTransformDtoList = new ArrayList<>();
+        dataSetTransformList.forEach(dataSetTransform -> {
+            DataSetTransformDto dataSetTransformDto = new DataSetTransformDto();
+            GaeaBeanUtils.copyAndFormatter(dataSetTransform, dataSetTransformDto);
+            dataSetTransformDtoList.add(dataSetTransformDto);
+        });
+        dto.setDataSetTransformDtoList(dataSetTransformDtoList);
+
+        if (StringUtils.isNotBlank(dto.getCaseResult())) {
+            try {
+                JSONArray jsonArray = JSONArray.parseArray(dto.getCaseResult());
+                JSONObject jsonObject = jsonArray.getJSONObject(0);
+                dto.setSetParamList(jsonObject.keySet());
+            } catch (Exception e) {
+            }
+        }
+        return dto;
+    }
+
+
+    /**
+     * 新增数据集、添加查询参数、数据转换
+     *
+     * @param dto
+     */
+    @Override
+    @Transactional
+    public DataSetDto insertSet(DataSetDto dto) {
+        List<DataSetParamDto> dataSetParamDtoList = dto.getDataSetParamDtoList();
+        List<DataSetTransformDto> dataSetTransformDtoList = dto.getDataSetTransformDtoList();
+
+        //1.新增数据集
+        DataSet dataSet = new DataSet();
+        BeanUtils.copyProperties(dto, dataSet);
+        insert(dataSet);
+        //2.更新查询参数
+        dataSetParamBatch(dataSetParamDtoList, dto.getSetCode());
+
+        //3.更新数据转换
+        dataSetTransformBatch(dataSetTransformDtoList, dto.getSetCode());
+        return dto;
+    }
+
+    /**
+     * 更新数据集、添加查询参数、数据转换
+     *
+     * @param dto
+     */
+    @Override
+    @Transactional
+    public void updateSet(DataSetDto dto) {
+        List<DataSetParamDto> dataSetParamDtoList = dto.getDataSetParamDtoList();
+        List<DataSetTransformDto> dataSetTransformDtoList = dto.getDataSetTransformDtoList();
+        //1.更新数据集
+        DataSet dataSet = new DataSet();
+        BeanUtils.copyProperties(dto, dataSet);
+        update(dataSet);
+
+        //2.更新查询参数
+        dataSetParamBatch(dataSetParamDtoList, dto.getSetCode());
+
+        //3.更新数据转换
+        dataSetTransformBatch(dataSetTransformDtoList, dto.getSetCode());
+    }
+
+
+    /**
+     * 删除数据集、添加查询参数、数据转换
+     *
+     * @param id
+     */
+    @Override
+    public void deleteSet(Long id) {
+        DataSet dataSet = selectOne(id);
+        String setCode = dataSet.getSetCode();
+        //1.删除数据集
+        deleteById(id);
+
+        //2.删除查询参数
+        dataSetParamService.delete(
+                new QueryWrapper<DataSetParam>()
+                        .lambda()
+                        .eq(DataSetParam::getSetCode, setCode)
+        );
+
+        //3.删除数据转换
+        dataSetTransformService.delete(
+                new QueryWrapper<DataSetTransform>()
+                        .lambda()
+                        .eq(DataSetTransform::getSetCode, setCode)
+        );
+    }
+
+    /**
+     * 获取数据
+     *
+     * @param dto
+     * @return
+     */
+    @Override
+    public OriginalDataDto getData(DataSetDto dto) {
+        OriginalDataDto originalDataDto = new OriginalDataDto();
+        String setCode = dto.getSetCode();
+        //1.获取数据集、参数替换、数据转换
+        DataSetDto dataSetDto = detailSet(setCode);
+        //2.获取数据源
+        DataSource dataSource = dataSourceService.selectOne("source_code", dataSetDto.getSourceCode());
+        //3.参数替换
+        //3.1参数校验
+        boolean verification = dataSetParamService.verification(dataSetDto.getDataSetParamDtoList(), dto.getContextData());
+        if (!verification) {
+            throw BusinessExceptionBuilder.build(ResponseCode.RULE_FIELDS_CHECK_ERROR);
+        }
+        String dynSentence = dataSetParamService.transform(dto.getContextData(), dataSetDto.getDynSentence());
+        //4.获取数据
+        DataSourceDto dataSourceDto = new DataSourceDto();
+        BeanUtils.copyProperties(dataSource, dataSourceDto);
+        dataSourceDto.setDynSentence(dynSentence);
+        dataSourceDto.setContextData(dto.getContextData());
+        //获取total,判断contextData中是否传入分页参数
+        if (null != dto.getContextData()
+                && dto.getContextData().containsKey("pageNumber")
+                && dto.getContextData().containsKey("pageSize")) {
+            long total = dataSourceService.total(dataSourceDto, dto);
+            originalDataDto.setTotal(total);
+        }
+        List<JSONObject> data = dataSourceService.execute(dataSourceDto);
+        //5.数据转换
+        List<JSONObject> transform = dataSetTransformService.transform(dataSetDto.getDataSetTransformDtoList(), data);
+        originalDataDto.setData(transform);
+        return originalDataDto;
+    }
+
+    /**
+     * @param dto
+     * @return
+     */
+    @Override
+    public OriginalDataDto testTransform(DataSetDto dto) {
+        OriginalDataDto originalDataDto = new OriginalDataDto();
+        String sourceCode = dto.getSourceCode();
+        //1.获取数据源
+        DataSource dataSource = dataSourceService.selectOne("source_code", sourceCode);
+        //3.参数替换
+        //3.1参数校验
+        boolean verification = dataSetParamService.verification(dto.getDataSetParamDtoList(), null);
+        if (!verification) {
+            throw BusinessExceptionBuilder.build(ResponseCode.RULE_FIELDS_CHECK_ERROR);
+        }
+
+        String dynSentence = dataSetParamService.transform(dto.getDataSetParamDtoList(), dto.getDynSentence());
+        //4.获取数据
+        DataSourceDto dataSourceDto = new DataSourceDto();
+        BeanUtils.copyProperties(dataSource, dataSourceDto);
+        dataSourceDto.setDynSentence(dynSentence);
+        dataSourceDto.setContextData(dto.getContextData());
+
+        //获取total,判断DataSetParamDtoList中是否传入分页参数
+        Map<String, Object> collect = dto.getDataSetParamDtoList().stream().collect(Collectors.toMap(DataSetParamDto::getParamName, DataSetParamDto::getSampleItem));
+        if (collect.containsKey("pageNumber") && collect.containsKey("pageSize")) {
+            dto.setContextData(collect);
+            long total = dataSourceService.total(dataSourceDto, dto);
+            originalDataDto.setTotal(total);
+        }
+
+        List<JSONObject> data = dataSourceService.execute(dataSourceDto);
+        //5.数据转换
+        List<JSONObject> transform = dataSetTransformService.transform(dto.getDataSetTransformDtoList(), data);
+        originalDataDto.setData(transform);
+        return originalDataDto;
+    }
+
+
+    /**
+     * 获取所有数据集
+     *
+     * @return
+     */
+    @Override
+    public List<DataSet> queryAllDataSet() {
+        LambdaQueryWrapper<DataSet> wrapper = Wrappers.lambdaQuery();
+        wrapper.select(DataSet::getSetCode, DataSet::getSetName, DataSet::getSetDesc, DataSet::getId)
+                .eq(DataSet::getEnableFlag, Enabled.YES.getValue());
+        return dataSetMapper.selectList(wrapper);
+    }
+
+    public void dataSetParamBatch(List<DataSetParamDto> dataSetParamDtoList,String setCode){
+        dataSetParamService.delete(
+                new QueryWrapper<DataSetParam>()
+                        .lambda()
+                        .eq(DataSetParam::getSetCode, setCode)
+        );
+        if (null == dataSetParamDtoList || dataSetParamDtoList.size() <= 0) {
+            return;
+        }
+        List<DataSetParam> dataSetParamList = new ArrayList<>();
+        dataSetParamDtoList.forEach(dataSetParamDto -> {
+            DataSetParam dataSetParam = new DataSetParam();
+            BeanUtils.copyProperties(dataSetParamDto, dataSetParam);
+            dataSetParam.setSetCode(setCode);
+            dataSetParamList.add(dataSetParam);
+        });
+        dataSetParamService.insertBatch(dataSetParamList);
+
+    }
+
+    public void dataSetTransformBatch(List<DataSetTransformDto> dataSetTransformDtoList,String setCode){
+        dataSetTransformService.delete(
+                new QueryWrapper<DataSetTransform>()
+                        .lambda()
+                        .eq(DataSetTransform::getSetCode, setCode)
+        );
+        if (null == dataSetTransformDtoList || dataSetTransformDtoList.size() <= 0) {
+            return;
+        }
+        List<DataSetTransform> dataSetTransformList = new ArrayList<>();
+        for (int i = 0; i < dataSetTransformDtoList.size(); i++) {
+            DataSetTransform dataSetTransform = new DataSetTransform();
+            BeanUtils.copyProperties(dataSetTransformDtoList.get(i), dataSetTransform);
+            dataSetTransform.setOrderNum(i + 1);
+            dataSetTransform.setSetCode(setCode);
+            dataSetTransformList.add(dataSetTransform);
+        }
+        dataSetTransformService.insertBatch(dataSetTransformList);
+    }
+
+}

+ 62 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/DataSetParamController.java

@@ -0,0 +1,62 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller;
+
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param.DataSetParamParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param.DataSetParamValidationParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+* @desc 数据集动态参数 controller
+* @website https://gitee.com/anji-plus/gaea
+* @author Raod
+* @date 2021-03-18 12:12:33.108033200
+**/
+@RestController
+@Api(tags = "数据集动态参数管理")
+@RequestMapping("/dataSetParam")
+public class DataSetParamController extends GaeaBaseController<DataSetParamParam, DataSetParam, DataSetParamDto> {
+
+    @Autowired
+    private DataSetParamService dataSetParamService;
+
+    @Override
+    public GaeaBaseService<DataSetParamParam, DataSetParam> getService() {
+        return dataSetParamService;
+    }
+
+    @Override
+    public DataSetParam getEntity() {
+        return new DataSetParam();
+    }
+
+    @Override
+    public DataSetParamDto getDTO() {
+        return new DataSetParamDto();
+    }
+
+    /**
+     * 测试 查询参数是否正确
+     * @param param
+     * @return
+     */
+    @PostMapping("/verification")
+    public ResponseBean verification(@Validated @RequestBody DataSetParamValidationParam param) {
+        DataSetParamDto dto = new DataSetParamDto();
+        dto.setSampleItem(param.getSampleItem());
+        dto.setValidationRules(param.getValidationRules());
+        return responseSuccessWithData(dataSetParamService.verification(dto));
+    }
+}

+ 48 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/dto/DataSetParamDto.java

@@ -0,0 +1,48 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+*
+* @description 数据集动态参数 dto
+* @author Raod
+* @date 2021-03-18 12:12:33.108033200
+**/
+@Data
+public class DataSetParamDto extends GaeaBaseDTO implements Serializable {
+    /** 数据集编码 */
+     private String setCode;
+
+    /** 参数名 */
+     private String paramName;
+
+    /** 参数描述 */
+     private String paramDesc;
+
+    /** 参数类型,字典= */
+     private String paramType;
+
+    /** 参数示例项 */
+     private String sampleItem;
+
+    /** 0--非必填 1--必填 DIC_NAME=REQUIRED_FLAG */
+     private Integer requiredFlag;
+
+    /** js校验字段值规则,满足校验返回 true */
+     private String validationRules;
+
+    /** 排序 */
+     private Integer orderNum;
+
+    /** 0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG */
+     private Integer enableFlag;
+
+    /** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
+     private Integer deleteFlag;
+
+}

+ 17 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/param/DataSetParamParam.java

@@ -0,0 +1,17 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param;
+
+import com.anji.plus.gaea.curd.params.PageParam;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+* @desc DataSetParam 数据集动态参数查询输入类
+* @author Raod
+* @date 2021-03-18 12:12:33.108033200
+**/
+@Data
+public class DataSetParamParam extends PageParam implements Serializable{
+}

+ 22 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/controller/param/DataSetParamValidationParam.java

@@ -0,0 +1,22 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * Created by raodeming on 2021/3/24.
+ */
+@Data
+public class DataSetParamValidationParam implements Serializable {
+
+    /** 参数示例项 */
+    @NotBlank(message = "sampleItem not empty")
+    private String sampleItem;
+
+
+    /** js校验字段值规则,满足校验返回 true */
+    @NotBlank(message = "validationRules not empty")
+    private String validationRules;
+}

+ 15 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/dao/DataSetParamMapper.java

@@ -0,0 +1,15 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* DataSetParam Mapper
+* @author Raod
+* @date 2021-03-18 12:12:33.108033200
+**/
+@Mapper
+public interface DataSetParamMapper extends GaeaBaseMapper<DataSetParam> {
+
+}

+ 48 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/dao/entity/DataSetParam.java

@@ -0,0 +1,48 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity;
+
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+* @description 数据集动态参数 entity
+* @author Raod
+* @date 2021-03-18 12:12:33.108033200
+**/
+@TableName(value="gaea_report_data_set_param")
+@Data
+public class DataSetParam extends GaeaBaseEntity {
+    @ApiModelProperty(value = "数据集编码")
+    private String setCode;
+
+    @ApiModelProperty(value = "参数名")
+    private String paramName;
+
+    @ApiModelProperty(value = "参数描述")
+    private String paramDesc;
+
+    @ApiModelProperty(value = "参数类型,字典=")
+    private String paramType;
+
+    @ApiModelProperty(value = "参数示例项")
+    private String sampleItem;
+
+    @ApiModelProperty(value = "0--非必填 1--必填 DIC_NAME=REQUIRED_FLAG")
+    private Integer requiredFlag;
+
+    @ApiModelProperty(value = "js校验字段值规则,满足校验返回 true")
+    private String validationRules;
+
+    @ApiModelProperty(value = "排序")
+    private Integer orderNum;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
+    private Integer deleteFlag;
+
+
+}

+ 52 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/service/DataSetParamService.java

@@ -0,0 +1,52 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.service;
+
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.param.DataSetParamParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Raod
+ * @desc DataSetParam 数据集动态参数服务接口
+ * @date 2021-03-18 12:12:33.108033200
+ **/
+public interface DataSetParamService extends GaeaBaseService<DataSetParamParam, DataSetParam> {
+
+    /**
+     * 参数替换
+     *
+     * @param contextData
+     * @param dynSentence
+     * @return
+     */
+    String transform(Map<String, Object> contextData, String dynSentence);
+
+    /**
+     * 参数替换
+     *
+     * @param dataSetParamDtoList
+     * @param dynSentence
+     * @return
+     */
+    String transform(List<DataSetParamDto> dataSetParamDtoList, String dynSentence);
+
+    /**
+     * 参数校验  js脚本
+     * @param dataSetParamDto
+     * @return
+     */
+    boolean verification(DataSetParamDto dataSetParamDto);
+
+    /**
+     * 参数校验  js脚本
+     *
+     * @param dataSetParamDtoList
+     * @return
+     */
+    boolean verification(List<DataSetParamDto> dataSetParamDtoList, Map<String, Object> contextData);
+}

+ 136 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/service/impl/DataSetParamServiceImpl.java

@@ -0,0 +1,136 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.impl;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.controller.dto.DataSetParamDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.DataSetParamMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.dao.entity.DataSetParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.util.ParamsResolverHelper;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+* @desc DataSetParam 数据集动态参数服务实现
+* @author Raod
+* @date 2021-03-18 12:12:33.108033200
+**/
+@Service
+//@RequiredArgsConstructor
+@Slf4j
+public class DataSetParamServiceImpl implements DataSetParamService {
+
+    private ScriptEngine engine;
+    {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        engine = manager.getEngineByName("JavaScript");
+    }
+
+    @Autowired
+    private DataSetParamMapper dataSetParamMapper;
+
+    @Override
+    public GaeaBaseMapper<DataSetParam> getMapper() {
+      return dataSetParamMapper;
+    }
+
+    /**
+     * 参数替换
+     *
+     * @param contextData
+     * @param dynSentence
+     * @return
+     */
+    @Override
+    public String transform(Map<String, Object> contextData, String dynSentence) {
+        if (StringUtils.isBlank(dynSentence)) {
+            return dynSentence;
+        }
+        if (dynSentence.contains("${")) {
+            dynSentence = ParamsResolverHelper.resolveParams(contextData, dynSentence);
+        }
+        if (dynSentence.contains("${")) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.INCOMPLETE_PARAMETER_REPLACEMENT_VALUES, dynSentence);
+        }
+        return dynSentence;
+    }
+
+    /**
+     * 参数替换
+     *
+     * @param dataSetParamDtoList
+     * @param dynSentence
+     * @return
+     */
+    @Override
+    public String transform(List<DataSetParamDto> dataSetParamDtoList, String dynSentence) {
+        Map<String, Object> contextData = new HashMap<>();
+        if (null == dataSetParamDtoList || dataSetParamDtoList.size() <= 0) {
+            return dynSentence;
+        }
+        dataSetParamDtoList.forEach(dataSetParamDto -> {
+            contextData.put(dataSetParamDto.getParamName(), dataSetParamDto.getSampleItem());
+        });
+        return transform(contextData, dynSentence);
+    }
+
+    /**
+     * 参数校验  js脚本
+     *
+     * @param dataSetParamDto
+     * @return
+     */
+    @Override
+    public boolean verification(DataSetParamDto dataSetParamDto) {
+
+        String sampleItem = dataSetParamDto.getSampleItem();
+        String validationRules = dataSetParamDto.getValidationRules();
+        if (StringUtils.isNotBlank(validationRules)) {
+            validationRules = validationRules + "\nvar result = verification('" + sampleItem + "');";
+            try {
+                engine.eval(validationRules);
+                return Boolean.parseBoolean(engine.get("result").toString());
+
+            } catch (Exception ex) {
+                throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_JS_ERROR, ex.getMessage());
+            }
+
+        }
+        return true;
+    }
+
+    /**
+     * 参数校验  js脚本
+     *
+     * @param dataSetParamDtoList
+     * @return
+     */
+    @Override
+    public boolean verification(List<DataSetParamDto> dataSetParamDtoList, Map<String, Object> contextData) {
+        if (null == dataSetParamDtoList || dataSetParamDtoList.size() == 0) {
+            return true;
+        }
+
+        for (DataSetParamDto dataSetParamDto : dataSetParamDtoList) {
+            if (null != contextData) {
+                String value = contextData.getOrDefault(dataSetParamDto.getParamName(), "").toString();
+                dataSetParamDto.setSampleItem(value);
+            }
+            if (!verification(dataSetParamDto)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}

+ 36 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetParam/util/ParamsResolverHelper.java

@@ -0,0 +1,36 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSetParam.util;
+
+import org.springframework.util.PropertyPlaceholderHelper;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by raodeming on 2021/3/23.
+ */
+public class ParamsResolverHelper {
+    private static String placeholderPrefix = "${";
+    private static String placeholderSuffix = "}";
+    private static PropertyPlaceholderHelper helper =
+            new PropertyPlaceholderHelper(placeholderPrefix, placeholderSuffix);
+
+    public static String resolveParams(final Map<String, Object> param, String con) {
+        con = helper.replacePlaceholders(con, (key -> param.get(key) + ""));
+        return con;
+    }
+
+    private static Pattern key = Pattern.compile("\\$\\{(.*?)\\}");
+
+    public static List<String> findParamKeys(String con) {
+        Matcher m = key.matcher(con);
+        List ret = new ArrayList();
+        while (m.find()) {
+            ret.add(m.group(1));
+        }
+        return ret;
+    }
+
+}

+ 44 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/controller/DataSetTransformController.java

@@ -0,0 +1,44 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller;
+
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.param.DataSetTransformParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.DataSetTransformService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+* @desc 数据集数据转换 controller
+* @website https://gitee.com/anji-plus/gaea
+* @author Raod
+* @date 2021-03-18 12:13:15.591309400
+**/
+@RestController
+@Api(tags = "数据集数据转换管理")
+@RequestMapping("/dataSetTransform")
+public class DataSetTransformController extends GaeaBaseController<DataSetTransformParam, DataSetTransform, DataSetTransformDto> {
+
+    @Autowired
+    private DataSetTransformService dataSetTransformService;
+
+    @Override
+    public GaeaBaseService<DataSetTransformParam, DataSetTransform> getService() {
+        return dataSetTransformService;
+    }
+
+    @Override
+    public DataSetTransform getEntity() {
+        return new DataSetTransform();
+    }
+
+    @Override
+    public DataSetTransformDto getDTO() {
+        return new DataSetTransformDto();
+    }
+
+}

+ 36 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/controller/dto/DataSetTransformDto.java

@@ -0,0 +1,36 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+*
+* @description 数据集数据转换 dto
+* @author Raod
+* @date 2021-03-18 12:13:15.591309400
+**/
+@Data
+public class DataSetTransformDto extends GaeaBaseDTO implements Serializable {
+    /** 数据集编码 */
+     private String setCode;
+
+    /** 数据转换类型,DIC_NAME=TRANSFORM_TYPE; js,javaBean,字典转换 */
+     private String transformType;
+
+    /** 数据转换script,处理逻辑 */
+     private String transformScript;
+
+    /** 排序,执行数据转换顺序 */
+     private Integer orderNum;
+
+    /** 0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG */
+     private Integer enableFlag;
+
+    /** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
+     private Integer deleteFlag;
+
+}

+ 17 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/controller/param/DataSetTransformParam.java

@@ -0,0 +1,17 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.param;
+
+import com.anji.plus.gaea.curd.params.PageParam;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+* @desc DataSetTransform 数据集数据转换查询输入类
+* @author Raod
+* @date 2021-03-18 12:13:15.591309400
+**/
+@Data
+public class DataSetTransformParam extends PageParam implements Serializable{
+}

+ 15 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/dao/DataSetTransformMapper.java

@@ -0,0 +1,15 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* DataSetTransform Mapper
+* @author Raod
+* @date 2021-03-18 12:13:15.591309400
+**/
+@Mapper
+public interface DataSetTransformMapper extends GaeaBaseMapper<DataSetTransform> {
+
+}

+ 36 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/dao/entity/DataSetTransform.java

@@ -0,0 +1,36 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity;
+
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+* @description 数据集数据转换 entity
+* @author Raod
+* @date 2021-03-18 12:13:15.591309400
+**/
+@TableName(value="gaea_report_data_set_transform")
+@Data
+public class DataSetTransform extends GaeaBaseEntity {
+    @ApiModelProperty(value = "数据集编码")
+    private String setCode;
+
+    @ApiModelProperty(value = "数据转换类型,DIC_NAME=TRANSFORM_TYPE; js,javaBean,字典转换")
+    private String transformType;
+
+    @ApiModelProperty(value = "数据转换script,处理逻辑")
+    private String transformScript;
+
+    @ApiModelProperty(value = "排序,执行数据转换顺序")
+    private Integer orderNum;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
+    private Integer deleteFlag;
+
+
+}

+ 21 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/DataSetTransformService.java

@@ -0,0 +1,21 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.param.DataSetTransformParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
+
+import java.util.List;
+
+/**
+* @desc DataSetTransform 数据集数据转换服务接口
+* @author Raod
+* @date 2021-03-18 12:13:15.591309400
+**/
+public interface DataSetTransformService extends GaeaBaseService<DataSetTransformParam, DataSetTransform> {
+
+    List<JSONObject> transform(List<DataSetTransformDto> dataSetTransformDtoList, List<JSONObject> data);
+
+}

+ 25 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/TransformStrategy.java

@@ -0,0 +1,25 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+
+import java.util.List;
+
+/**
+ * Created by raodeming on 2021/3/23.
+ */
+public interface TransformStrategy {
+    /**
+     * 数据清洗转换 类型
+     * @return
+     */
+    String type();
+
+    /***
+     * 清洗转换算法接口
+     * @param def
+     * @param data
+     * @return
+     */
+    List<JSONObject> transform(DataSetTransformDto def, List<JSONObject> data);
+}

+ 71 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/impl/DataSetTransformServiceImpl.java

@@ -0,0 +1,71 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.DataSetTransformMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.dao.entity.DataSetTransform;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.DataSetTransformService;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.TransformStrategy;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+* @desc DataSetTransform 数据集数据转换服务实现
+* @author Raod
+* @date 2021-03-18 12:13:15.591309400
+**/
+@Service
+//@RequiredArgsConstructor
+public class DataSetTransformServiceImpl implements DataSetTransformService, InitializingBean, ApplicationContextAware {
+
+    private final Map<String, TransformStrategy> queryServiceImplMap = new HashMap<>();
+    private ApplicationContext applicationContext;
+
+    @Autowired
+    private DataSetTransformMapper dataSetTransformMapper;
+
+    @Override
+    public GaeaBaseMapper<DataSetTransform> getMapper() {
+      return dataSetTransformMapper;
+    }
+
+    public TransformStrategy getTarget(String type) {
+        return queryServiceImplMap.get(type);
+    }
+
+    @Override
+    public void afterPropertiesSet() {
+        Map<String, TransformStrategy> beanMap = applicationContext.getBeansOfType(TransformStrategy.class);
+        //遍历该接口的所有实现,将其放入map中
+        for (TransformStrategy serviceImpl : beanMap.values()) {
+            queryServiceImplMap.put(serviceImpl.type(), serviceImpl);
+        }
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+
+    @Override
+    public List<JSONObject> transform(List<DataSetTransformDto> dataSetTransformDtoList, List<JSONObject> data) {
+        if (dataSetTransformDtoList == null || dataSetTransformDtoList.size() <= 0) {
+            return data;
+        }
+
+        for (DataSetTransformDto dataSetTransformDto : dataSetTransformDtoList) {
+            data = getTarget(dataSetTransformDto.getTransformType()).transform(dataSetTransformDto, data);
+        }
+        return data;
+    }
+}

+ 56 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/impl/DictTransformServiceImpl.java

@@ -0,0 +1,56 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.TransformStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 字典转换
+ * Created by raodeming on 2021/3/29.
+ */
+@Component
+@Slf4j
+public class DictTransformServiceImpl implements TransformStrategy {
+
+    /**
+     * 数据清洗转换 类型
+     *
+     * @return
+     */
+    @Override
+    public String type() {
+        return "dict";
+    }
+
+    /***
+     * 清洗转换算法接口
+     * @param def
+     * @param data
+     * @return
+     */
+    @Override
+    public List<JSONObject> transform(DataSetTransformDto def, List<JSONObject> data) {
+        String transformScript = def.getTransformScript();
+        if (StringUtils.isBlank(transformScript)) {
+            return data;
+        }
+        JSONObject jsonObject = JSONObject.parseObject(transformScript);
+        Set<String> keys = jsonObject.keySet();
+
+        data.forEach(dataDetail -> dataDetail.forEach((key, value) -> {
+            if (keys.contains(key)) {
+                String string = jsonObject.getJSONObject(key).getString(value.toString());
+                if (StringUtils.isNotBlank(string)) {
+                    dataDetail.put(key, string);
+                }
+            }
+        }));
+        return data;
+    }
+}

+ 62 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSetTransform/service/impl/JsTransformServiceImpl.java

@@ -0,0 +1,62 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.controller.dto.DataSetTransformDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetTransform.service.TransformStrategy;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Created by raodeming on 2021/3/23.
+ */
+@Component
+@Slf4j
+public class JsTransformServiceImpl implements TransformStrategy {
+
+    private ScriptEngine engine;
+    {
+        ScriptEngineManager manager = new ScriptEngineManager();
+        engine = manager.getEngineByName("JavaScript");
+    }
+
+    /**
+     * 数据清洗转换 类型
+     *
+     * @return
+     */
+    @Override
+    public String type() {
+        return "js";
+    }
+
+    /***
+     * 清洗转换算法接口
+     * @param def
+     * @param data
+     * @return
+     */
+    @Override
+    public List<JSONObject> transform(DataSetTransformDto def, List<JSONObject> data) {
+        return getValueFromJS(def,data);
+    }
+
+    private List<JSONObject> getValueFromJS(DataSetTransformDto def, List<JSONObject> data) {
+        String js = def.getTransformScript();
+        js = js + "\nvar result = dataTransform(eval(" + data.toString() + "));";
+        try {
+            engine.eval(js);
+            ScriptObjectMirror result = (ScriptObjectMirror) engine.get("result");
+            return result.values().stream().map(o -> JSONObject.parseObject(JSONObject.toJSONString(o))).collect(Collectors.toList());
+        } catch (Exception ex) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_JS_ERROR, ex.getMessage());
+        }
+    }
+}

+ 214 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/config/HttpClientConfig.java

@@ -0,0 +1,214 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.config;
+
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HeaderElementIterator;
+import org.apache.http.HttpHost;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ConnectionKeepAliveStrategy;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.message.BasicHeaderElementIterator;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.ssl.SSLContextBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.client.DefaultResponseErrorHandler;
+import org.springframework.web.client.RestTemplate;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import java.nio.charset.Charset;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+
+/**
+ * Created by raodeming on 2021/3/24.
+ */
+@Configuration
+@Slf4j
+public class HttpClientConfig {
+    @Autowired
+    private HttpClientPoolConfig httpClientPoolConfig;
+
+    /**
+     * 创建HTTP客户端工厂
+     */
+    @Bean(name = "clientHttpRequestFactory")
+    public ClientHttpRequestFactory clientHttpRequestFactory() {
+        /**
+         *  maxTotalConnection 和 maxConnectionPerRoute 必须要配
+         */
+        if (httpClientPoolConfig.getMaxTotalConnect() <= 0) {
+            throw new IllegalArgumentException("invalid maxTotalConnection: " + httpClientPoolConfig.getMaxTotalConnect());
+        }
+        if (httpClientPoolConfig.getMaxConnectPerRoute() <= 0) {
+            throw new IllegalArgumentException("invalid maxConnectionPerRoute: " + httpClientPoolConfig.getMaxConnectPerRoute());
+        }
+        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient());
+        // 连接超时
+        clientHttpRequestFactory.setConnectTimeout(httpClientPoolConfig.getConnectTimeout());
+        // 数据读取超时时间,即SocketTimeout
+        clientHttpRequestFactory.setReadTimeout(httpClientPoolConfig.getReadTimeout());
+        // 从连接池获取请求连接的超时时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的
+        clientHttpRequestFactory.setConnectionRequestTimeout(httpClientPoolConfig.getConnectionRequestTimout());
+        return clientHttpRequestFactory;
+    }
+
+    /**
+     * 初始化RestTemplate,并加入spring的Bean工厂,由spring统一管理
+     */
+    @Bean(name = "dataSourceRestTemplate")
+    public RestTemplate restTemplate(@Qualifier("clientHttpRequestFactory") ClientHttpRequestFactory factory) {
+        return createRestTemplate(factory);
+    }
+
+    /**
+     * 配置httpClient
+     *
+     * @return
+     */
+    @Bean
+    public HttpClient httpClient() {
+        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
+        try {
+            //设置信任ssl访问
+            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (arg0, arg1) -> true).build();
+
+            httpClientBuilder.setSSLContext(sslContext);
+            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
+            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
+            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
+                    // 注册http和https请求
+                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                    .register("https", sslConnectionSocketFactory).build();
+
+            //使用Httpclient连接池的方式配置(推荐),同时支持netty,okHttp以及其他http框架
+            PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+            // 最大连接数
+            poolingHttpClientConnectionManager.setMaxTotal(httpClientPoolConfig.getMaxTotalConnect());
+            // 同路由并发数
+            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(httpClientPoolConfig.getMaxConnectPerRoute());
+            //配置连接池
+            httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
+            // 重试次数
+            httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(httpClientPoolConfig.getRetryTimes(), true));
+
+            //设置默认请求头
+            List<Header> headers = getDefaultHeaders();
+            httpClientBuilder.setDefaultHeaders(headers);
+            //设置长连接保持策略
+            httpClientBuilder.setKeepAliveStrategy(connectionKeepAliveStrategy());
+            return httpClientBuilder.build();
+        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
+            log.error("初始化HTTP连接池出错", e);
+        }
+        return null;
+    }
+
+
+    /**
+     * 配置长连接保持策略
+     *
+     * @return
+     */
+    public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
+        return (response, context) -> {
+            // Honor 'keep-alive' header
+            HeaderElementIterator it = new BasicHeaderElementIterator(
+                    response.headerIterator(HTTP.CONN_KEEP_ALIVE));
+            while (it.hasNext()) {
+                HeaderElement he = it.nextElement();
+                log.info("HeaderElement:{}", JSON.toJSONString(he));
+                String param = he.getName();
+                String value = he.getValue();
+                if (value != null && "timeout".equalsIgnoreCase(param)) {
+                    try {
+                        return Long.parseLong(value) * 1000;
+                    } catch (NumberFormatException ignore) {
+                        log.error("解析长连接过期时间异常", ignore);
+                    }
+                }
+            }
+            HttpHost target = (HttpHost) context.getAttribute(
+                    HttpClientContext.HTTP_TARGET_HOST);
+            //如果请求目标地址,单独配置了长连接保持时间,使用该配置
+            Optional<Map.Entry<String, Integer>> any = Optional.ofNullable(httpClientPoolConfig.getKeepAliveTargetHost()).orElseGet(HashMap::new)
+                    .entrySet().stream().filter(
+                            e -> e.getKey().equalsIgnoreCase(target.getHostName())).findAny();
+            //否则使用默认长连接保持时间
+            return any.map(en -> en.getValue() * 1000L).orElse(httpClientPoolConfig.getKeepAliveTime() * 1000L);
+        };
+    }
+
+
+    /**
+     * 设置请求头
+     *
+     * @return
+     */
+    private List<Header> getDefaultHeaders() {
+        List<Header> headers = new ArrayList<>();
+        headers.add(new BasicHeader("User-Agent",
+                "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"));
+        headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate"));
+        headers.add(new BasicHeader("Accept-Language", "zh-CN"));
+        headers.add(new BasicHeader("Connection", "Keep-Alive"));
+        return headers;
+    }
+
+
+    private RestTemplate createRestTemplate(ClientHttpRequestFactory factory) {
+        RestTemplate restTemplate = new RestTemplate(factory);
+
+        //我们采用RestTemplate内部的MessageConverter
+        //重新设置StringHttpMessageConverter字符集,解决中文乱码问题
+        modifyDefaultCharset(restTemplate);
+
+        //设置错误处理器
+        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
+
+        return restTemplate;
+    }
+
+    /**
+     * 修改默认的字符集类型为utf-8
+     *
+     * @param restTemplate
+     */
+    private void modifyDefaultCharset(RestTemplate restTemplate) {
+        List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
+        HttpMessageConverter<?> converterTarget = null;
+        for (HttpMessageConverter<?> item : converterList) {
+            if (StringHttpMessageConverter.class == item.getClass()) {
+                converterTarget = item;
+                break;
+            }
+        }
+        if (null != converterTarget) {
+            converterList.remove(converterTarget);
+        }
+        Charset defaultCharset = Charset.forName(httpClientPoolConfig.getCharset());
+        converterList.add(1, new StringHttpMessageConverter(defaultCharset));
+    }
+}
+

+ 53 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/config/HttpClientPoolConfig.java

@@ -0,0 +1,53 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * Created by raodeming on 2021/3/24.
+ */
+@Component
+@ConfigurationProperties(prefix = "spring.http-client.pool")
+@Data
+public class HttpClientPoolConfig {
+    /**
+     * java配置的优先级低于yml配置;如果yml配置不存在,会采用java配置
+     */
+    /**
+     * 连接池的最大连接数
+     */
+    private int maxTotalConnect = 1000;
+    /**
+     * 同路由的并发数
+     */
+    private int maxConnectPerRoute = 200;
+    /**
+     * 客户端和服务器建立连接超时,默认2s
+     */
+    private int connectTimeout = 2 * 1000;
+    /**
+     * 指客户端从服务器读取数据包的间隔超时时间,不是总读取时间,默认30s
+     */
+    private int readTimeout = 30 * 1000;
+
+    private String charset = "UTF-8";
+    /**
+     * 重试次数,默认2次
+     */
+    private int retryTimes = 2;
+    /**
+     * 从连接池获取连接的超时时间,不宜过长,单位ms
+     */
+    private int connectionRequestTimout = 200;
+    /**
+     * 针对不同的地址,特别设置不同的长连接保持时间
+     */
+    private Map<String,Integer> keepAliveTargetHost;
+    /**
+     * 针对不同的地址,特别设置不同的长连接保持时间,单位 s
+     */
+    private int keepAliveTime = 60;
+}

+ 67 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/DataSourceController.java

@@ -0,0 +1,67 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSource.controller;
+
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.DataSourceParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.service.DataSourceService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+* @desc 数据源 controller
+* @website https://gitee.com/anji-plus/gaea
+* @author Raod
+* @date 2021-03-18 12:09:57.728203200
+**/
+@RestController
+@Api(tags = "数据源管理")
+@RequestMapping("/dataSource")
+public class DataSourceController extends GaeaBaseController<DataSourceParam, DataSource, DataSourceDto> {
+
+    @Autowired
+    private DataSourceService dataSourceService;
+
+    @Override
+    public GaeaBaseService<DataSourceParam, DataSource> getService() {
+        return dataSourceService;
+    }
+
+    @Override
+    public DataSource getEntity() {
+        return new DataSource();
+    }
+
+    @Override
+    public DataSourceDto getDTO() {
+        return new DataSourceDto();
+    }
+
+    /**
+     * 获取所有数据源
+     * @return
+     */
+    @GetMapping("/queryAllDataSource")
+    public ResponseBean queryAllDataSource() {
+        return responseSuccessWithData(dataSourceService.queryAllDataSource());
+    }
+
+    /**
+     * 测试 连接
+     * @param connectionParam
+     * @return
+     */
+    @PostMapping("/testConnection")
+    public ResponseBean testConnection(@Validated @RequestBody ConnectionParam connectionParam) {
+        return responseSuccessWithData(dataSourceService.testConnection(connectionParam));
+    }
+
+
+
+}

+ 74 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/dto/DataSourceDto.java

@@ -0,0 +1,74 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Map;
+
+
+/**
+*
+* @description 数据源 dto
+* @author Raod
+* @date 2021-03-18 12:09:57.728203200
+**/
+@Data
+public class DataSourceDto extends GaeaBaseDTO implements Serializable {
+    /** 数据源编码 */
+     private String sourceCode;
+
+    /** 数据源名称 */
+     private String sourceName;
+
+    /** 数据源描述 */
+     private String sourceDesc;
+
+    /** 数据源类型 DIC_NAME=SOURCE_TYPE; mysql,orace,sqlserver,elasticsearch,接口,javaBean,数据源类型字典中item-extend动态生成表单 */
+     private String sourceType;
+
+    /** 数据源连接配置json:关系库{ jdbcUrl:'', username:'', password:'','driverName':''}ES-sql{ apiUrl:'http://127.0.0.1:9092/_xpack/sql?format=json','method':'POST','body':'{"query":"select 1"}' }  接口{ apiUrl:'http://ip:port/url', method:'' } javaBean{ beanNamw:'xxx' } */
+     private String sourceConfig;
+
+    /** 0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG */
+     private Integer enableFlag;
+
+    /** 0--未删除 1--已删除 DIC_NAME=DELETE_FLAG */
+     private Integer deleteFlag;
+
+    /**************************************************************/
+    /**关系型数据库jdbcUrl */
+    private String jdbcUrl;
+
+    /** 关系型数据库用户名 */
+    private String username;
+
+    /** 关系型数据库密码 */
+    private String password;
+
+    /** 关系型数据库驱动类 */
+    private String driverName;
+
+    /** 关系型数据库sql */
+    private String sql;
+
+    /** http requestUrl */
+    private String apiUrl;
+
+    /** http method */
+    private String method;
+
+    /** http header */
+    private String header;
+
+    /** http 请求体 */
+    private String body;
+
+    /** 动态查询sql或者接口中的请求体 */
+    private String dynSentence;
+
+    /** 传入的自定义参数,解决url中存在的动态参数*/
+    private Map<String, Object> contextData;
+
+}

+ 21 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/param/ConnectionParam.java

@@ -0,0 +1,21 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * Created by raodeming on 2021/3/19.
+ */
+@Data
+public class ConnectionParam implements Serializable {
+
+    /** 数据源类型 DIC_NAME=SOURCE_TYPE; mysql,orace,sqlserver,elasticsearch,接口,javaBean,数据源类型字典中item-extend动态生成表单 */
+    @NotBlank(message = "sourceType not empty")
+    private String sourceType;
+
+    /** 数据源连接配置json:关系库{ jdbcUrl:'', username:'', password:'','driverName':''}ES-sql{ apiUrl:'http://127.0.0.1:9092/_xpack/sql?format=json','method':'POST','body':'{"query":"select 1"}' }  接口{ apiUrl:'http://ip:port/url', method:'' } javaBean{ beanNamw:'xxx' } */
+    @NotBlank(message = "sourceConfig not empty")
+    private String sourceConfig;
+}

+ 31 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/controller/param/DataSourceParam.java

@@ -0,0 +1,31 @@
+/**/
+package com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param;
+
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+* @desc DataSource 数据集查询输入类
+* @author Raod
+* @date 2021-03-18 12:09:57.728203200
+**/
+@Data
+public class DataSourceParam extends PageParam implements Serializable{
+
+    /** 数据源名称 */
+    @Query(QueryEnum.LIKE)
+    private String sourceName;
+
+    /** 数据源编码 */
+    @Query(QueryEnum.LIKE)
+    private String sourceCode;
+
+    /** 数据源类型 DIC_NAME=SOURCE_TYPE; mysql,orace,sqlserver,elasticsearch,接口,javaBean,数据源类型字典中item-extend动态生成表单 */
+    @Query(QueryEnum.EQ)
+    private String sourceType;
+}

+ 16 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/dao/DataSourceMapper.java

@@ -0,0 +1,16 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
+
+/**
+* DataSource Mapper
+* @author Raod
+* @date 2021-03-18 12:09:57.728203200
+**/
+@Mapper
+public interface DataSourceMapper extends GaeaBaseMapper<DataSource> {
+
+}

+ 42 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/dao/entity/DataSource.java

@@ -0,0 +1,42 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity;
+
+import com.anji.plus.gaea.annotation.Unique;
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+* @description 数据源 entity
+* @author Raod
+* @date 2021-03-18 12:09:57.728203200
+**/
+@TableName(value="gaea_report_data_source")
+@Data
+public class DataSource extends GaeaBaseEntity {
+    @ApiModelProperty(value = "数据源编码")
+    @Unique(code = RespCommonCode.SOURCE_CODE_ISEXIST)
+    private String sourceCode;
+
+    @ApiModelProperty(value = "数据源名称")
+    private String sourceName;
+
+    @ApiModelProperty(value = "数据源描述")
+    private String sourceDesc;
+
+    @ApiModelProperty(value = "数据源类型 DIC_NAME=SOURCE_TYPE; mysql,orace,sqlserver,elasticsearch,接口,javaBean,数据源类型字典中item-extend动态生成表单")
+    private String sourceType;
+
+    @ApiModelProperty(value = "数据源连接配置json:关系库{ jdbcUrl:'', username:'', password:'','driverName':''}ES-sql{ apiUrl:'http://127.0.0.1:9092/_xpack/sql?format=json','method':'POST','body':'{\"query\":\"select 1\"}' }  接口{ apiUrl:'http://ip:port/url', method:'' } javaBean{ beanNamw:'xxx' }")
+    private String sourceConfig;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
+    private Integer deleteFlag;
+
+
+}

+ 39 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/IConfig.java

@@ -0,0 +1,39 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
+
+/**
+ * 配置接口
+ * @author binbin.hou
+ * @since 1.0.0
+ */
+public interface IConfig {
+
+    /**
+     * 设置驱动类
+     *
+     * @param driverClass 驱动类
+     * @since 1.0.0
+     */
+    void setDriverClass(final String driverClass);
+
+    /**
+     * jdbc url
+     * @param jdbcUrl url
+     * @since 1.0.0
+     */
+    void setJdbcUrl(final String jdbcUrl);
+
+    /**
+     * 设置用户信息
+     * @param user 用户信息
+     * @since 1.0.0
+     */
+    void setUser(final String user);
+
+    /**
+     * 设置密码
+     * @param password 密码
+     * @since 1.0.0
+     */
+    void setPassword(final String password);
+
+}

+ 13 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/IDataSourceConfig.java

@@ -0,0 +1,13 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
+
+import javax.sql.DataSource;
+
+/**
+ * 配置接口
+ * @author binbin.hou
+ * @since 1.0.0
+ */
+public interface IDataSourceConfig extends IConfig, DataSource {
+
+
+}

+ 21 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/ILifeCycle.java

@@ -0,0 +1,21 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
+
+/**
+ * 生命周期管理
+ * @since 1.1.0
+ */
+public interface ILifeCycle {
+
+    /**
+     * 生命的初始化
+     * @since 1.1.0
+     */
+    void init();
+
+    /**
+     * 生命的销毁
+     * @since 1.1.0
+     */
+    void destroy();
+
+}

+ 93 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/api/IPooledDataSourceConfig.java

@@ -0,0 +1,93 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection.IPooledConnection;
+
+/**
+ * 池化的接口
+ * @author binbin.hou
+ * @since 1.0.0
+ */
+public interface IPooledDataSourceConfig extends IDataSourceConfig {
+
+    /**
+     * 归还连接
+     * @param pooledConnection 连接池信息
+     * @since 1.5.0
+     */
+    void returnConnection(IPooledConnection pooledConnection);
+
+    /**
+     * 设置最小尺寸
+     *
+     * @param minSize 大小
+     * @since 1.1.0
+     */
+    void setMinSize(final int minSize);
+
+    /**
+     * 设置最大的大小
+     *
+     * @param maxSize 最大的大小
+     * @since 1.1.0
+     */
+    void setMaxSize(final int maxSize);
+
+    /**
+     * 设置最大的等待时间
+     * @param maxWaitMills 最大的等待时间
+     * @since 1.1.0
+     */
+    void setMaxWaitMills(final long maxWaitMills);
+
+    /**
+     * 设置验证查询的语句
+     *
+     * 如果这个值为空,那么 {@link #setTestOnBorrow(boolean)}
+     * {@link #setTestOnIdle(boolean)}}
+     * {@link #setTestOnReturn(boolean)}
+     * 都将无效
+     * @param validQuery 验证查询的语句
+     * @since 1.5.0
+     */
+    void setValidQuery(final String validQuery);
+
+    /**
+     * 验证的超时秒数
+     * @param validTimeOutSeconds 验证的超时秒数
+     * @since 1.5.0
+     */
+    void setValidTimeOutSeconds(final int validTimeOutSeconds);
+
+    /**
+     * 获取连接时进行校验
+     *
+     * 备注:影响性能
+     * @param testOnBorrow 是否
+     * @since 1.5.0
+     */
+    void setTestOnBorrow(final boolean testOnBorrow);
+
+    /**
+     * 归还连接时进行校验
+     *
+     * 备注:影响性能
+     * @param testOnReturn 归还连接时进行校验
+     * @since 1.5.0
+     */
+    void setTestOnReturn(final boolean testOnReturn);
+
+    /**
+     * 闲暇的时候进行校验
+     * @param testOnIdle 闲暇的时候进行校验
+     * @since 1.5.0
+     */
+    void setTestOnIdle(final boolean testOnIdle);
+
+    /**
+     * 闲暇时进行校验的时间间隔
+     * @param testOnIdleIntervalSeconds 时间间隔
+     * @since 1.5.0
+     */
+    void setTestOnIdleIntervalSeconds(final long testOnIdleIntervalSeconds);
+
+}

+ 56 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/connection/IPooledConnection.java

@@ -0,0 +1,56 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IPooledDataSourceConfig;
+
+import java.sql.Connection;
+
+/**
+ * 池化的连接池
+ * @since 1.1.0
+ */
+public interface IPooledConnection extends Connection {
+
+
+    /**
+     * 是否繁忙
+     * @since 1.1.0
+     * @return 状态
+     */
+    boolean isBusy();
+
+    /**
+     * 设置状态
+     * @param busy 状态
+     * @since 1.1.0
+     */
+    void setBusy(boolean busy);
+
+    /**
+     * 获取真正的连接
+     * @return 连接
+     * @since 1.1.0
+     */
+    Connection getConnection();
+
+    /**
+     * 设置连接信息
+     * @param connection 连接信息
+     * @since 1.1.0
+     */
+    void setConnection(Connection connection);
+
+    /**
+     * 设置对应的数据源
+     * @param dataSource 数据源
+     * @since 1.5.0
+     */
+    void setDataSource(final IPooledDataSourceConfig dataSource);
+
+    /**
+     * 获取对应的数据源信息
+     * @return 数据源
+     * @since 1.5.0
+     */
+    IPooledDataSourceConfig getDataSource();
+
+}

+ 457 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/connection/PooledConnection.java

@@ -0,0 +1,457 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IPooledDataSourceConfig;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.exception.JdbcPoolException;
+import lombok.extern.slf4j.Slf4j;
+
+import java.sql.*;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+/**
+ * 池化的连接
+ *
+ * @since 1.1.0
+ */
+@Slf4j
+public class PooledConnection implements IPooledConnection {
+
+    /**
+     * 是否繁忙
+     * @since 1.1.0
+     */
+    private volatile boolean isBusy;
+
+    /**
+     * 数据库链接信息
+     * @since 1.1.0
+     */
+    private Connection connection;
+
+    /**
+     * 对应的数据源信息
+     *
+     * @since 1.1.0
+     */
+    private IPooledDataSourceConfig dataSource;
+
+    @Override
+    public Statement createStatement() throws SQLException {
+        checkStatus();
+
+        return connection.createStatement();
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql) throws SQLException {
+        checkStatus();
+
+        return connection.prepareStatement(sql);
+    }
+
+    @Override
+    public CallableStatement prepareCall(String sql) throws SQLException {
+        checkStatus();
+
+        return connection.prepareCall(sql);
+    }
+
+    @Override
+    public String nativeSQL(String sql) throws SQLException {
+        checkStatus();
+
+        return connection.nativeSQL(sql);
+    }
+
+    @Override
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        checkStatus();
+
+        connection.setAutoCommit(autoCommit);
+    }
+
+    @Override
+    public boolean getAutoCommit() throws SQLException {
+        checkStatus();
+
+        return connection.getAutoCommit();
+    }
+
+    @Override
+    public void commit() throws SQLException {
+        checkStatus();
+
+        connection.commit();
+    }
+
+    @Override
+    public void rollback() throws SQLException {
+        checkStatus();
+
+        connection.rollback();
+    }
+
+    @Override
+    public void close() throws SQLException {
+        checkStatus();
+
+        this.dataSource.returnConnection(this);
+    }
+
+    @Override
+    public boolean isClosed() throws SQLException {
+        checkStatus();
+
+        return connection.isClosed();
+    }
+
+    @Override
+    public DatabaseMetaData getMetaData() throws SQLException {
+        checkStatus();
+
+        return connection.getMetaData();
+    }
+
+    @Override
+    public void setReadOnly(boolean readOnly) throws SQLException {
+        checkStatus();
+
+        connection.setReadOnly(readOnly);
+    }
+
+    @Override
+    public boolean isReadOnly() throws SQLException {
+        checkStatus();
+
+        return connection.isReadOnly();
+    }
+
+    @Override
+    public void setCatalog(String catalog) throws SQLException {
+        checkStatus();
+
+        connection.setCatalog(catalog);
+    }
+
+    @Override
+    public String getCatalog() throws SQLException {
+        checkStatus();
+
+        return connection.getCatalog();
+    }
+
+    @Override
+    public void setTransactionIsolation(int level) throws SQLException {
+        checkStatus();
+
+        connection.setTransactionIsolation(level);
+    }
+
+    @Override
+    public int getTransactionIsolation() throws SQLException {
+        checkStatus();
+
+        return connection.getTransactionIsolation();
+    }
+
+    @Override
+    public SQLWarning getWarnings() throws SQLException {
+        checkStatus();
+
+        return connection.getWarnings();
+    }
+
+    @Override
+    public void clearWarnings() throws SQLException {
+        checkStatus();
+
+        connection.clearWarnings();
+    }
+
+    @Override
+    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+        checkStatus();
+
+        return connection.createStatement(resultSetType, resultSetConcurrency);
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        checkStatus();
+
+        return connection.prepareStatement(sql, resultSetType, resultSetConcurrency);
+    }
+
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        checkStatus();
+
+        return connection.prepareCall(sql, resultSetType, resultSetConcurrency);
+    }
+
+    @Override
+    public Map<String, Class<?>> getTypeMap() throws SQLException {
+        checkStatus();
+
+        return connection.getTypeMap();
+    }
+
+    @Override
+    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+        checkStatus();
+
+        connection.setTypeMap(map);
+    }
+
+    @Override
+    public void setHoldability(int holdability) throws SQLException {
+        checkStatus();
+
+        connection.setHoldability(holdability);
+    }
+
+    @Override
+    public int getHoldability() throws SQLException {
+        checkStatus();
+
+        return connection.getHoldability();
+    }
+
+    @Override
+    public Savepoint setSavepoint() throws SQLException {
+        checkStatus();
+
+        return connection.setSavepoint();
+    }
+
+    @Override
+    public Savepoint setSavepoint(String name) throws SQLException {
+        checkStatus();
+
+        return connection.setSavepoint(name);
+    }
+
+    @Override
+    public void rollback(Savepoint savepoint) throws SQLException {
+        checkStatus();
+
+        connection.rollback(savepoint);
+    }
+
+    @Override
+    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+        checkStatus();
+
+        connection.releaseSavepoint(savepoint);
+    }
+
+    @Override
+    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        checkStatus();
+
+        return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        checkStatus();
+
+        return connection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+    }
+
+    @Override
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+        checkStatus();
+
+        return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+        checkStatus();
+
+        return connection.prepareStatement(sql, autoGeneratedKeys);
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
+        checkStatus();
+
+        return connection.prepareStatement(sql, columnIndexes);
+    }
+
+    @Override
+    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
+        checkStatus();
+
+        return connection.prepareStatement(sql, columnNames);
+    }
+
+    @Override
+    public Clob createClob() throws SQLException {
+        checkStatus();
+
+        return connection.createClob();
+    }
+
+    @Override
+    public Blob createBlob() throws SQLException {
+        checkStatus();
+
+        return connection.createBlob();
+    }
+
+    @Override
+    public NClob createNClob() throws SQLException {
+        checkStatus();
+
+        return connection.createNClob();
+    }
+
+    @Override
+    public SQLXML createSQLXML() throws SQLException {
+        checkStatus();
+
+        return connection.createSQLXML();
+    }
+
+    @Override
+    public boolean isValid(int timeout) throws SQLException {
+        checkStatus();
+
+        return connection.isValid(timeout);
+    }
+
+    @Override
+    public void setClientInfo(String name, String value) throws SQLClientInfoException {
+        checkStatus();
+
+        connection.setClientInfo(name, value);
+    }
+
+    @Override
+    public void setClientInfo(Properties properties) throws SQLClientInfoException {
+        checkStatus();
+
+        connection.setClientInfo(properties);
+    }
+
+    @Override
+    public String getClientInfo(String name) throws SQLException {
+        checkStatus();
+
+        return connection.getClientInfo(name);
+    }
+
+    @Override
+    public Properties getClientInfo() throws SQLException {
+        checkStatus();
+
+        return connection.getClientInfo();
+    }
+
+    @Override
+    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
+        checkStatus();
+
+        return connection.createArrayOf(typeName, elements);
+    }
+
+    @Override
+    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
+        checkStatus();
+
+        return connection.createStruct(typeName, attributes);
+    }
+
+    @Override
+    public void setSchema(String schema) throws SQLException {
+        checkStatus();
+
+        connection.setSchema(schema);
+    }
+
+    @Override
+    public String getSchema() throws SQLException {
+        checkStatus();
+
+        return connection.getSchema();
+    }
+
+    @Override
+    public void abort(Executor executor) throws SQLException {
+        checkStatus();
+
+        connection.abort(executor);
+    }
+
+    @Override
+    public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+        checkStatus();
+
+        connection.setNetworkTimeout(executor, milliseconds);
+    }
+
+    @Override
+    public int getNetworkTimeout() throws SQLException {
+        checkStatus();
+
+        return connection.getNetworkTimeout();
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        checkStatus();
+
+        return connection.unwrap(iface);
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        checkStatus();
+
+        return connection.isWrapperFor(iface);
+    }
+
+    @Override
+    public boolean isBusy() {
+        return isBusy;
+    }
+
+    @Override
+    public void setBusy(boolean busy) {
+        isBusy = busy;
+    }
+
+    @Override
+    public Connection getConnection() {
+        return connection;
+    }
+
+    @Override
+    public void setConnection(Connection connection) {
+        this.connection = connection;
+    }
+
+    @Override
+    public IPooledDataSourceConfig getDataSource() {
+        return dataSource;
+    }
+
+    @Override
+    public void setDataSource(IPooledDataSourceConfig dataSource) {
+        this.dataSource = dataSource;
+    }
+
+    /**
+     * 对于设置为繁忙的连接,等价于关闭
+     * @since 1.4.0
+     */
+    private void checkStatus() {
+        if(!isBusy) {
+            throw new JdbcPoolException("Connection has been closed");
+        }
+    }
+
+}

+ 71 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/constant/JdbcConstants.java

@@ -0,0 +1,71 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant;
+
+/**
+ * Created by raodeming on 2021/3/19.
+ */
+public class JdbcConstants {
+   public final static String JTDS = "jtds";
+   public final static String MOCK = "mock";
+   public final static String HSQL = "hsql";
+   public final static String DB2 = "db2";
+   public final static String DB2_DRIVER = "COM.ibm.db2.jdbc.app.DB2Driver";
+   public final static String POSTGRESQL = "postgresql";
+   public final static String POSTGRESQL_DRIVER = "org.postgresql.Driver";
+   public final static String SYBASE = "sybase";
+   public final static String SQL_SERVER = "sqlserver";
+   public final static String SQL_SERVER_DRIVER = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
+   public final static String SQL_SERVER_DRIVER_SQLJDBC4 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
+   public final static String SQL_SERVER_DRIVER_JTDS = "net.sourceforge.jtds.jdbc.Driver";
+   public final static String ORACLE = "oracle";
+   public final static String ORACLE_DRIVER = "oracle.jdbc.OracleDriver";
+   public final static String ORACLE_DRIVER2 = "oracle.jdbc.driver.OracleDriver";
+   public final static String ALI_ORACLE = "AliOracle";
+   public final static String ALI_ORACLE_DRIVER = "com.alibaba.jdbc.AlibabaDriver";
+   public final static String MYSQL = "mysql";
+   public final static String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
+   public final static String MYSQL_DRIVER_6 = "com.mysql.cj.jdbc.Driver";
+   public final static String MYSQL_DRIVER_REPLICATE = "com.mysql.jdbc.";
+   public final static String MARIADB = "mariadb";
+   public final static String MARIADB_DRIVER = "org.mariadb.jdbc.Driver";
+   public final static String DERBY = "derby";
+   public final static String HBASE = "hbase";
+   public final static String HIVE = "hive";
+   public final static String HIVE_DRIVER = "org.apache.hive.jdbc.HiveDriver";
+   public final static String H2 = "h2";
+   public final static String H2_DRIVER = "org.h2.Driver";
+   public final static String DM = "dm";
+   public final static String DM_DRIVER = "dm.jdbc.driver.DmDriver";
+   public final static String KINGBASE = "kingbase";
+   public final static String KINGBASE_DRIVER = "com.kingbase.Driver";
+   public final static String GBASE = "gbase";
+   public final static String GBASE_DRIVER = "com.gbase.jdbc.Driver";
+   public final static String XUGU = "xugu";
+   public final static String XUGU_DRIVER = "com.xugu.cloudjdbc.Driver";
+   public final static String OCEANBASE = "oceanbase";
+   public final static String OCEANBASE_DRIVER = "com.mysql.jdbc.Driver";
+   public final static String INFORMIX = "informix";
+   public final static String ODPS = "odps";
+   public final static String ODPS_DRIVER = "com.aliyun.odps.jdbc.OdpsDriver";
+   public final static String TERADATA = "teradata";
+   public final static String TERADATA_DRIVER = "com.teradata.jdbc.TeraDriver";
+   public final static String LOG4JDBC = "log4jdbc";
+   public final static String LOG4JDBC_DRIVER = "net.sf.log4jdbc.DriverSpy";
+   public final static String PHOENIX = "phoenix";
+   public final static String PHOENIX_DRIVER = "org.apache.phoenix.jdbc.PhoenixDriver";
+   public final static String ENTERPRISEDB = "edb";
+   public final static String ENTERPRISEDB_DRIVER = "com.edb.Driver";
+   public final static String KYLIN = "kylin";
+   public final static String KYLIN_DRIVER = "org.apache.kylin.jdbc.Driver";
+   public final static String SQLITE = "sqlite";
+   public final static String SQLITE_DRIVER = "org.sqlite.JDBC";
+   public final static String ALIYUN_ADS = "aliyun_ads";
+   public final static String ALIYUN_DRDS = "aliyun_drds";
+   public final static String PRESTO = "presto";
+   public final static String ELASTIC_SEARCH = "elasticsearch";
+   public final static String ELASTIC_SEARCH_SQL = "elasticsearch_sql";
+   public final static String ELASTIC_SEARCH_DRIVER = "com.alibaba.xdriver.elastic.jdbc.ElasticDriver";
+   public final static String CLICKHOUSE = "clickhouse";
+   public final static String CLICKHOUSE_DRIVER = "ru.yandex.clickhouse.ClickHouseDriver";
+   public final static String KUDU_IMAPLA = "kudu_impala";
+   public final static String HTTP = "http";
+}

+ 71 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/constant/PooledConst.java

@@ -0,0 +1,71 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant;
+
+/**
+ * 线程池常量
+ * @since 1.1.0
+ */
+public final class PooledConst {
+
+    private PooledConst(){}
+
+    /**
+     * 默认的最小连接数
+     * @since 1.1.0
+     */
+    public static final int DEFAULT_MIN_SIZE = 10;
+
+    /**
+     * 默认最大的连接数
+     * @since 1.1.0
+     */
+    public static final int DEFAULT_MAX_SIZE = 300;
+
+    /**
+     * 默认最大的等待毫秒数
+     *
+     * 默认:1 min
+     *
+     * @since 1.3.0
+     */
+    public static final int DEFAULT_MAX_WAIT_MILLS = 60 * 1000;
+
+    /**
+     * 默认验证查询的语句
+     * @since 1.5.0
+     */
+    public static final String DEFAULT_VALID_QUERY = "select 1 from dual";
+
+    /**
+     * 默认的验证的超时时间
+     * @since 1.5.0
+     */
+    public static final int DEFAULT_VALID_TIME_OUT_SECONDS = 5;
+
+    /**
+     * 获取连接时,默认不校验
+     * @since 1.5.0
+     */
+    public static final boolean DEFAULT_TEST_ON_BORROW = false;
+
+
+    /**
+     * 归还连接时,默认不校验
+     * @since 1.5.0
+     */
+    public static final boolean DEFAULT_TEST_ON_RETURN = false;
+
+    /**
+     * 默认闲暇的时候,进行校验
+     *
+     * @since 1.5.0
+     */
+    public static final boolean DEFAULT_TEST_ON_IDLE = true;
+
+    /**
+     * 1min 自动校验一次
+     *
+     * @since 1.5.0
+     */
+    public static final long DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS = 60;
+
+}

+ 68 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/AbstractDataSourceConfig.java

@@ -0,0 +1,68 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
+
+/**
+ * @author binbin.hou
+ * @since 1.0.0
+ */
+public class AbstractDataSourceConfig extends DataSourceConfigAdaptor {
+
+    /**
+     * 驱动类
+     * @since 1.0.0
+     */
+    protected String driverClass;
+
+    /**
+     * jdbc url
+     * @since 1.0.0
+     */
+    protected String jdbcUrl;
+
+    /**
+     * 用户
+     * @since 1.0.0
+     */
+    protected String user;
+
+    /**
+     * 密码
+     * @since 1.0.0
+     */
+    protected String password;
+
+    public String getDriverClass() {
+        return driverClass;
+    }
+
+    @Override
+    public void setDriverClass(String driverClass) {
+        this.driverClass = driverClass;
+    }
+
+    public String getJdbcUrl() {
+        return jdbcUrl;
+    }
+
+    @Override
+    public void setJdbcUrl(String jdbcUrl) {
+        this.jdbcUrl = jdbcUrl;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    @Override
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    @Override
+    public void setPassword(String password) {
+        this.password = password;
+    }
+}

+ 159 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/AbstractPooledDataSourceConfig.java

@@ -0,0 +1,159 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.ILifeCycle;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IPooledDataSourceConfig;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant.PooledConst;
+
+/**
+ * @author binbin.hou
+ * @since 1.1.0
+ */
+public abstract class AbstractPooledDataSourceConfig extends AbstractDataSourceConfig
+        implements IPooledDataSourceConfig, ILifeCycle {
+
+    /**
+     * 最小尺寸
+     * @since 1.1.0
+     */
+    protected int minSize = PooledConst.DEFAULT_MIN_SIZE;
+
+    /**
+     * 最大尺寸
+     * @since 1.1.0
+     */
+    protected int maxSize = PooledConst.DEFAULT_MAX_SIZE;
+
+    /**
+     * 最大的等待时间
+     * @since 1.3.0
+     */
+    protected long maxWaitMills = PooledConst.DEFAULT_MAX_WAIT_MILLS;
+
+    /**
+     * 验证查询
+     * @since 1.5.0
+     */
+    protected String validQuery = PooledConst.DEFAULT_VALID_QUERY;
+
+    /**
+     * 验证的超时时间
+     * @since 1.5.0
+     */
+    protected int validTimeOutSeconds = PooledConst.DEFAULT_VALID_TIME_OUT_SECONDS;
+
+    /**
+     * 获取时验证
+     * @since 1.5.0
+     */
+    protected boolean testOnBorrow = PooledConst.DEFAULT_TEST_ON_BORROW;
+
+    /**
+     * 归还时验证
+     * @since 1.5.0
+     */
+    protected boolean testOnReturn = PooledConst.DEFAULT_TEST_ON_RETURN;
+
+    /**
+     * 闲暇时验证
+     * @since 1.5.0
+     */
+    protected boolean testOnIdle = PooledConst.DEFAULT_TEST_ON_IDLE;
+
+    /**
+     * 闲暇时验证的时间间隔
+     * @since 1.5.0
+     */
+    protected long testOnIdleIntervalSeconds = PooledConst.DEFAULT_TEST_ON_IDLE_INTERVAL_SECONDS;
+
+    public int getMinSize() {
+        return minSize;
+    }
+
+    @Override
+    public void setMinSize(int minSize) {
+        this.minSize = minSize;
+    }
+
+    public int getMaxSize() {
+        return maxSize;
+    }
+
+    @Override
+    public void setMaxSize(int maxSize) {
+        this.maxSize = maxSize;
+    }
+
+    public long getMaxWaitMills() {
+        return maxWaitMills;
+    }
+
+    @Override
+    public void setMaxWaitMills(long maxWaitMills) {
+        this.maxWaitMills = maxWaitMills;
+    }
+
+    public String getValidQuery() {
+        return validQuery;
+    }
+
+    @Override
+    public void setValidQuery(String validQuery) {
+        this.validQuery = validQuery;
+    }
+
+    public int getValidTimeOutSeconds() {
+        return validTimeOutSeconds;
+    }
+
+    @Override
+    public void setValidTimeOutSeconds(int validTimeOutSeconds) {
+        this.validTimeOutSeconds = validTimeOutSeconds;
+    }
+
+    public boolean isTestOnBorrow() {
+        return testOnBorrow;
+    }
+
+    @Override
+    public void setTestOnBorrow(boolean testOnBorrow) {
+        this.testOnBorrow = testOnBorrow;
+    }
+
+    public boolean isTestOnReturn() {
+        return testOnReturn;
+    }
+
+    @Override
+    public void setTestOnReturn(boolean testOnReturn) {
+        this.testOnReturn = testOnReturn;
+    }
+
+    public boolean isTestOnIdle() {
+        return testOnIdle;
+    }
+
+    @Override
+    public void setTestOnIdle(boolean testOnIdle) {
+        this.testOnIdle = testOnIdle;
+    }
+
+    public long getTestOnIdleIntervalSeconds() {
+        return testOnIdleIntervalSeconds;
+    }
+
+    @Override
+    public void setTestOnIdleIntervalSeconds(long testOnIdleIntervalSeconds) {
+        this.testOnIdleIntervalSeconds = testOnIdleIntervalSeconds;
+    }
+
+    @Override
+    public void init() {
+
+    }
+
+    @Override
+    public void destroy() {
+
+    }
+
+}

+ 82 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/DataSourceConfigAdaptor.java

@@ -0,0 +1,82 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.api.IDataSourceConfig;
+
+import java.io.PrintWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.util.logging.Logger;
+
+/**
+ * @author binbin.hou
+ * @since 1.0.0
+ */
+public class DataSourceConfigAdaptor implements IDataSourceConfig {
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        return null;
+    }
+
+    @Override
+    public Connection getConnection(String username, String password) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return null;
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return false;
+    }
+
+    @Override
+    public PrintWriter getLogWriter() throws SQLException {
+        return null;
+    }
+
+    @Override
+    public void setLogWriter(PrintWriter out) throws SQLException {
+
+    }
+
+    @Override
+    public void setLoginTimeout(int seconds) throws SQLException {
+
+    }
+
+    @Override
+    public int getLoginTimeout() throws SQLException {
+        return 0;
+    }
+
+    @Override
+    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+        return null;
+    }
+
+    @Override
+    public void setDriverClass(String driverClass) {
+
+    }
+
+    @Override
+    public void setJdbcUrl(String jdbcUrl) {
+
+    }
+
+    @Override
+    public void setUser(String user) {
+
+    }
+
+    @Override
+    public void setPassword(String password) {
+
+    }
+
+}

+ 240 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/PooledDataSource.java

@@ -0,0 +1,240 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection.IPooledConnection;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.connection.PooledConnection;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.exception.JdbcPoolException;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util.DriverClassUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 池化的数据源
+ *
+ * @author binbin.hou
+ * @since 1.1.0
+ */
+@Slf4j
+public class PooledDataSource extends AbstractPooledDataSourceConfig {
+
+    /**
+     * 内置的队列
+     *
+     * @since 1.1.0
+     */
+    private List<IPooledConnection> pool = new ArrayList<>();
+
+    @Override
+    public synchronized void init() {
+        DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl);
+
+        this.initJdbcPool();
+
+        // 初始化 idle check
+        this.initTestOnIdle();
+    }
+
+    @Override
+    public synchronized Connection getConnection() throws SQLException {
+        //1. 获取第一个不是 busy 的连接
+        Optional<IPooledConnection> connectionOptional = getFreeConnectionFromPool();
+        if (connectionOptional.isPresent()) {
+            return connectionOptional.get();
+        }
+
+        //2. 考虑是否可以扩容
+        if (pool.size() >= maxSize) {
+            //2.1 立刻返回
+            if (maxWaitMills <= 0) {
+                throw new JdbcPoolException("Can't get connection from pool!");
+            }
+
+
+            //2.2 循环等待
+            final long startWaitMills = System.currentTimeMillis();
+            final long endWaitMills = startWaitMills + maxWaitMills;
+            while (System.currentTimeMillis() < endWaitMills) {
+                Optional<IPooledConnection> optional = getFreeConnectionFromPool();
+                if (optional.isPresent()) {
+                    return optional.get();
+                }
+
+                try {
+                    TimeUnit.MILLISECONDS.sleep(1);
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+                log.debug("等待连接池归还,wait for 1 mills");
+            }
+
+            //2.3 等待超时
+            throw new JdbcPoolException("Can't get connection from pool, wait time out for mills: " + maxWaitMills);
+        }
+
+        //3. 扩容(暂时只扩容一个)
+        log.debug("开始扩容连接池大小,step: 1");
+        IPooledConnection pooledConnection = createPooledConnection();
+        pooledConnection.setBusy(true);
+        this.pool.add(pooledConnection);
+        log.debug("从扩容后的连接池中获取连接");
+        return pooledConnection;
+    }
+
+    @Override
+    public void returnConnection(IPooledConnection pooledConnection) {
+        // 验证状态
+        if (testOnReturn) {
+            checkValid(pooledConnection);
+        }
+
+        // 设置为不繁忙
+        pooledConnection.setBusy(false);
+        log.debug("归还连接,状态设置为不繁忙");
+    }
+
+    /**
+     * 获取空闲的连接
+     *
+     * @return 连接
+     * @since 1.3.0
+     */
+    private Optional<IPooledConnection> getFreeConnectionFromPool() {
+        for (IPooledConnection pc : pool) {
+            if (!pc.isBusy()) {
+                pc.setBusy(true);
+                log.debug("从连接池中获取连接");
+
+                // 验证有效性
+                if (testOnBorrow) {
+                    log.debug("Test on borrow start");
+                    checkValid(pc);
+                    log.debug("Test on borrow finish");
+                }
+
+                return Optional.of(pc);
+            }
+        }
+        // 空
+        return Optional.empty();
+    }
+
+
+    /**
+     * https://stackoverflow.com/questions/3668506/efficient-sql-test-query-or-validation-query-that-will-work-across-all-or-most
+     * <p>
+     * 真正支持标准的,直接使用 {@link Connection#isValid(int)} 验证比较合适
+     *
+     * @param pooledConnection 连接池信息
+     * @since 1.5.0
+     */
+    private void checkValid(final IPooledConnection pooledConnection) {
+        if (StringUtils.isNotEmpty(super.validQuery)) {
+            Connection connection = pooledConnection.getConnection();
+            try {
+                // 如果连接无效,重新申请一个新的替代
+                if (!connection.isValid(super.validTimeOutSeconds)) {
+                    log.debug("Old connection is inValid, start create one for it.");
+
+                    Connection newConnection = createConnection();
+                    pooledConnection.setConnection(newConnection);
+                    log.debug("Old connection is inValid, finish create one for it.");
+                }
+            } catch (SQLException throwables) {
+                throw new JdbcPoolException(throwables);
+            }
+        } else {
+            log.debug("valid query is empty, ignore valid.");
+        }
+    }
+
+    /**
+     * 初始化连接池
+     *
+     * @since 1.1.0
+     */
+    private void initJdbcPool() {
+        final int minSize = super.minSize;
+        pool = new ArrayList<>(minSize);
+
+        for (int i = 0; i < minSize; i++) {
+            IPooledConnection pooledConnection = createPooledConnection();
+
+            pool.add(pooledConnection);
+        }
+    }
+
+    /**
+     * 创建一个池化的连接
+     *
+     * @return 连接
+     * @since 1.1.0
+     */
+    private IPooledConnection createPooledConnection() {
+        Connection connection = createConnection();
+
+        IPooledConnection pooledConnection = new PooledConnection();
+        pooledConnection.setBusy(false);
+        pooledConnection.setConnection(connection);
+        pooledConnection.setDataSource(this);
+
+        return pooledConnection;
+    }
+
+    /**
+     * 创建新连接
+     *
+     * @return 连接
+     * @since 1.1.0
+     */
+    private Connection createConnection() {
+        try {
+            if (StringUtils.isBlank(super.getUser()) && StringUtils.isBlank(super.getPassword())) {
+                return DriverManager.getConnection(super.getJdbcUrl());
+            }
+            return DriverManager.getConnection(super.getJdbcUrl(),
+                    super.getUser(), super.getPassword());
+        } catch (SQLException e) {
+            throw new JdbcPoolException(e);
+        }
+    }
+
+
+    /**
+     * 初始化空闲时检验
+     *
+     * @since 1.5.0
+     */
+    private void initTestOnIdle() {
+        if (StringUtils.isNotEmpty(validQuery)) {
+            ScheduledExecutorService idleExecutor = Executors.newSingleThreadScheduledExecutor();
+
+            idleExecutor.scheduleAtFixedRate(this::testOnIdleCheck, super.testOnIdleIntervalSeconds, testOnIdleIntervalSeconds, TimeUnit.SECONDS);
+            log.debug("Test on idle config with interval seonds: " + testOnIdleIntervalSeconds);
+        }
+    }
+
+    /**
+     * 验证所有的空闲连接是否有效
+     *
+     * @since 1.5.0
+     */
+    private void testOnIdleCheck() {
+        log.debug("start check test on idle");
+        for (IPooledConnection pc : this.pool) {
+            if (!pc.isBusy()) {
+                checkValid(pc);
+            }
+        }
+        log.debug("finish check test on idle");
+    }
+
+}

+ 26 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/datasource/UnPooledDataSource.java

@@ -0,0 +1,26 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util.DriverClassUtil;
+import org.apache.commons.lang3.StringUtils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+/**
+ * @author binbin.hou
+ * @since 1.0.0
+ */
+public class UnPooledDataSource extends AbstractDataSourceConfig {
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        DriverClassUtil.loadDriverClass(super.driverClass, super.jdbcUrl);
+        if (StringUtils.isBlank(super.getUser()) && StringUtils.isBlank(super.getPassword())) {
+            return DriverManager.getConnection(super.jdbcUrl);
+        }
+        return DriverManager.getConnection(super.getJdbcUrl(),
+                super.getUser(), super.getPassword());
+    }
+
+}

+ 28 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/exception/JdbcPoolException.java

@@ -0,0 +1,28 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.exception;
+
+/**
+ * @author binbin.hou
+ * @since 1.0.0
+ */
+public class JdbcPoolException extends RuntimeException {
+
+    public JdbcPoolException() {
+    }
+
+    public JdbcPoolException(String message) {
+        super(message);
+    }
+
+    public JdbcPoolException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public JdbcPoolException(Throwable cause) {
+        super(cause);
+    }
+
+    public JdbcPoolException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+}

+ 13 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/util/DataSourceHandleUtil.java

@@ -0,0 +1,13 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util;
+
+/**
+ * Created by raodeming on 2021/3/19.
+ */
+public class DataSourceHandleUtil {
+
+
+    public static void mysqlConnection() {
+
+
+    }
+}

+ 89 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/util/DriverClassUtil.java

@@ -0,0 +1,89 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util;
+
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Created by raodeming on 2021/4/19.
+ */
+public final class DriverClassUtil {
+
+    /**
+     * 存放驱动类信息
+     */
+    private static final Map<String, String> DRIVER_CLASS_MAP;
+
+    static {
+        DRIVER_CLASS_MAP = new HashMap<>(32);
+        DRIVER_CLASS_MAP.put("jdbc:db2", "COM.ibm.db2.jdbc.app.DB2Driver");
+        DRIVER_CLASS_MAP.put("jdbc:firebirdsql", "org.firebirdsql.jdbc.FBDriver");
+        DRIVER_CLASS_MAP.put("jdbc:edbc", "ca.edbc.jdbc.EdbcDriver");
+        DRIVER_CLASS_MAP.put("jdbc:pointbase", "com.pointbase.jdbc.jdbcUniversalDriver");
+        DRIVER_CLASS_MAP.put("jdbc:fake", "com.alibaba.druid.mock.MockDriver");
+        DRIVER_CLASS_MAP.put("jdbc:informix-sqli", "com.informix.jdbc.IfxDriver");
+        DRIVER_CLASS_MAP.put("jdbc:sqlite", "org.sqlite.JDBC");
+        DRIVER_CLASS_MAP.put("jdbc:microsoft", "com.microsoft.jdbc.sqlserver.SQLServerDriver");
+        DRIVER_CLASS_MAP.put("jdbc:hsqldb", "org.hsqldb.jdbcDriver");
+        DRIVER_CLASS_MAP.put("jdbc:postgresql", "org.postgresql.Driver");
+        DRIVER_CLASS_MAP.put("jdbc:ingres", "com.ingres.jdbc.IngresDriver");
+        DRIVER_CLASS_MAP.put("jdbc:cloudscape", "COM.cloudscape.core.JDBCDriver");
+        DRIVER_CLASS_MAP.put("jdbc:JSQLConnect", "com.jnetdirect.jsql.JSQLDriver");
+        DRIVER_CLASS_MAP.put("jdbc:derby", "org.apache.derby.jdbc.EmbeddedDriver");
+        DRIVER_CLASS_MAP.put("jdbc:timesten", "com.timesten.jdbc.TimesTenDriver");
+        DRIVER_CLASS_MAP.put("jdbc:interbase", "interbase.interclient.Driver");
+        DRIVER_CLASS_MAP.put("jdbc:h2", "org.h2.Driver");
+        DRIVER_CLASS_MAP.put("jdbc:as400", "com.ibm.as400.access.AS400JDBCDriver");
+        DRIVER_CLASS_MAP.put("jdbc:sybase:Tds", "com.sybase.jdbc2.jdbc.SybDriver");
+        DRIVER_CLASS_MAP.put("jdbc:mock", "com.alibaba.druid.mock.MockDriver");
+        DRIVER_CLASS_MAP.put("jdbc:oracle", "oracle.jdbc.driver.OracleDriver");
+        DRIVER_CLASS_MAP.put("jdbc:mysql", "com.mysql.jdbc.Driver");
+        DRIVER_CLASS_MAP.put("jdbc:odps", "com.aliyun.odps.jdbc.OdpsDriver");
+        DRIVER_CLASS_MAP.put("jdbc:mckoi", "com.mckoi.JDBCDriver");
+        DRIVER_CLASS_MAP.put("jdbc:jtds", "net.sourceforge.jtds.jdbc.Driver");
+        DRIVER_CLASS_MAP.put("jdbc:sapdb", "com.sap.dbtech.jdbc.DriverSapDB");
+        DRIVER_CLASS_MAP.put("jdbc:JTurbo", "com.newatlanta.jturbo.driver.Driver");
+        DRIVER_CLASS_MAP.put("jdbc:mimer:multi1", "com.mimer.jdbc.Driver");
+    }
+
+    /**
+     * 加载驱动类信息
+     * @param driverClass 驱动类
+     * @param url 连接信息
+     */
+    public static void loadDriverClass(String driverClass, final String url) {
+        if(StringUtils.isEmpty(driverClass)) {
+            driverClass = getDriverClassByUrl(url);
+        }
+
+        try {
+            Class.forName(driverClass);
+        } catch (ClassNotFoundException e) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.CLASS_NOT_FOUND, e.getMessage());
+        }
+    }
+
+
+    /**
+     * 根据 URL 获取对应的驱动类
+     *
+     * 1. 禁止 url 为空
+     * 2. 如果未找到,则直接报错。
+     * @param url url
+     * @return 驱动信息
+     */
+    private static String getDriverClassByUrl(final String url) {
+        for(Map.Entry<String, String> entry : DRIVER_CLASS_MAP.entrySet()) {
+            String urlPrefix = entry.getKey();
+            if(url.startsWith(urlPrefix)) {
+                return entry.getValue();
+            }
+        }
+
+        throw BusinessExceptionBuilder.build(RespCommonCode.CLASS_NOT_FOUND, "Can't auto find match driver class for url: " + url);
+    }
+
+}

+ 100 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/pool/util/JdbcUtil.java

@@ -0,0 +1,100 @@
+package com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util;
+
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource.PooledDataSource;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.datasource.UnPooledDataSource;
+import lombok.extern.slf4j.Slf4j;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Created by raodeming on 2021/3/18.
+ */
+@Slf4j
+public class JdbcUtil {
+
+    private static Lock lock = new ReentrantLock();
+
+    private static Lock deleteLock = new ReentrantLock();
+
+    //所有数据源的连接池存在map里
+    static Map<Long, PooledDataSource> map = new HashMap<>();
+
+    public static PooledDataSource getJdbcConnectionPool(DataSourceDto dataSource) {
+        if (map.containsKey(dataSource.getId())) {
+            return map.get(dataSource.getId());
+        } else {
+            lock.lock();
+            try {
+                log.debug(Thread.currentThread().getName() + "获取锁");
+                if (!map.containsKey(dataSource.getId())) {
+                    PooledDataSource pool = new PooledDataSource();
+                    pool.setJdbcUrl(dataSource.getJdbcUrl());
+                    pool.setUser(dataSource.getUsername());
+                    pool.setPassword(dataSource.getPassword());
+                    pool.setDriverClass(dataSource.getDriverName());
+                    pool.init();
+                    map.put(dataSource.getId(), pool);
+                    log.info("创建连接池成功:{}", dataSource.getJdbcUrl());
+                }
+                return map.get(dataSource.getId());
+            }  finally {
+                lock.unlock();
+            }
+        }
+    }
+
+    /**
+     * 删除数据库连接池
+     * @param id
+     */
+    public static void removeJdbcConnectionPool(Long id) {
+        deleteLock.lock();
+        try {
+            PooledDataSource pool = map.get(id);
+            if (pool != null) {
+                map.remove(id);
+            }
+        } catch (Exception e) {
+            log.error(e.toString());
+        } finally {
+            deleteLock.unlock();
+        }
+
+    }
+
+    /**
+     * 获取连接
+     * @param dataSource
+     * @return
+     * @throws SQLException
+     */
+    public static Connection getPooledConnection(DataSourceDto dataSource) throws SQLException {
+        PooledDataSource pool = getJdbcConnectionPool(dataSource);
+        return pool.getConnection();
+    }
+
+    /**
+     * 测试数据库连接  获取一个连接
+     * @param dataSource
+     * @return
+     * @throws ClassNotFoundException  driverName不正确
+     * @throws SQLException
+     */
+    public static Connection getUnPooledConnection(DataSourceDto dataSource) throws SQLException {
+        UnPooledDataSource source = new UnPooledDataSource();
+        source.setJdbcUrl(dataSource.getJdbcUrl());
+        source.setDriverClass(dataSource.getDriverName());
+        source.setUser(dataSource.getUsername());
+        source.setPassword(dataSource.getPassword());
+        return source.getConnection();
+    }
+
+
+
+}

+ 48 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/service/DataSourceService.java

@@ -0,0 +1,48 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSource.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.DataSourceParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
+
+import java.util.List;
+
+/**
+* @desc DataSource 数据集服务接口
+* @author Raod
+* @date 2021-03-18 12:09:57.728203200
+**/
+public interface DataSourceService extends GaeaBaseService<DataSourceParam, DataSource> {
+
+    /**
+     * 获取所有数据源
+     * @return
+     */
+    List<DataSource> queryAllDataSource();
+
+    /**
+     * 测试 连接
+     * @param connectionParam
+     * @return
+     */
+    Boolean testConnection(ConnectionParam connectionParam);
+
+    /**
+     * 执行sql
+     * @param dto
+     * @return
+     */
+    List<JSONObject> execute(DataSourceDto dto);
+
+    /**
+     * 执行sql,统计数据total
+     * @param dataSourceDto
+     * @param dto
+     * @return
+     */
+    long total(DataSourceDto dataSourceDto, DataSetDto dto);
+}

+ 384 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/dataSource/service/impl/DataSourceServiceImpl.java

@@ -0,0 +1,384 @@
+
+package com.anjiplus.template.gaea.business.modules.data.dataSource.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.anji.plus.gaea.constant.Enabled;
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
+import com.anji.plus.gaea.utils.GaeaAssert;
+import com.anjiplus.template.gaea.business.code.ResponseCode;
+import com.anjiplus.template.gaea.business.modules.data.dataSet.controller.dto.DataSetDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSetParam.service.DataSetParamService;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.dto.DataSourceDto;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.controller.param.ConnectionParam;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.DataSourceMapper;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.dao.entity.DataSource;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.constant.JdbcConstants;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.pool.util.JdbcUtil;
+import com.anjiplus.template.gaea.business.modules.data.dataSource.service.DataSourceService;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Raod
+ * @desc DataSource 数据集服务实现
+ * @date 2021-03-18 12:09:57.728203200
+ **/
+@Service
+@Slf4j
+public class DataSourceServiceImpl implements DataSourceService {
+
+    @Autowired
+    private DataSourceMapper dataSourceMapper;
+
+    @Resource(name = "dataSourceRestTemplate")
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private DataSetParamService dataSetParamService;
+
+    @Override
+    public GaeaBaseMapper<DataSource> getMapper() {
+        return dataSourceMapper;
+    }
+
+
+    /**
+     * 获取所有数据源
+     * @return
+     */
+    @Override
+    public List<DataSource> queryAllDataSource() {
+        LambdaQueryWrapper<DataSource> wrapper = Wrappers.lambdaQuery();
+        wrapper.select(DataSource::getSourceCode, DataSource::getSourceName)
+                .eq(DataSource::getEnableFlag, Enabled.YES.getValue());
+        return dataSourceMapper.selectList(wrapper);
+    }
+
+    /**
+     * 测试 连接
+     *
+     * @param connectionParam
+     * @return
+     */
+    @Override
+    public Boolean testConnection(ConnectionParam connectionParam) {
+        String sourceType = connectionParam.getSourceType();
+        String sourceConfig = connectionParam.getSourceConfig();
+        DataSourceDto dto = new DataSourceDto();
+        dto.setSourceConfig(sourceConfig);
+        switch (sourceType) {
+            case JdbcConstants.ELASTIC_SEARCH_SQL:
+                testElasticsearchSqlConnection(dto);
+                break;
+            case JdbcConstants.MYSQL:
+            case JdbcConstants.KUDU_IMAPLA:
+                testRelationalDb(dto);
+                break;
+            case JdbcConstants.HTTP:
+                testHttp(dto);
+                break;
+            default:
+                throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_TYPE_DOES_NOT_MATCH_TEMPORARILY);
+        }
+        return true;
+
+    }
+
+    @Override
+    public List<JSONObject> execute(DataSourceDto dto) {
+        String sourceType = dto.getSourceType();
+        switch (sourceType) {
+            case JdbcConstants.ELASTIC_SEARCH_SQL:
+                return executeElasticsearchSql(dto);
+            case JdbcConstants.MYSQL:
+            case JdbcConstants.KUDU_IMAPLA:
+                return executeRelationalDb(dto);
+            case JdbcConstants.HTTP:
+                return executeHttp(dto);
+            default:
+                throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_TYPE_DOES_NOT_MATCH_TEMPORARILY);
+        }
+    }
+
+    /**
+     * 执行sql,统计数据total
+     *
+     * @param dto
+     * @return
+     */
+    @Override
+    public long total(DataSourceDto sourceDto, DataSetDto dto) {
+        //区分数据类型
+        String sourceType = sourceDto.getSourceType();
+        switch (sourceType) {
+            case JdbcConstants.ELASTIC_SEARCH_SQL:
+                return 0;
+            case JdbcConstants.MYSQL:
+                return mysqlTotal(sourceDto, dto);
+            default:
+                throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_TYPE_DOES_NOT_MATCH_TEMPORARILY);
+        }
+
+    }
+
+    /**
+     * 获取mysql count 和添加limit分页信息
+     * @param sourceDto
+     * @param dto
+     * @return
+     */
+    public long mysqlTotal(DataSourceDto sourceDto, DataSetDto dto){
+        String dynSentence = sourceDto.getDynSentence();
+        String sql = "select count(1) as count from (" + dynSentence + ") as gaeaExecute";
+        sourceDto.setDynSentence(sql);
+        List<JSONObject> result = execute(sourceDto);
+
+        //sql 拼接 limit 分页信息
+        int pageNumber = Integer.parseInt(dto.getContextData().getOrDefault("pageNumber", "1").toString());
+        int pageSize = Integer.parseInt(dto.getContextData().getOrDefault("pageSize", "10").toString());
+        String sqlLimit = " limit " + (pageNumber - 1) * pageSize + "," + pageSize;
+        sourceDto.setDynSentence(dynSentence.concat(sqlLimit));
+        log.info("当前total:{}, 添加分页参数,sql语句:{}", JSONObject.toJSONString(result), sourceDto.getDynSentence());
+        return result.get(0).getLongValue("count");
+    }
+
+
+
+    public List<JSONObject> executeElasticsearchSql(DataSourceDto dto) {
+        analysisHttpConfig(dto);
+        HttpHeaders headers = new HttpHeaders();
+        headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
+        HttpEntity<String> entity = new HttpEntity<>(dto.getDynSentence(), headers);
+        ResponseEntity<JSONObject> exchange;
+        try {
+            exchange = restTemplate.exchange(dto.getApiUrl(), HttpMethod.valueOf(dto.getMethod()), entity, JSONObject.class);
+        } catch (Exception e) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
+        }
+        if (exchange.getStatusCode().isError()) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
+        }
+        List<JSONObject> result;
+        try {
+            JSONObject body = exchange.getBody();
+            //解析es sql数据
+            if (null == body) {
+                return null;
+            }
+            JSONArray columns = body.getJSONArray("columns");
+            JSONArray rows = body.getJSONArray("rows");
+            result = new ArrayList<>();
+            for (int i = 0; i < rows.size(); i++) {
+                JSONArray row = rows.getJSONArray(i);
+                JSONObject jsonObject = new JSONObject();
+                for (int j = 0; j < row.size(); j++) {
+                    String name = columns.getJSONObject(j).getString("name");
+                    String value = row.getString(j);
+                    jsonObject.put(name, value);
+                }
+                result.add(jsonObject);
+            }
+        } catch (Exception e) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.ANALYSIS_DATA_ERROR, e.getMessage());
+        }
+        return result;
+    }
+
+    public List<JSONObject> executeRelationalDb(DataSourceDto dto) {
+        analysisRelationalDbConfig(dto);
+        Connection pooledConnection = null;
+        try {
+            pooledConnection = JdbcUtil.getPooledConnection(dto);
+
+            PreparedStatement statement = pooledConnection.prepareStatement(dto.getDynSentence());
+            ResultSet rs = statement.executeQuery();
+
+            int columnCount = rs.getMetaData().getColumnCount();
+
+            List<String> columns = new ArrayList<>();
+            for (int i = 1; i <= columnCount; i++) {
+                String columnName = rs.getMetaData().getColumnLabel(i);
+                columns.add(columnName);
+            }
+            List<JSONObject> list = new ArrayList<>();
+            while (rs.next()) {
+                JSONObject jo = new JSONObject();
+                columns.forEach(t -> {
+                    try {
+                        Object value = rs.getObject(t);
+                        jo.put(t, value);
+                    } catch (SQLException throwable) {
+                        throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_SQL_ERROR, throwable.getMessage());
+                    }
+                });
+                list.add(jo);
+            }
+            return list;
+        } catch (Exception throwable) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.EXECUTE_SQL_ERROR, throwable.getMessage());
+        } finally {
+            try {
+                pooledConnection.close();
+            } catch (SQLException throwable) {
+                throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, throwable.getMessage());
+            }
+        }
+    }
+
+    /**
+     * http 执行获取数据
+     *
+     * @param dto
+     */
+    public List<JSONObject> executeHttp(DataSourceDto dto) {
+        analysisHttpConfig(dto);
+        HttpHeaders headers = new HttpHeaders();
+        headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
+        HttpEntity<String> entity = new HttpEntity<>(dto.getDynSentence(), headers);
+        ResponseEntity<JSONObject> exchange;
+        try {
+            exchange = restTemplate.exchange(dto.getApiUrl(), HttpMethod.valueOf(dto.getMethod()), entity, JSONObject.class);
+        } catch (Exception e) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
+        }
+        if (exchange.getStatusCode().isError()) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
+        }
+        JSONObject body = exchange.getBody();
+        List<JSONObject> result = new ArrayList<>();
+        result.add(body);
+        return result;
+    }
+
+    /**
+     * 关系型数据库 测试连接
+     *
+     * @param dto
+     */
+    public void testRelationalDb(DataSourceDto dto) {
+        analysisRelationalDbConfig(dto);
+        try {
+            Connection unPooledConnection = JdbcUtil.getUnPooledConnection(dto);
+            String catalog = unPooledConnection.getCatalog();
+            log.info("数据库测试连接成功:{}", catalog);
+            unPooledConnection.close();
+        } catch (Exception e) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
+        }
+    }
+
+    /**
+     * http 测试连接
+     *
+     * @param dto
+     */
+    public void testHttp(DataSourceDto dto) {
+        analysisHttpConfig(dto);
+        String apiUrl = dto.getApiUrl();
+        String method = dto.getMethod();
+        String body = dto.getBody();
+        HttpHeaders headers = new HttpHeaders();
+        headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
+        HttpEntity<String> entity = new HttpEntity<>(body, headers);
+        ResponseEntity<Object> exchange;
+        try {
+            exchange = restTemplate.exchange(apiUrl, HttpMethod.valueOf(method), entity, Object.class);
+            if (exchange.getStatusCode().isError()) {
+                throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
+            }
+        } catch (RestClientException e) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
+        }
+    }
+
+
+    /**
+     * 关系型数据库 测试连接
+     *
+     * @param dto
+     */
+    public void testElasticsearchSqlConnection(DataSourceDto dto) {
+        analysisHttpConfig(dto);
+        String apiUrl = dto.getApiUrl();
+        String method = dto.getMethod();
+        String body = dto.getBody();
+        HttpHeaders headers = new HttpHeaders();
+        headers.setAll(JSONObject.parseObject(dto.getHeader(), Map.class));
+        HttpEntity<String> entity = new HttpEntity<>(body, headers);
+        ResponseEntity<Object> exchange;
+        try {
+            exchange = restTemplate.exchange(apiUrl, HttpMethod.valueOf(method), entity, Object.class);
+            if (exchange.getStatusCode().isError()) {
+                throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, exchange.getBody());
+            }
+        } catch (RestClientException e) {
+            throw BusinessExceptionBuilder.build(RespCommonCode.DATA_SOURCE_CONNECTION_FAILED, e.getMessage());
+        }
+
+    }
+
+
+    public void analysisRelationalDbConfig(DataSourceDto dto) {
+        JSONObject json = JSONObject.parseObject(dto.getSourceConfig());
+        GaeaAssert.isFalse(json.containsKey("jdbcUrl"), ResponseCode.PARAM_IS_NULL,"jdbcUrl not empty");
+        GaeaAssert.isFalse(json.containsKey("driverName"), ResponseCode.PARAM_IS_NULL,"driverName not empty");
+        String jdbcUrl = json.getString("jdbcUrl");
+        String username = json.getString("username");
+        String password = json.getString("password");
+        String driverName = json.getString("driverName");
+        dto.setJdbcUrl(jdbcUrl);
+        dto.setDriverName(driverName);
+        dto.setUsername(username);
+        dto.setPassword(password);
+    }
+
+
+    /**
+     * es通过api获取数据
+     *
+     * @param dto
+     * @return
+     */
+    public void analysisHttpConfig(DataSourceDto dto) {
+        JSONObject json = JSONObject.parseObject(dto.getSourceConfig());
+        GaeaAssert.isFalse(json.containsKey("apiUrl"), ResponseCode.PARAM_IS_NULL,"apiUrl not empty");
+        GaeaAssert.isFalse(json.containsKey("method"), ResponseCode.PARAM_IS_NULL,"method not empty");
+        GaeaAssert.isFalse(json.containsKey("header"), ResponseCode.PARAM_IS_NULL,"header not empty");
+        GaeaAssert.isFalse(json.containsKey("body"), ResponseCode.PARAM_IS_NULL,"body not empty");
+        String apiUrl = json.getString("apiUrl");
+        String method = json.getString("method");
+        String header = json.getString("header");
+        String body = json.getString("body");
+        //解决url中存在的动态参数
+        apiUrl = dataSetParamService.transform(dto.getContextData(), apiUrl);
+        //请求头中动态参数
+        header = dataSetParamService.transform(dto.getContextData(), header);
+        dto.setApiUrl(apiUrl);
+        dto.setMethod(method);
+        dto.setHeader(header);
+        dto.setBody(body);
+    }
+
+
+}

+ 25 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/constant/ExpConstant.java

@@ -0,0 +1,25 @@
+package com.anjiplus.template.gaea.business.modules.data.report.constant;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ */
+public class ExpConstant {
+
+    public static final String[] FUNCTION = new String[]{"=SUM(", "=AVERAGE(", "=MAX(", "=MIN(", "=IF(", "=AND(", "=OR(", "=CONCAT("};
+
+    public static List<Integer> getExpFunction(String e) {
+        List<Integer> counts = new ArrayList<>();
+        for (int i = 0; i < FUNCTION.length; i++) {
+            if(e.contains(FUNCTION[i])){
+                counts.add(i);
+            }
+        }
+
+        return counts;
+    }
+
+}

+ 60 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/controller/ReportController.java

@@ -0,0 +1,60 @@
+package com.anjiplus.template.gaea.business.modules.data.report.controller;
+
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.report.controller.dto.ReportDto;
+import com.anjiplus.template.gaea.business.modules.data.report.controller.param.ReportParam;
+import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
+import com.anjiplus.template.gaea.business.modules.data.report.service.ReportService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * TODO
+ *
+ * @author chenkening
+ * @date 2021/3/26 10:19
+ */
+@RestController
+@Api(tags = "报表数据管理")
+@RequestMapping("/report")
+public class ReportController extends GaeaBaseController<ReportParam, Report, ReportDto> {
+
+    @Autowired
+    private ReportService reportService;
+
+    @Override
+    public GaeaBaseService<ReportParam, Report> getService() {
+        return reportService;
+    }
+
+    @Override
+    public Report getEntity() {
+        return new Report();
+    }
+
+    @Override
+    public ReportDto getDTO() {
+        return new ReportDto();
+    }
+
+    @DeleteMapping("/delReport")
+    @Permission(
+            code = "DELETE",
+            name = "删除"
+    )
+    @GaeaAuditLog(
+            pageTitle = "删除"
+    )
+    public ResponseBean delReport(@RequestBody ReportDto reportDto) {
+        reportService.delReport(reportDto);
+        return ResponseBean.builder().build();
+    }
+}

+ 44 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/controller/dto/ReportDto.java

@@ -0,0 +1,44 @@
+package com.anjiplus.template.gaea.business.modules.data.report.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * TODO
+ *
+ * @author chenkening
+ * @date 2021/3/26 10:34
+ */
+@Data
+public class ReportDto extends GaeaBaseDTO implements Serializable {
+
+    /** 报表名称 */
+    private String reportName;
+
+    /** 报表编码 */
+    private String reportCode;
+
+    /**数据集编码,以|分割*/
+    private String setCodes;
+
+    /** 分组 */
+    private String reportGroup;
+
+    /** 备注 */
+    private String reportDesc;
+
+    /** 数据集查询参数 */
+    private String setParam;
+
+    /** 报表json字符串 */
+    private String jsonStr;
+
+    /** 报表类型 */
+    private String reportType;
+
+    /** 数据总计 */
+    private long total;
+
+}

+ 30 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/controller/param/ReportParam.java

@@ -0,0 +1,30 @@
+package com.anjiplus.template.gaea.business.modules.data.report.controller.param;
+
+import com.anji.plus.gaea.annotation.Query;
+import com.anji.plus.gaea.constant.QueryEnum;
+import com.anji.plus.gaea.curd.params.PageParam;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * TODO
+ *
+ * @author chenkening
+ * @date 2021/3/26 10:40
+ */
+@Data
+public class ReportParam extends PageParam implements Serializable{
+
+    /** 报表名称 */
+    @Query(QueryEnum.LIKE)
+    private String reportName;
+
+    /** 报表编码 */
+    @Query(QueryEnum.LIKE)
+    private String reportCode;
+
+    /** 报表类型 */
+    @Query(QueryEnum.EQ)
+    private String reportType;
+}

+ 13 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/dao/ReportMapper.java

@@ -0,0 +1,13 @@
+package com.anjiplus.template.gaea.business.modules.data.report.dao;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
+
+/**
+ * TODO
+ *
+ * @author chenkening
+ * @date 2021/3/26 10:19
+ */
+public interface ReportMapper extends GaeaBaseMapper<Report> {
+}

+ 41 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/dao/entity/Report.java

@@ -0,0 +1,41 @@
+package com.anjiplus.template.gaea.business.modules.data.report.dao.entity;
+
+import com.anji.plus.gaea.annotation.Unique;
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.anjiplus.template.gaea.common.RespCommonCode;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * TODO
+ *
+ * @author chenkening
+ * @date 2021/3/26 10:20
+ */
+@TableName(value="gaea_report")
+@Data
+public class Report extends GaeaBaseEntity {
+
+    @ApiModelProperty(value = "名称")
+    private String reportName;
+
+    @ApiModelProperty(value = "报表编码")
+    @Unique(code = RespCommonCode.REPORT_CODE_ISEXIST)
+    private String reportCode;
+
+    @ApiModelProperty(value = "分组")
+    private String reportGroup;
+
+    @ApiModelProperty(value = "报表描述")
+    private String reportDesc;
+
+    @ApiModelProperty(value = "报表类型")
+    private String reportType;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
+    private Integer deleteFlag;
+}

+ 17 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/service/ReportService.java

@@ -0,0 +1,17 @@
+package com.anjiplus.template.gaea.business.modules.data.report.service;
+
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.report.controller.dto.ReportDto;
+import com.anjiplus.template.gaea.business.modules.data.report.controller.param.ReportParam;
+import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
+
+/**
+ * TODO
+ *
+ * @author chenkening
+ * @date 2021/3/26 10:35
+ */
+public interface ReportService extends GaeaBaseService<ReportParam, Report> {
+
+    void delReport(ReportDto reportDto);
+}

+ 45 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/report/service/impl/ReportServiceImpl.java

@@ -0,0 +1,45 @@
+package com.anjiplus.template.gaea.business.modules.data.report.service.impl;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.report.controller.dto.ReportDto;
+import com.anjiplus.template.gaea.business.modules.data.report.dao.ReportMapper;
+import com.anjiplus.template.gaea.business.modules.data.report.dao.entity.Report;
+import com.anjiplus.template.gaea.business.modules.data.report.service.ReportService;
+import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.ReportExcelMapper;
+import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity.ReportExcel;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * TODO
+ *
+ * @author chenkening
+ * @date 2021/3/26 10:35
+ */
+@Service
+public class ReportServiceImpl implements ReportService {
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+    @Autowired
+    private ReportMapper reportMapper;
+
+    @Autowired
+    private ReportExcelMapper reportExcelMapper;
+
+    @Override
+    public GaeaBaseMapper<Report> getMapper() {
+        return reportMapper;
+    }
+
+
+    @Override
+    public void delReport(ReportDto reportDto) {
+        deleteById(reportDto.getId());
+        QueryWrapper<ReportExcel> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("report_code" , reportDto.getReportCode());
+        reportExcelMapper.delete(queryWrapper);
+    }
+}

+ 97 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/controller/ReportExcelController.java

@@ -0,0 +1,97 @@
+package com.anjiplus.template.gaea.business.modules.data.reportexcel.controller;
+
+import com.anji.plus.gaea.annotation.Permission;
+import com.anji.plus.gaea.annotation.log.GaeaAuditLog;
+import com.anji.plus.gaea.bean.ResponseBean;
+import com.anji.plus.gaea.code.ResponseCode;
+import com.anji.plus.gaea.curd.controller.GaeaBaseController;
+import com.anji.plus.gaea.curd.service.GaeaBaseService;
+import com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.dto.ReportExcelDto;
+import com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.param.ReportExcelParam;
+import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity.ReportExcel;
+import com.anjiplus.template.gaea.business.modules.data.reportexcel.service.ReportExcelService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author chenkening
+ * @date 2021/4/13 15:12
+ */
+@RestController
+@Api(tags = "报表表格管理")
+@RequestMapping("/reportExcel")
+public class ReportExcelController extends GaeaBaseController<ReportExcelParam, ReportExcel, ReportExcelDto> {
+
+    @Autowired
+    private ReportExcelService reportExcelService;
+
+    @Override
+    public GaeaBaseService<ReportExcelParam, ReportExcel> getService() {
+        return reportExcelService;
+    }
+
+    @Override
+    public ReportExcel getEntity() {
+        return new ReportExcel();
+    }
+
+    @Override
+    public ReportExcelDto getDTO() {
+        return new ReportExcelDto();
+    }
+
+    @GetMapping("/detailByReportCode/{reportCode}")
+    @Permission(
+            code = "DETAIL",
+            name = "详情"
+    )
+    @GaeaAuditLog(
+            pageTitle = "详情"
+    )
+    public ResponseBean detailByReportCode(@PathVariable String reportCode) {
+        ReportExcelDto reportExcelDto = reportExcelService.detailByReportCode(reportCode);
+        return ResponseBean.builder().data(reportExcelDto).build();
+    }
+
+    @PostMapping("/preview")
+    @Permission(
+            code = "DETAIL",
+            name = "预览"
+    )
+    @GaeaAuditLog(
+            pageTitle = "预览"
+    )
+    public ResponseBean preview(@RequestBody ReportExcelDto reportExcelDto) {
+        ReportExcelDto result = reportExcelService.preview(reportExcelDto);
+        return ResponseBean.builder().data(result).build();
+    }
+
+
+    @PostMapping("/exportExcel")
+    @Permission(
+            code = "IMPORT",
+            name = "导出"
+    )
+    @GaeaAuditLog(
+            pageTitle = "报表导出"
+    )
+    public ResponseBean exportExcel(@RequestBody ReportExcelDto reportExcelDto) {
+
+        return ResponseBean.builder().code(ResponseCode.SUCCESS_CODE)
+                .data(reportExcelService.exportExcel(reportExcelDto))
+                .message("导出成功,请稍后在下载中心查看").build();
+    }
+
+//    @PostMapping("/exportPdf")
+//    public ResponseBean exportPdf(@RequestBody ReportExcelDto reportExcelDto) {
+//        reportExcelService.exportPdf(reportExcelDto);
+//        return ResponseBean.builder().code(ResponseCode.SUCCESS_CODE)
+//                .build();
+//    }
+}

+ 43 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/controller/dto/ReportExcelDto.java

@@ -0,0 +1,43 @@
+
+package com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.dto;
+
+import com.anji.plus.gaea.curd.dto.GaeaBaseDTO;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+ * @author chenkening
+ * @date 2021/4/13 15:12
+ */
+@Data
+public class ReportExcelDto extends GaeaBaseDTO implements Serializable {
+    /** 报表名称 */
+    private String reportName;
+
+    /** 报表编码 */
+    private String reportCode;
+
+    /**数据集编码,以|分割*/
+    private String setCodes;
+
+    /** 分组 */
+    private String reportGroup;
+
+    /** 数据集查询参数 */
+    private String setParam;
+
+    /** 报表json字符串 */
+    private String jsonStr;
+
+    /** 报表类型 */
+    private String reportType;
+
+    /** 数据总计 */
+    private long total;
+
+    /**导出类型*/
+    private String exportType;
+
+}

+ 18 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/controller/param/ReportExcelParam.java

@@ -0,0 +1,18 @@
+
+package com.anjiplus.template.gaea.business.modules.data.reportexcel.controller.param;
+
+import com.anji.plus.gaea.curd.params.PageParam;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+/**
+ * @author chenkening
+ * @date 2021/4/13 15:12
+ */
+@Data
+public class ReportExcelParam extends PageParam implements Serializable{
+
+
+}

+ 11 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/dao/ReportExcelMapper.java

@@ -0,0 +1,11 @@
+package com.anjiplus.template.gaea.business.modules.data.reportexcel.dao;
+
+import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
+import com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity.ReportExcel;
+
+/**
+ * @author chenkening
+ * @date 2021/4/13 15:11
+ */
+public interface ReportExcelMapper extends GaeaBaseMapper<ReportExcel> {
+}

+ 33 - 0
report-core/src/main/java/com/anjiplus/template/gaea/business/modules/data/reportexcel/dao/entity/ReportExcel.java

@@ -0,0 +1,33 @@
+package com.anjiplus.template.gaea.business.modules.data.reportexcel.dao.entity;
+
+import com.anji.plus.gaea.curd.entity.GaeaBaseEntity;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author chenkening
+ * @date 2021/4/13 15:11
+ */
+@TableName(value="gaea_report_excel")
+@Data
+public class ReportExcel extends GaeaBaseEntity {
+
+    @ApiModelProperty(value = "报表编码")
+    private String reportCode;
+
+    @ApiModelProperty(value = "数据集编码,以|分割")
+    private String setCodes;
+
+    @ApiModelProperty(value = "数据集查询参数")
+    private String setParam;
+
+    @ApiModelProperty(value = "报表json字符串")
+    private String jsonStr;
+
+    @ApiModelProperty(value = "0--已禁用 1--已启用  DIC_NAME=ENABLE_FLAG")
+    private Integer enableFlag;
+
+    @ApiModelProperty(value = "0--未删除 1--已删除 DIC_NAME=DELETE_FLAG")
+    private Integer deleteFlag;
+}

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů