修改数据源集成代码
This commit is contained in:
parent
91db1899e0
commit
c0c5f21609
224
backend/db/core_dataset_group.sql
Normal file
224
backend/db/core_dataset_group.sql
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
Navicat Premium Dump SQL
|
||||||
|
|
||||||
|
Source Server : 华为云-mysql数据库
|
||||||
|
Source Server Type : MySQL
|
||||||
|
Source Server Version : 80403 (8.4.3)
|
||||||
|
Source Host : 121.37.111.42:3306
|
||||||
|
Source Schema : dataease
|
||||||
|
|
||||||
|
Target Server Type : MySQL
|
||||||
|
Target Server Version : 80403 (8.4.3)
|
||||||
|
File Encoding : 65001
|
||||||
|
|
||||||
|
Date: 30/05/2025 14:22:13
|
||||||
|
*/
|
||||||
|
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_dataset_group
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_dataset_group`;
|
||||||
|
CREATE TABLE `core_dataset_group` (
|
||||||
|
`id` bigint NOT NULL COMMENT 'ID',
|
||||||
|
`app_id` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用ID 关联应用系统',
|
||||||
|
`name` varchar(128) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '名称',
|
||||||
|
`pid` bigint NULL DEFAULT NULL COMMENT '父级ID',
|
||||||
|
`level` int NULL DEFAULT 0 COMMENT '当前分组处于第几级',
|
||||||
|
`node_type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT 'node类型:folder or dataset',
|
||||||
|
`type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT 'sql,union',
|
||||||
|
`mode` int NULL DEFAULT 0 COMMENT '连接模式:0-直连,1-同步(包括excel、api等数据存在de中的表)',
|
||||||
|
`info` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '关联关系树',
|
||||||
|
`create_by` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '创建人ID',
|
||||||
|
`create_time` bigint NULL DEFAULT NULL COMMENT '创建时间',
|
||||||
|
`qrtz_instance` varchar(1024) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT 'Quartz 实例 ID',
|
||||||
|
`sync_status` varchar(45) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '同步状态',
|
||||||
|
`update_by` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '更新人ID',
|
||||||
|
`last_update_time` bigint NULL DEFAULT 0 COMMENT '最后同步时间',
|
||||||
|
`union_sql` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '关联sql',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = '数据集分组表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_dataset_table
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_dataset_table`;
|
||||||
|
CREATE TABLE `core_dataset_table` (
|
||||||
|
`id` bigint NOT NULL COMMENT 'ID',
|
||||||
|
`app_id` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用ID 关联应用系统',
|
||||||
|
`name` varchar(128) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '名称',
|
||||||
|
`table_name` varchar(128) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '物理表名',
|
||||||
|
`datasource_id` bigint NULL DEFAULT NULL COMMENT '数据源ID',
|
||||||
|
`dataset_group_id` bigint NOT NULL COMMENT '数据集ID',
|
||||||
|
`type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT 'db,sql,union,excel,api',
|
||||||
|
`info` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '表原始信息,表名,sql等',
|
||||||
|
`sql_variable_details` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT 'SQL参数',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = 'table数据集' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_dataset_table_field
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_dataset_table_field`;
|
||||||
|
CREATE TABLE `core_dataset_table_field` (
|
||||||
|
`id` bigint NOT NULL COMMENT 'ID',
|
||||||
|
`datasource_id` bigint NULL DEFAULT NULL COMMENT '数据源ID',
|
||||||
|
`dataset_table_id` bigint NULL DEFAULT NULL COMMENT '数据表ID',
|
||||||
|
`dataset_group_id` bigint NULL DEFAULT NULL COMMENT '数据集ID',
|
||||||
|
`chart_id` bigint NULL DEFAULT NULL COMMENT '图表ID',
|
||||||
|
`origin_name` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '原始字段名',
|
||||||
|
`name` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '字段名用于展示',
|
||||||
|
`description` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '描述',
|
||||||
|
`dataease_name` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT 'de字段名用作唯一标识',
|
||||||
|
`field_short_name` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT 'de字段别名',
|
||||||
|
`group_list` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '分组设置',
|
||||||
|
`other_group` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '未分组的值',
|
||||||
|
`group_type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '维度/指标标识 d:维度,q:指标',
|
||||||
|
`type` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '原始字段类型',
|
||||||
|
`size` int NULL DEFAULT NULL COMMENT '字段长度(允许为空,默认0)',
|
||||||
|
`de_type` int NOT NULL COMMENT 'dataease字段类型:0-文本,1-时间,2-整型数值,3-浮点数值,4-布尔,5-地理位置,6-二进制,7-URL',
|
||||||
|
`de_extract_type` int NOT NULL COMMENT 'de记录的原始类型',
|
||||||
|
`ext_field` int NULL DEFAULT NULL COMMENT '是否扩展字段 0原始 1复制 2计算字段...',
|
||||||
|
`checked` tinyint(1) NULL DEFAULT 1 COMMENT '是否选中',
|
||||||
|
`column_index` int NULL DEFAULT NULL COMMENT '列位置',
|
||||||
|
`last_sync_time` bigint NULL DEFAULT NULL COMMENT '同步时间',
|
||||||
|
`accuracy` int NULL DEFAULT 0 COMMENT '精度',
|
||||||
|
`date_format` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '时间字段类型',
|
||||||
|
`date_format_type` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '时间格式类型',
|
||||||
|
`params` text CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '计算字段参数',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = 'table数据集表字段' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_dataset_table_sql_log
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_dataset_table_sql_log`;
|
||||||
|
CREATE TABLE `core_dataset_table_sql_log` (
|
||||||
|
`id` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL DEFAULT '' COMMENT 'ID',
|
||||||
|
`table_id` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL DEFAULT '' COMMENT '数据集SQL节点ID',
|
||||||
|
`start_time` bigint NULL DEFAULT NULL COMMENT '开始时间',
|
||||||
|
`end_time` bigint NULL DEFAULT NULL COMMENT '结束时间',
|
||||||
|
`spend` bigint NULL DEFAULT NULL COMMENT '耗时(毫秒)',
|
||||||
|
`sql` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '详细信息',
|
||||||
|
`status` varchar(45) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '状态',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = 'table数据集查询sql日志' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_datasource
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_datasource`;
|
||||||
|
CREATE TABLE `core_datasource` (
|
||||||
|
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`app_id` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '应用ID 关联应用系统',
|
||||||
|
`name` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '名称',
|
||||||
|
`description` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '描述',
|
||||||
|
`type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '类型',
|
||||||
|
`pid` bigint NULL DEFAULT NULL COMMENT '父级ID',
|
||||||
|
`edit_type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '更新方式:0:替换;1:追加',
|
||||||
|
`configuration` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '详细信息',
|
||||||
|
`create_time` bigint NOT NULL COMMENT '创建时间',
|
||||||
|
`update_time` bigint NOT NULL COMMENT '更新时间',
|
||||||
|
`update_by` bigint NULL DEFAULT NULL COMMENT '变更人',
|
||||||
|
`create_by` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '创建人ID',
|
||||||
|
`status` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '状态',
|
||||||
|
`qrtz_instance` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '状态',
|
||||||
|
`task_status` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '任务状态',
|
||||||
|
`enable_data_fill` tinyint NULL DEFAULT 0 COMMENT '启用数据填报功能',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1915350839984336899 CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = '数据源表' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_datasource_task
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_datasource_task`;
|
||||||
|
CREATE TABLE `core_datasource_task` (
|
||||||
|
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`ds_id` bigint NOT NULL COMMENT '数据源ID',
|
||||||
|
`name` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '任务名称',
|
||||||
|
`update_type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '更新方式',
|
||||||
|
`start_time` bigint NULL DEFAULT NULL COMMENT '开始时间',
|
||||||
|
`sync_rate` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '执行频率:0 一次性 1 cron',
|
||||||
|
`cron` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT 'cron表达式',
|
||||||
|
`simple_cron_value` bigint NULL DEFAULT NULL COMMENT '简单重复间隔',
|
||||||
|
`simple_cron_type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '简单重复类型:分、时、天',
|
||||||
|
`end_limit` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '结束限制 0 无限制 1 设定结束时间',
|
||||||
|
`end_time` bigint NULL DEFAULT NULL COMMENT '结束时间',
|
||||||
|
`create_time` bigint NULL DEFAULT NULL COMMENT '创建时间',
|
||||||
|
`last_exec_time` bigint NULL DEFAULT NULL COMMENT '上次执行时间',
|
||||||
|
`last_exec_status` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '上次执行结果',
|
||||||
|
`extra_data` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '额外数据',
|
||||||
|
`task_status` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '任务状态',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = '数据源定时同步任务' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_datasource_task_log
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_datasource_task_log`;
|
||||||
|
CREATE TABLE `core_datasource_task_log` (
|
||||||
|
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`ds_id` bigint NOT NULL COMMENT '数据源ID',
|
||||||
|
`task_id` bigint NULL DEFAULT NULL COMMENT '任务ID',
|
||||||
|
`start_time` bigint NULL DEFAULT NULL COMMENT '开始时间',
|
||||||
|
`end_time` bigint NULL DEFAULT NULL COMMENT '结束时间',
|
||||||
|
`task_status` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '执行状态',
|
||||||
|
`table_name` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '表名',
|
||||||
|
`info` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '错误信息',
|
||||||
|
`create_time` bigint NULL DEFAULT NULL COMMENT '创建时间',
|
||||||
|
`trigger_type` varchar(45) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '更新频率类型',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
INDEX `idx_dataset_table_task_log_ds_id`(`ds_id` ASC) USING BTREE,
|
||||||
|
INDEX `idx_dataset_table_task_log_task_id`(`task_id` ASC) USING BTREE,
|
||||||
|
INDEX `idx_dataset_table_task_log_A`(`ds_id` ASC, `table_name` ASC, `start_time` ASC) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1125460897473630209 CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = '数据源定时同步任务执行日志' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_de_engine
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_de_engine`;
|
||||||
|
CREATE TABLE `core_de_engine` (
|
||||||
|
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`name` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '名称',
|
||||||
|
`description` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '描述',
|
||||||
|
`type` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '类型',
|
||||||
|
`configuration` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '详细信息',
|
||||||
|
`create_time` bigint NULL DEFAULT NULL COMMENT 'Create timestamp',
|
||||||
|
`update_time` bigint NULL DEFAULT NULL COMMENT 'Update timestamp',
|
||||||
|
`create_by` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '创建人ID',
|
||||||
|
`status` varchar(45) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '状态',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = '数据引擎' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_driver
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_driver`;
|
||||||
|
CREATE TABLE `core_driver` (
|
||||||
|
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`name` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '名称',
|
||||||
|
`create_time` bigint NOT NULL COMMENT '创建时间',
|
||||||
|
`type` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '数据源类型',
|
||||||
|
`driver_class` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '驱动类',
|
||||||
|
`description` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '描述',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = '驱动' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for core_driver_jar
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `core_driver_jar`;
|
||||||
|
CREATE TABLE `core_driver_jar` (
|
||||||
|
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`de_driver_id` varchar(50) CHARACTER SET utf16 COLLATE utf16_general_ci NOT NULL COMMENT '驱动主键',
|
||||||
|
`file_name` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '名称',
|
||||||
|
`version` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '版本',
|
||||||
|
`driver_class` longtext CHARACTER SET utf16 COLLATE utf16_general_ci NULL COMMENT '驱动类',
|
||||||
|
`trans_name` varchar(255) CHARACTER SET utf16 COLLATE utf16_general_ci NULL DEFAULT NULL COMMENT '替换后的 jar 包名称',
|
||||||
|
`is_trans_name` tinyint(1) NULL DEFAULT NULL COMMENT '是否将上传 jar 包替换了名称(1-是,0-否)',
|
||||||
|
PRIMARY KEY (`id`) USING BTREE
|
||||||
|
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf16 COLLATE = utf16_general_ci COMMENT = '驱动详情' ROW_FORMAT = Dynamic;
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.0.13</version>
|
<version>3.3.0</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.stdproject</groupId>
|
<groupId>com.stdproject</groupId>
|
||||||
@ -14,6 +14,9 @@
|
|||||||
<name>stdproject</name>
|
<name>stdproject</name>
|
||||||
<description>Standard Project Backend</description>
|
<description>Standard Project Backend</description>
|
||||||
<properties>
|
<properties>
|
||||||
|
<spring-boot.version>3.3.0</spring-boot.version>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
<java.version>21</java.version>
|
<java.version>21</java.version>
|
||||||
<mybatis-plus.version>3.5.3</mybatis-plus.version>
|
<mybatis-plus.version>3.5.3</mybatis-plus.version>
|
||||||
<jjwt.version>0.11.5</jjwt.version>
|
<jjwt.version>0.11.5</jjwt.version>
|
||||||
@ -23,6 +26,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -45,6 +49,13 @@
|
|||||||
<artifactId>cache-api</artifactId>
|
<artifactId>cache-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.gisbi</groupId>
|
||||||
|
<artifactId>sdk-bundle</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${project.basedir}/libs/sdk-bundle-2.0.jar</systemPath>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
|
@ -13,7 +13,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|||||||
* @author StdProject
|
* @author StdProject
|
||||||
* @since 2023-12-07
|
* @since 2023-12-07
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication(scanBasePackages = {"com.stdproject", "io.gisbi.extensions.datasource.utils", "io.gisbi.i18n"})
|
||||||
@MapperScan("com.stdproject.mapper")
|
@MapperScan("com.stdproject.mapper")
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.stdproject.config;
|
||||||
|
|
||||||
|
import io.gisbi.utils.CommonThreadPool;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线程池配置类
|
||||||
|
*
|
||||||
|
* @author StdProject
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class ThreadPoolConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置CommonThreadPool Bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public CommonThreadPool commonThreadPool() {
|
||||||
|
return new CommonThreadPool();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.stdproject.controller;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.stdproject.common.OperationLog;
|
||||||
|
import com.stdproject.service.IDynamicDataService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 动态数据管理 前端控制器
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author StdProject
|
||||||
|
* @since 2024-01-01
|
||||||
|
*/
|
||||||
|
@Tag(name = "动态数据管理", description = "提供对数据源表数据的增删改查操作")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/dynamicdata")
|
||||||
|
public class DynamicDataController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDynamicDataService dynamicDataService;
|
||||||
|
|
||||||
|
@Operation(summary = "向指定数据源的表中添加数据")
|
||||||
|
@OperationLog(type = "01", module = "动态数据管理", description = "添加表数据")
|
||||||
|
@PostMapping("addTableData")
|
||||||
|
public boolean addTableData(Long datasourceId, @RequestParam("tableData") String tableData) throws Exception {
|
||||||
|
boolean result = dynamicDataService.addTableData(
|
||||||
|
datasourceId,
|
||||||
|
tableData
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@Operation(summary = "根据主键查询表数据")
|
||||||
|
@OperationLog(type = "06", module = "动态数据管理", description = "根据主键查询表数据")
|
||||||
|
@PostMapping("getTableDataByPk")
|
||||||
|
public Map<String, Object> getTableDataByPk(Long datasourceId,@RequestParam("whereJson") String whereJson) throws Exception {
|
||||||
|
Map<String, Object> result=dynamicDataService.getTableDataByPk(
|
||||||
|
datasourceId,
|
||||||
|
whereJson
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "更新表数据")
|
||||||
|
@OperationLog(type = "02", module = "动态数据管理", description = "更新表数据")
|
||||||
|
@PostMapping("updateTableData")
|
||||||
|
public boolean updateTableData(Long datasourceId, @RequestParam("tableData") String tableData) throws Exception {
|
||||||
|
boolean result = dynamicDataService.updateTableData(
|
||||||
|
datasourceId,
|
||||||
|
tableData
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "删除表数据")
|
||||||
|
@OperationLog(type = "03", module = "动态数据管理", description = "删除表数据")
|
||||||
|
@PostMapping("deleteTableData")
|
||||||
|
public boolean deleteTableData(Long datasourceId, @RequestParam("whereJson") String whereJson) throws Exception {
|
||||||
|
boolean result = dynamicDataService.deleteTableData(
|
||||||
|
datasourceId,
|
||||||
|
whereJson
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询表数据")
|
||||||
|
@OperationLog(type = "06", module = "动态数据管理", description = "分页查询表数据")
|
||||||
|
@PostMapping("queryTableDataPaged")
|
||||||
|
public Page<Map<String, Object>> queryTableDataPaged(Long datasourceId, @RequestParam("queryJson") String queryJson) throws Exception {
|
||||||
|
Page<Map<String, Object>> result = dynamicDataService.queryTableDataPaged(
|
||||||
|
datasourceId,
|
||||||
|
queryJson
|
||||||
|
);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.stdproject.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.stdproject.entity.CoreDeEngine;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class EngineRequest {
|
||||||
|
private final String REG_WITH_SQL_FRAGMENT = "((?i)WITH[\\s\\S]+(?i)AS?\\s*\\([\\s\\S]+\\))\\s*(?i)SELECT";
|
||||||
|
private Pattern WITH_SQL_FRAGMENT = Pattern.compile("((?i)WITH[\\s\\S]+(?i)AS?\\s*\\([\\s\\S]+\\))\\s*(?i)SELECT");
|
||||||
|
protected String query;
|
||||||
|
protected String table;
|
||||||
|
protected CoreDeEngine engine;
|
||||||
|
private Integer pageSize;
|
||||||
|
private Integer page;
|
||||||
|
private Integer realSize;
|
||||||
|
private Integer fetchSize = 10000;
|
||||||
|
private boolean pageable = false;
|
||||||
|
private boolean previewData = false;
|
||||||
|
private boolean totalPageFlag;
|
||||||
|
|
||||||
|
public EngineRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQuery() {
|
||||||
|
return this.rebuildSqlWithFragment(this.query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuery(String query) {
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String rebuildSqlWithFragment(String sql) {
|
||||||
|
if (!sql.toLowerCase().startsWith("with")) {
|
||||||
|
Matcher matcher = this.WITH_SQL_FRAGMENT.matcher(sql);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String withFragment = matcher.group();
|
||||||
|
if (!StringUtils.isEmpty(withFragment)) {
|
||||||
|
if (withFragment.length() > 6) {
|
||||||
|
int lastSelectIndex = withFragment.length() - 6;
|
||||||
|
sql = sql.replace(withFragment, withFragment.substring(lastSelectIndex));
|
||||||
|
withFragment = withFragment.substring(0, lastSelectIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql = withFragment + " " + sql;
|
||||||
|
sql = sql.replaceAll(" {2,}", " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getREG_WITH_SQL_FRAGMENT() {
|
||||||
|
this.getClass();
|
||||||
|
return "((?i)WITH[\\s\\S]+(?i)AS?\\s*\\([\\s\\S]+\\))\\s*(?i)SELECT";
|
||||||
|
}
|
||||||
|
}
|
250
backend/src/main/java/com/stdproject/entity/CoreDatasource.java
Normal file
250
backend/src/main/java/com/stdproject/entity/CoreDatasource.java
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
package com.stdproject.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 数据源表
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @Author bi-coder
|
||||||
|
* @since 2024-07-09
|
||||||
|
*/
|
||||||
|
@TableName("core_datasource")
|
||||||
|
public class CoreDatasource implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 应用ID
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父级ID
|
||||||
|
*/
|
||||||
|
private Long pid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新方式:0:替换;1:追加
|
||||||
|
*/
|
||||||
|
private String editType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详细信息
|
||||||
|
*/
|
||||||
|
private String configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Long createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Long updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更人
|
||||||
|
*/
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人ID
|
||||||
|
*/
|
||||||
|
private String createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private String qrtzInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务状态
|
||||||
|
*/
|
||||||
|
private String taskStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启数据填报
|
||||||
|
*/
|
||||||
|
private Boolean enableDataFill;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getPid() {
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPid(Long pid) {
|
||||||
|
this.pid = pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEditType() {
|
||||||
|
return editType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEditType(String editType) {
|
||||||
|
this.editType = editType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfiguration() {
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfiguration(String configuration) {
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Long createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUpdateTime() {
|
||||||
|
return updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdateTime(Long updateTime) {
|
||||||
|
this.updateTime = updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUpdateBy() {
|
||||||
|
return updateBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdateBy(Long updateBy) {
|
||||||
|
this.updateBy = updateBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCreateBy() {
|
||||||
|
return createBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateBy(String createBy) {
|
||||||
|
this.createBy = createBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQrtzInstance() {
|
||||||
|
return qrtzInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQrtzInstance(String qrtzInstance) {
|
||||||
|
this.qrtzInstance = qrtzInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskStatus() {
|
||||||
|
return taskStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskStatus(String taskStatus) {
|
||||||
|
this.taskStatus = taskStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getEnableDataFill() {
|
||||||
|
return enableDataFill;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnableDataFill(Boolean enableDataFill) {
|
||||||
|
this.enableDataFill = enableDataFill;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CoreDatasource{" +
|
||||||
|
"id = " + id +
|
||||||
|
", appId = " + appId +
|
||||||
|
", name = " + name +
|
||||||
|
", description = " + description +
|
||||||
|
", type = " + type +
|
||||||
|
", pid = " + pid +
|
||||||
|
", editType = " + editType +
|
||||||
|
", configuration = " + configuration +
|
||||||
|
", createTime = " + createTime +
|
||||||
|
", updateTime = " + updateTime +
|
||||||
|
", updateBy = " + updateBy +
|
||||||
|
", createBy = " + createBy +
|
||||||
|
", status = " + status +
|
||||||
|
", qrtzInstance = " + qrtzInstance +
|
||||||
|
", taskStatus = " + taskStatus +
|
||||||
|
", enableDataFill = " + enableDataFill +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppId() {
|
||||||
|
return appId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppId(String appId) {
|
||||||
|
this.appId = appId;
|
||||||
|
}
|
||||||
|
}
|
154
backend/src/main/java/com/stdproject/entity/CoreDeEngine.java
Normal file
154
backend/src/main/java/com/stdproject/entity/CoreDeEngine.java
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
package com.stdproject.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @Author bi-coder
|
||||||
|
* @since 2023-04-18
|
||||||
|
*/
|
||||||
|
@TableName("core_de_engine")
|
||||||
|
public class CoreDeEngine implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详细信息
|
||||||
|
*/
|
||||||
|
private String configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create timestamp
|
||||||
|
*/
|
||||||
|
private Long createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update timestamp
|
||||||
|
*/
|
||||||
|
private Long updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人ID
|
||||||
|
*/
|
||||||
|
private String createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfiguration() {
|
||||||
|
return configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfiguration(String configuration) {
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Long createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getUpdateTime() {
|
||||||
|
return updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdateTime(Long updateTime) {
|
||||||
|
this.updateTime = updateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCreateBy() {
|
||||||
|
return createBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateBy(String createBy) {
|
||||||
|
this.createBy = createBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CoreDeEngine{" +
|
||||||
|
"id = " + id +
|
||||||
|
", name = " + name +
|
||||||
|
", description = " + description +
|
||||||
|
", type = " + type +
|
||||||
|
", configuration = " + configuration +
|
||||||
|
", createTime = " + createTime +
|
||||||
|
", updateTime = " + updateTime +
|
||||||
|
", createBy = " + createBy +
|
||||||
|
", status = " + status +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
112
backend/src/main/java/com/stdproject/entity/CoreDriver.java
Normal file
112
backend/src/main/java/com/stdproject/entity/CoreDriver.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package com.stdproject.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 驱动
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @Author bi-coder
|
||||||
|
* @since 2023-04-18
|
||||||
|
*/
|
||||||
|
@TableName("core_driver")
|
||||||
|
public class CoreDriver implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创健时间
|
||||||
|
*/
|
||||||
|
private Long createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据源类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驱动类
|
||||||
|
*/
|
||||||
|
private String driverClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(Long createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriverClass() {
|
||||||
|
return driverClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDriverClass(String driverClass) {
|
||||||
|
this.driverClass = driverClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CoreDriver{" +
|
||||||
|
"id = " + id +
|
||||||
|
", name = " + name +
|
||||||
|
", createTime = " + createTime +
|
||||||
|
", type = " + type +
|
||||||
|
", driverClass = " + driverClass +
|
||||||
|
", description = " + description +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
120
backend/src/main/java/com/stdproject/entity/CoreDriverJar.java
Normal file
120
backend/src/main/java/com/stdproject/entity/CoreDriverJar.java
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
package com.stdproject.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 驱动详情
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @Author bi-coder
|
||||||
|
* @since 2023-04-17
|
||||||
|
*/
|
||||||
|
@TableName("core_driver_jar")
|
||||||
|
public class CoreDriverJar implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驱动主键
|
||||||
|
*/
|
||||||
|
private String deDriverId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 名称
|
||||||
|
*/
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 驱动类
|
||||||
|
*/
|
||||||
|
private String driverClass;
|
||||||
|
|
||||||
|
private String transName;
|
||||||
|
|
||||||
|
private Boolean isTransName;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDeDriverId() {
|
||||||
|
return deDriverId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeDriverId(String deDriverId) {
|
||||||
|
this.deDriverId = deDriverId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDriverClass() {
|
||||||
|
return driverClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDriverClass(String driverClass) {
|
||||||
|
this.driverClass = driverClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTransName() {
|
||||||
|
return transName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransName(String transName) {
|
||||||
|
this.transName = transName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getIsTransName() {
|
||||||
|
return isTransName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsTransName(Boolean isTransName) {
|
||||||
|
this.isTransName = isTransName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CoreDriverJar{" +
|
||||||
|
"id = " + id +
|
||||||
|
", deDriverId = " + deDriverId +
|
||||||
|
", fileName = " + fileName +
|
||||||
|
", version = " + version +
|
||||||
|
", driverClass = " + driverClass +
|
||||||
|
", transName = " + transName +
|
||||||
|
", isTransName = " + isTransName +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.stdproject.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.stdproject.entity.CoreDatasource;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 数据源表 Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @Author bi-coder
|
||||||
|
* @since 2024-07-09
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CoreDatasourceMapper extends BaseMapper<CoreDatasource> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.stdproject.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import com.stdproject.entity.CoreDeEngine;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @Author bi-coder
|
||||||
|
* @since 2023-04-18
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface CoreDeEngineMapper extends BaseMapper<CoreDeEngine> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
package com.stdproject.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态数据服务接口
|
||||||
|
* 提供对数据源表数据的增删改查操作
|
||||||
|
*/
|
||||||
|
public interface IDynamicDataService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向指定数据源的表中添加数据
|
||||||
|
*
|
||||||
|
* @param datasourceId 数据源ID
|
||||||
|
* @param tableData 表数据JSON字符串,格式:
|
||||||
|
* {
|
||||||
|
* "tableName": "user",
|
||||||
|
* "data": [
|
||||||
|
* {
|
||||||
|
* "fieldName": "id",
|
||||||
|
* "fieldType": "varchar",
|
||||||
|
* "IsPrimaryKey": true,
|
||||||
|
* "fieldValue": "0001"
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* "fieldName": "name",
|
||||||
|
* "fieldType": "varchar",
|
||||||
|
* "fieldValue": "张三"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* @return 是否添加成功
|
||||||
|
* @throws Exception 操作异常
|
||||||
|
*/
|
||||||
|
boolean addTableData(Long datasourceId, String tableData) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据主键查询表数据
|
||||||
|
*
|
||||||
|
* @param datasourceId 数据源ID
|
||||||
|
* @param condition 查询条件JSON字符串,格式:
|
||||||
|
* {
|
||||||
|
* "tableName": "user",
|
||||||
|
* "key": [
|
||||||
|
* {
|
||||||
|
* "fieldName": "id",
|
||||||
|
* "fieldValue": "0001"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* @return 查询到的数据Map,如果没有找到则返回null
|
||||||
|
* @throws Exception 操作异常
|
||||||
|
*/
|
||||||
|
Map<String, Object> getTableDataByPk(Long datasourceId, String condition) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新表数据
|
||||||
|
*
|
||||||
|
* @param datasourceId 数据源ID
|
||||||
|
* @param tableData 更新数据JSON字符串,格式:
|
||||||
|
* {
|
||||||
|
* "tableName": "user",
|
||||||
|
* "key": [
|
||||||
|
* {
|
||||||
|
* "fieldName": "id",
|
||||||
|
* "fieldValue": "0001"
|
||||||
|
* }
|
||||||
|
* ],
|
||||||
|
* "data": [
|
||||||
|
* {
|
||||||
|
* "fieldName": "name",
|
||||||
|
* "fieldType": "varchar",
|
||||||
|
* "fieldValue": "李四"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* @return 是否更新成功
|
||||||
|
* @throws Exception 操作异常
|
||||||
|
*/
|
||||||
|
boolean updateTableData(Long datasourceId, String tableData) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除表数据
|
||||||
|
*
|
||||||
|
* @param datasourceId 数据源ID
|
||||||
|
* @param condition 删除条件JSON字符串,格式:
|
||||||
|
* {
|
||||||
|
* "tableName": "user",
|
||||||
|
* "key": [
|
||||||
|
* {
|
||||||
|
* "fieldName": "id",
|
||||||
|
* "fieldValue": "0001"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* @return 是否删除成功
|
||||||
|
* @throws Exception 操作异常
|
||||||
|
*/
|
||||||
|
boolean deleteTableData(Long datasourceId, String condition) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询表数据
|
||||||
|
*
|
||||||
|
* @param datasourceId 数据源ID
|
||||||
|
* @param condition 查询条件JSON字符串,格式:
|
||||||
|
* {
|
||||||
|
* "tableName": "user",
|
||||||
|
* "pageNum": 1,
|
||||||
|
* "pageSize": 10,
|
||||||
|
* "conditions": [
|
||||||
|
* {
|
||||||
|
* "field": "name",
|
||||||
|
* "operator": "like",
|
||||||
|
* "value": "张"
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* "field": "age",
|
||||||
|
* "operator": ">",
|
||||||
|
* "value": 18
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
* @return 分页查询结果
|
||||||
|
* @throws Exception 操作异常
|
||||||
|
*/
|
||||||
|
Page<Map<String, Object>> queryTableDataPaged(Long datasourceId, String condition) throws Exception;
|
||||||
|
}
|
@ -22,6 +22,7 @@ import java.time.LocalDateTime;
|
|||||||
* @author StdProject
|
* @author StdProject
|
||||||
* @since 2023-12-07
|
* @since 2023-12-07
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {
|
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {
|
||||||
|
|
||||||
|
@ -0,0 +1,427 @@
|
|||||||
|
package com.stdproject.service.impl;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.stdproject.common.BusinessException;
|
||||||
|
import com.stdproject.entity.CoreDatasource;
|
||||||
|
import com.stdproject.mapper.CoreDatasourceMapper;
|
||||||
|
import com.stdproject.service.IDynamicDataService;
|
||||||
|
import io.gisbi.extensions.datasource.dto.DatasourceRequest;
|
||||||
|
import io.gisbi.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||||
|
import io.gisbi.extensions.datasource.dto.TableField;
|
||||||
|
import io.gisbi.extensions.datasource.factory.ProviderFactory;
|
||||||
|
import io.gisbi.extensions.datasource.provider.Provider;
|
||||||
|
import io.gisbi.utils.BeanUtils;
|
||||||
|
import io.gisbi.utils.IDUtils;
|
||||||
|
import io.gisbi.utils.JsonUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class DynamicDataServiceImpl implements IDynamicDataService {
|
||||||
|
@Resource
|
||||||
|
private CoreDatasourceMapper coreDatasourceMapper;
|
||||||
|
@Override
|
||||||
|
public boolean addTableData(Long datasourceId, String tableData) throws Exception {
|
||||||
|
// 根据数据源 id 查询数据源信息,调用通用数据源执行器
|
||||||
|
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasourceId);
|
||||||
|
if (coreDatasource == null) {
|
||||||
|
BusinessException.throwException("数据源不存在");
|
||||||
|
}
|
||||||
|
// 解析 tableData JSON 字符串 "{ \"tableName\": \"user\", \"data\": [ { \"fieldName\": \"id\", \"fieldType\": \"varchar\", \"IsPrimaryKey\": true, \"fieldValue\": \"0001\" }, { \"fieldName\": \"name\", \"fieldType\": \"varchar\", \"fieldValue\": \"张三\" } ] }";
|
||||||
|
Map<String, Object> dataMap = JsonUtil.parseObject(tableData, Map.class);
|
||||||
|
String tableName = (String) dataMap.get("tableName");
|
||||||
|
List<Map<String, Object>> fieldList = (List<Map<String, Object>>) dataMap.get("data");
|
||||||
|
|
||||||
|
if (fieldList == null || fieldList.isEmpty()) {
|
||||||
|
BusinessException.throwException("没有可插入的数据字段");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建插入语句
|
||||||
|
StringBuilder columns = new StringBuilder();
|
||||||
|
StringBuilder values = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < fieldList.size(); i++) {
|
||||||
|
Map<String, Object> field = fieldList.get(i);
|
||||||
|
String fieldName = (String) field.get("fieldName");
|
||||||
|
Object fieldValue = field.get("fieldValue");
|
||||||
|
boolean isPrimaryKey = field.get("IsPrimaryKey") != null && (boolean) field.get("IsPrimaryKey");
|
||||||
|
if (isPrimaryKey) {
|
||||||
|
if (fieldValue == null) {fieldValue= IDUtils.snowID();}
|
||||||
|
}
|
||||||
|
if (i > 0) {
|
||||||
|
columns.append(", ");
|
||||||
|
values.append(", ");
|
||||||
|
}
|
||||||
|
columns.append(fieldName);
|
||||||
|
if (fieldValue instanceof String) {
|
||||||
|
values.append("'").append(fieldValue).append("'");
|
||||||
|
} else {
|
||||||
|
values.append(fieldValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String sql = String.format("INSERT INTO %s (%s) VALUES (%s)", tableName, columns.toString(), values.toString());
|
||||||
|
|
||||||
|
// 调用执行器,向数据表中插入 tableData 数据
|
||||||
|
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||||
|
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||||
|
|
||||||
|
Provider provider = ProviderFactory.getProvider(coreDatasource.getType());
|
||||||
|
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||||
|
datasourceRequest.setQuery(sql);
|
||||||
|
datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO));
|
||||||
|
|
||||||
|
log.debug("执行插入数据的SQL: {}", sql);
|
||||||
|
|
||||||
|
// 执行插入操作
|
||||||
|
int result= provider.executeUpdate(datasourceRequest);
|
||||||
|
if (result==1) {
|
||||||
|
return true;
|
||||||
|
// process result set
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getTableDataByPk(Long datasourceId, String condtion) throws Exception {
|
||||||
|
// 获取数据源信息
|
||||||
|
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasourceId);
|
||||||
|
if (coreDatasource == null) {
|
||||||
|
BusinessException.throwException("数据源不存在");
|
||||||
|
}
|
||||||
|
// 解析 JSON 数据
|
||||||
|
//condtion={ \"tableName\": \"user\", key:[{ \"fieldName\": \"id\",\"fieldValue\": \"0001\"]
|
||||||
|
Map<String, Object> dataMap = JsonUtil.parseObject(condtion, Map.class);
|
||||||
|
String tableName = (String) dataMap.get("tableName");
|
||||||
|
// 参数校验
|
||||||
|
if (StringUtils.isBlank(tableName)) {
|
||||||
|
BusinessException.throwException("表名不能为空");
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> keyFields = (List<Map<String, Object>>) dataMap.get("key");
|
||||||
|
if (CollectionUtils.isEmpty(keyFields)) {
|
||||||
|
BusinessException.throwException("主键字段或值不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
String whereClause = buildWhereCondition(keyFields);
|
||||||
|
String sql = String.format("SELECT * FROM %s WHERE %s", tableName, whereClause);
|
||||||
|
// 执行查询操作
|
||||||
|
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||||
|
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||||
|
|
||||||
|
Provider provider = ProviderFactory.getProvider(coreDatasource.getType());
|
||||||
|
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||||
|
datasourceRequest.setQuery(sql);
|
||||||
|
datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO));
|
||||||
|
|
||||||
|
log.debug("执行查询数据的SQL: {}", sql);
|
||||||
|
|
||||||
|
// 获取查询结果
|
||||||
|
Map<String, Object> data = provider.fetchResultField(datasourceRequest);
|
||||||
|
|
||||||
|
// 处理查询结果
|
||||||
|
List<String[]> dataList = (List<String[]>) data.get("data");
|
||||||
|
List<TableField> fields = (List<TableField>) data.get("fields");
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(dataList) || dataList.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将结果转换为 Map 格式
|
||||||
|
String[] row = dataList.get(0);
|
||||||
|
Map<String, Object> resultMap = new LinkedHashMap<>();
|
||||||
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
|
TableField field = fields.get(i);
|
||||||
|
String fieldName = field.getOriginName();
|
||||||
|
resultMap.put(fieldName, row[i]);
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 构建 WHERE 条件字符串,用于多字段主键查询/更新/删除操作
|
||||||
|
*
|
||||||
|
* @param keyFields 主键字段列表,格式如:{ "fieldName": "id", "fieldValue": "0001" }
|
||||||
|
* @return SQL WHERE 子句字符串
|
||||||
|
*/
|
||||||
|
private String buildWhereCondition(List<Map<String, Object>> keyFields) {
|
||||||
|
StringBuilder whereClause = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < keyFields.size(); i++) {
|
||||||
|
Map<String, Object> keyField = keyFields.get(i);
|
||||||
|
String fieldName = (String) keyField.get("fieldName");
|
||||||
|
Object fieldValue = keyField.get("fieldValue");
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
whereClause.append(" AND ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldValue == null) {
|
||||||
|
whereClause.append(fieldName).append(" IS NULL");
|
||||||
|
} else if (fieldValue instanceof String) {
|
||||||
|
whereClause.append(String.format("%s = '%s'", fieldName, fieldValue));
|
||||||
|
} else {
|
||||||
|
whereClause.append(String.format("%s = %s", fieldName, fieldValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return whereClause.toString();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean updateTableData(Long datasourceId, String tableData) throws Exception {
|
||||||
|
// 获取数据源信息
|
||||||
|
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasourceId);
|
||||||
|
if (coreDatasource == null) {
|
||||||
|
BusinessException.throwException("数据源不存在");
|
||||||
|
}
|
||||||
|
//String tableDataJson = "{ \"tableName\": \"user\", key:[{ \"fieldName\": \"id\",\"fieldValue\": \"0001\"], \"data\": [ { \"fieldName\": \"name\", \"fieldType\": \"varchar\", \"fieldValue\": \"李四\" } ] }";
|
||||||
|
// 解析 JSON 数据
|
||||||
|
Map<String, Object> dataMap = JsonUtil.parseObject(tableData, Map.class);
|
||||||
|
String tableName = (String) dataMap.get("tableName");
|
||||||
|
if (StringUtils.isBlank(tableName)) {
|
||||||
|
BusinessException.throwException("表名不能为空");
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> keyFields = (List<Map<String, Object>>) dataMap.get("key");
|
||||||
|
if (CollectionUtils.isEmpty(keyFields)) {
|
||||||
|
BusinessException.throwException("主键字段或值不能为空");
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> fieldList = (List<Map<String, Object>>) dataMap.get("data");
|
||||||
|
if (fieldList == null || fieldList.isEmpty()) {
|
||||||
|
BusinessException.throwException("没有可更新的数据字段");
|
||||||
|
}
|
||||||
|
// 构建 UPDATE 语句
|
||||||
|
StringBuilder setClause = new StringBuilder();
|
||||||
|
for (int i = 0; i < fieldList.size(); i++) {
|
||||||
|
Map<String, Object> field = fieldList.get(i);
|
||||||
|
String fieldName = (String) field.get("fieldName");
|
||||||
|
Object fieldValue = field.get("fieldValue");
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
setClause.append(", ");
|
||||||
|
}
|
||||||
|
if (fieldValue instanceof String) {
|
||||||
|
setClause.append(String.format("%s = '%s'", fieldName, fieldValue));
|
||||||
|
} else {
|
||||||
|
setClause.append(String.format("%s = %s", fieldName, fieldValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String whereClause = buildWhereCondition(keyFields);
|
||||||
|
String sql = String.format("UPDATE %s SET %s WHERE %s", tableName, setClause, whereClause);
|
||||||
|
// 调用执行器执行 SQL
|
||||||
|
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||||
|
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||||
|
|
||||||
|
Provider provider = ProviderFactory.getProvider(coreDatasource.getType());
|
||||||
|
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||||
|
datasourceRequest.setQuery(sql);
|
||||||
|
datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO));
|
||||||
|
|
||||||
|
log.debug("执行更新数据的SQL: {}", sql);
|
||||||
|
|
||||||
|
// 执行更新操作
|
||||||
|
int result= provider.executeUpdate(datasourceRequest);
|
||||||
|
if (result==1) {
|
||||||
|
return true;
|
||||||
|
// process result set
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean deleteTableData(Long datasourceId, String condtion) throws Exception {
|
||||||
|
// 获取数据源信息
|
||||||
|
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasourceId);
|
||||||
|
if (coreDatasource == null) {
|
||||||
|
BusinessException.throwException("数据源不存在"); }
|
||||||
|
|
||||||
|
// 解析 JSON 数据
|
||||||
|
//String tableDataJson = "{ \"tableName\": \"user\", key:[{ \"fieldName\": \"id\",\"fieldValue\": \"0001\"] }";
|
||||||
|
Map<String, Object> dataMap = JsonUtil.parseObject(condtion, Map.class);
|
||||||
|
String tableName = (String) dataMap.get("tableName");
|
||||||
|
if (StringUtils.isBlank(tableName)) {
|
||||||
|
BusinessException.throwException("表名不能为空");
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> keyFields = (List<Map<String, Object>>) dataMap.get("key");
|
||||||
|
if (CollectionUtils.isEmpty(keyFields)) {
|
||||||
|
BusinessException.throwException("主键字段或值不能为空");
|
||||||
|
}
|
||||||
|
String whereClause = buildWhereCondition(keyFields);
|
||||||
|
String sql = String.format("DELETE FROM %s WHERE %s", tableName, whereClause);
|
||||||
|
// 调用执行器执行 SQL
|
||||||
|
DatasourceSchemaDTO datasourceSchemaDTO = new DatasourceSchemaDTO();
|
||||||
|
BeanUtils.copyBean(datasourceSchemaDTO, coreDatasource);
|
||||||
|
|
||||||
|
Provider provider = ProviderFactory.getProvider(coreDatasource.getType());
|
||||||
|
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||||
|
datasourceRequest.setQuery(sql);
|
||||||
|
datasourceRequest.setDsList(Map.of(datasourceSchemaDTO.getId(), datasourceSchemaDTO));
|
||||||
|
|
||||||
|
log.debug("执行删除数据的SQL: {}", sql);
|
||||||
|
|
||||||
|
// 执行删除操作
|
||||||
|
int result= provider.executeUpdate(datasourceRequest);
|
||||||
|
if (result==1) {
|
||||||
|
return true;
|
||||||
|
// process result set
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Page<Map<String, Object>> queryTableDataPaged(Long datasourceId, String condition) throws Exception {
|
||||||
|
// 获取数据源信息
|
||||||
|
CoreDatasource coreDatasource = coreDatasourceMapper.selectById(datasourceId);
|
||||||
|
if (coreDatasource == null) {
|
||||||
|
BusinessException.throwException("数据源不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析 condition JSON 数据
|
||||||
|
Map<String, Object> dataMap = JsonUtil.parseObject(condition, Map.class);
|
||||||
|
String tableName = (String) dataMap.get("tableName");
|
||||||
|
List<Map<String, Object>> conditionList = (List<Map<String, Object>>) dataMap.get("conditions");
|
||||||
|
|
||||||
|
Integer pageNum = (Integer) dataMap.getOrDefault("pageNum", 1);
|
||||||
|
Integer pageSize = (Integer) dataMap.getOrDefault("pageSize", 10);
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(tableName)) {
|
||||||
|
BusinessException.throwException("表名不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建 WHERE 条件子句
|
||||||
|
StringBuilder whereClause = new StringBuilder();
|
||||||
|
if (conditionList != null && !conditionList.isEmpty()) {
|
||||||
|
whereClause.append(" WHERE ");
|
||||||
|
for (int i = 0; i < conditionList.size(); i++) {
|
||||||
|
Map<String, Object> cond = conditionList.get(i);
|
||||||
|
String field = (String) cond.get("field");
|
||||||
|
String operator = ((String) cond.get("operator")).toLowerCase();
|
||||||
|
Object value = cond.get("value");
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
whereClause.append(" AND ");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (operator) {
|
||||||
|
case "like":
|
||||||
|
whereClause.append(String.format("%s LIKE '%%%s%%'", field, value));
|
||||||
|
break;
|
||||||
|
case "=":
|
||||||
|
appendValue(whereClause, field, value, "=");
|
||||||
|
break;
|
||||||
|
case "<":
|
||||||
|
appendValue(whereClause, field, value, "<");
|
||||||
|
break;
|
||||||
|
case ">":
|
||||||
|
appendValue(whereClause, field, value, ">");
|
||||||
|
break;
|
||||||
|
case "<=":
|
||||||
|
appendValue(whereClause, field, value, "<=");
|
||||||
|
break;
|
||||||
|
case ">=":
|
||||||
|
appendValue(whereClause, field, value, ">=");
|
||||||
|
break;
|
||||||
|
case "!=":
|
||||||
|
case "<>":
|
||||||
|
appendValue(whereClause, field, value, "<>");
|
||||||
|
break;
|
||||||
|
case "in":
|
||||||
|
if (!(value instanceof List<?>)) {
|
||||||
|
BusinessException.throwException("IN 操作符要求值为列表类型");
|
||||||
|
}
|
||||||
|
List<?> values = (List<?>) value;
|
||||||
|
String inValues = values.stream()
|
||||||
|
.map(v -> v instanceof String ? "'" + v + "'" : v.toString())
|
||||||
|
.collect(Collectors.joining(", "));
|
||||||
|
whereClause.append(String.format("%s IN (%s)", field, inValues));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BusinessException.throwException("不支持的操作符: " + operator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建基础 SQL
|
||||||
|
String baseSql = String.format("SELECT * FROM %s%s", tableName, whereClause);
|
||||||
|
String dbType = coreDatasource.getType().toLowerCase();
|
||||||
|
String pagedSql = buildPagedSQL(baseSql, dbType, pageNum, pageSize);
|
||||||
|
String countSql = String.format("SELECT COUNT(*) FROM %s%s", tableName, whereClause);
|
||||||
|
|
||||||
|
DatasourceSchemaDTO schemaDTO = new DatasourceSchemaDTO();
|
||||||
|
BeanUtils.copyBean(schemaDTO, coreDatasource);
|
||||||
|
Provider provider = ProviderFactory.getProvider(coreDatasource.getType());
|
||||||
|
DatasourceRequest request = new DatasourceRequest();
|
||||||
|
request.setDsList(Map.of(schemaDTO.getId(), schemaDTO));
|
||||||
|
|
||||||
|
// 查询分页数据
|
||||||
|
request.setQuery(pagedSql);
|
||||||
|
Map<String, Object> result = provider.fetchResultField(request);
|
||||||
|
List<String[]> dataList = (List<String[]>) result.get("data");
|
||||||
|
List<TableField> fields = (List<TableField>) result.get("fields");
|
||||||
|
|
||||||
|
// 查询总记录数
|
||||||
|
request.setQuery(countSql);
|
||||||
|
Map<String, Object> countResult = provider.fetchResultField(request);
|
||||||
|
long total = Long.parseLong(((List<String[]>) countResult.get("data")).get(0)[0]);
|
||||||
|
|
||||||
|
// 将数据封装为 Map 形式
|
||||||
|
List<Map<String, Object>> records = new ArrayList<>();
|
||||||
|
if (!CollectionUtils.isEmpty(dataList)) {
|
||||||
|
for (String[] row : dataList) {
|
||||||
|
Map<String, Object> rowMap = new LinkedHashMap<>();
|
||||||
|
for (int i = 0; i < fields.size() && i < row.length; i++) {
|
||||||
|
String fieldName = fields.get(i).getOriginName();
|
||||||
|
String fieldValue = row[i];
|
||||||
|
rowMap.put(fieldName, fieldValue);
|
||||||
|
}
|
||||||
|
records.add(rowMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回分页结果
|
||||||
|
Page<Map<String, Object>> page = new Page<>();
|
||||||
|
page.setCurrent(pageNum);
|
||||||
|
page.setSize(pageSize);
|
||||||
|
page.setTotal(total);
|
||||||
|
page.setRecords(records);
|
||||||
|
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void appendValue(StringBuilder sb, String field, Object value, String op) {
|
||||||
|
if (value instanceof String) {
|
||||||
|
sb.append(String.format("%s %s '%s'", field, op, value));
|
||||||
|
} else {
|
||||||
|
sb.append(String.format("%s %s %s", field, op, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildPagedSQL(String baseSql, String dbType, int pageNum, int pageSize) {
|
||||||
|
int offset = (pageNum - 1) * pageSize;
|
||||||
|
|
||||||
|
switch (dbType) {
|
||||||
|
case "mysql":
|
||||||
|
case "mariadb":
|
||||||
|
return String.format("%s LIMIT %d OFFSET %d", baseSql, pageSize, offset);
|
||||||
|
case "postgresql":
|
||||||
|
return String.format("%s LIMIT %d OFFSET %d", baseSql, pageSize, offset);
|
||||||
|
case "oracle":
|
||||||
|
int start = offset + 1;
|
||||||
|
int end = offset + pageSize;
|
||||||
|
return String.format("SELECT * FROM (SELECT ROWNUM rn, t.* FROM (%s) t WHERE ROWNUM <= %d) WHERE rn >= %d", baseSql, end, start);
|
||||||
|
case "sqlserver":
|
||||||
|
return String.format("%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", baseSql, offset, pageSize);
|
||||||
|
default:
|
||||||
|
// 默认使用 MySQL 方式
|
||||||
|
return String.format("%s LIMIT %d OFFSET %d", baseSql, pageSize, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,197 @@
|
|||||||
|
package com.stdproject.service.manage;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.stdproject.entity.CoreDatasource;
|
||||||
|
import com.stdproject.entity.CoreDeEngine;
|
||||||
|
import com.stdproject.mapper.CoreDatasourceMapper;
|
||||||
|
import com.stdproject.mapper.CoreDeEngineMapper;
|
||||||
|
import com.stdproject.service.type.H2;
|
||||||
|
import com.stdproject.service.type.Mysql;
|
||||||
|
import io.gisbi.exception.DEException;
|
||||||
|
import io.gisbi.extensions.datasource.dto.DatasourceDTO;
|
||||||
|
import io.gisbi.extensions.datasource.dto.DatasourceRequest;
|
||||||
|
import io.gisbi.extensions.datasource.factory.ProviderFactory;
|
||||||
|
import io.gisbi.result.ResultMessage;
|
||||||
|
import io.gisbi.utils.BeanUtils;
|
||||||
|
import io.gisbi.utils.JsonUtil;
|
||||||
|
import io.gisbi.utils.ModelUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class EngineManage {
|
||||||
|
@Resource
|
||||||
|
private Environment env;
|
||||||
|
@Resource
|
||||||
|
private CoreDeEngineMapper deEngineMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CoreDatasourceMapper datasourceMapper;
|
||||||
|
|
||||||
|
@Value("${gisbi.path.engine:jdbc:h2:/opt/gisbi/desktop_data;AUTO_SERVER=TRUE;AUTO_RECONNECT=TRUE;MODE=MySQL;CASE_INSENSITIVE_IDENTIFIERS=TRUE;DATABASE_TO_UPPER=FALSE}")
|
||||||
|
private String engineUrl;
|
||||||
|
|
||||||
|
|
||||||
|
public CoreDeEngine info() throws DEException {
|
||||||
|
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null);
|
||||||
|
if (CollectionUtils.isEmpty(deEngines)) {
|
||||||
|
DEException.throwException("未完整设置数据引擎");
|
||||||
|
}
|
||||||
|
return deEngines.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CoreDatasource getDeEngine() {
|
||||||
|
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null);
|
||||||
|
if (CollectionUtils.isEmpty(deEngines)) {
|
||||||
|
DEException.throwException("未完整设置数据引擎");
|
||||||
|
}
|
||||||
|
CoreDatasource coreDatasource = new CoreDatasource();
|
||||||
|
BeanUtils.copyBean(coreDatasource, deEngines.get(0));
|
||||||
|
return coreDatasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public CoreDatasource deEngine() {
|
||||||
|
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null);
|
||||||
|
CoreDatasource coreDatasource = new CoreDatasource();
|
||||||
|
if (CollectionUtils.isEmpty(deEngines)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BeanUtils.copyBean(coreDatasource, deEngines.get(0));
|
||||||
|
return coreDatasource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(CoreDeEngine engine) throws Exception {
|
||||||
|
if (StringUtils.isEmpty(engine.getType()) || StringUtils.isEmpty(engine.getConfiguration())) {
|
||||||
|
throw new Exception("未完整设置数据引擎");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
|
||||||
|
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||||
|
DatasourceDTO datasource = new DatasourceDTO();
|
||||||
|
BeanUtils.copyBean(datasource, engine);
|
||||||
|
datasourceRequest.setDatasource(datasource);
|
||||||
|
ProviderFactory.getProvider(engine.getType()).checkStatus(datasourceRequest);
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException("校验失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultMessage save(CoreDeEngine engine) throws Exception {
|
||||||
|
if (engine.getId() == null) {
|
||||||
|
deEngineMapper.insert(engine);
|
||||||
|
} else {
|
||||||
|
deEngineMapper.updateById(engine);
|
||||||
|
}
|
||||||
|
return ResultMessage.success(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initSimpleEngine() throws Exception {
|
||||||
|
initLocalDataSource();
|
||||||
|
QueryWrapper<CoreDeEngine> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (ModelUtils.isDesktop()) {
|
||||||
|
queryWrapper.eq("type", engineType.h2.name());
|
||||||
|
} else {
|
||||||
|
queryWrapper.eq("type", engineType.mysql.name());
|
||||||
|
}
|
||||||
|
List<CoreDeEngine> deEngines = deEngineMapper.selectList(queryWrapper);
|
||||||
|
if (!CollectionUtils.isEmpty(deEngines)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreDeEngine engine = new CoreDeEngine();
|
||||||
|
if (ModelUtils.isDesktop()) {
|
||||||
|
engine.setType(engineType.h2.name());
|
||||||
|
H2 h2 = new H2();
|
||||||
|
h2.setJdbc(engineUrl);
|
||||||
|
h2.setDataBase("PUBLIC");
|
||||||
|
h2.setUsername(env.getProperty("spring.datasource.username"));
|
||||||
|
h2.setPassword(env.getProperty("spring.datasource.password"));
|
||||||
|
engine.setConfiguration(JsonUtil.toJSONString(h2).toString());
|
||||||
|
} else {
|
||||||
|
engine.setType(engineType.mysql.name());
|
||||||
|
Mysql mysqlConfiguration = new Mysql();
|
||||||
|
Pattern WITH_SQL_FRAGMENT = Pattern.compile("jdbc:mysql://(.*):(\\d+)/(.*)");
|
||||||
|
Matcher matcher = WITH_SQL_FRAGMENT.matcher(env.getProperty("spring.datasource.url"));
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mysqlConfiguration.setHost(matcher.group(1));
|
||||||
|
mysqlConfiguration.setPort(Integer.valueOf(matcher.group(2)));
|
||||||
|
String[] databasePrams = matcher.group(3).split("\\?");
|
||||||
|
mysqlConfiguration.setDataBase(databasePrams[0]);
|
||||||
|
if (databasePrams.length == 2) {
|
||||||
|
mysqlConfiguration.setExtraParams(databasePrams[1]);
|
||||||
|
}
|
||||||
|
mysqlConfiguration.setUsername(env.getProperty("spring.datasource.username"));
|
||||||
|
mysqlConfiguration.setPassword(env.getProperty("spring.datasource.password"));
|
||||||
|
engine.setConfiguration(JsonUtil.toJSONString(mysqlConfiguration).toString());
|
||||||
|
}
|
||||||
|
engine.setName("默认引擎");
|
||||||
|
engine.setDescription("默认引擎");
|
||||||
|
deEngineMapper.insert(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum engineType {
|
||||||
|
mysql("Mysql"),
|
||||||
|
h2("h2");
|
||||||
|
private String alias;
|
||||||
|
|
||||||
|
private engineType(String alias) {
|
||||||
|
this.alias = alias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAlias() {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initLocalDataSource() {
|
||||||
|
QueryWrapper<CoreDatasource> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("id", 985188400292302848L);
|
||||||
|
queryWrapper.ne("create_time", 1715053684176L);
|
||||||
|
if (!datasourceMapper.exists(queryWrapper) && !ModelUtils.isDesktop()) {
|
||||||
|
Pattern WITH_SQL_FRAGMENT = Pattern.compile("jdbc:mysql://(.*):(\\d+)/(.*)\\?(.*)");
|
||||||
|
Matcher matcher = WITH_SQL_FRAGMENT.matcher(env.getProperty("spring.datasource.url"));
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map configuration = new HashMap<>();
|
||||||
|
configuration.put("dataBase", matcher.group(3));
|
||||||
|
configuration.put("username", env.getProperty("spring.datasource.username"));
|
||||||
|
configuration.put("password", env.getProperty("spring.datasource.password"));
|
||||||
|
configuration.put("host", matcher.group(1));
|
||||||
|
configuration.put("port", Integer.valueOf(matcher.group(2)));
|
||||||
|
configuration.put("extraParams", "");
|
||||||
|
|
||||||
|
CoreDatasource initDatasource = new CoreDatasource();
|
||||||
|
initDatasource.setId(985188400292302848L);
|
||||||
|
initDatasource.setName("Demo");
|
||||||
|
initDatasource.setType("mysql");
|
||||||
|
initDatasource.setPid(0L);
|
||||||
|
initDatasource.setConfiguration(JsonUtil.toJSONString(configuration).toString());
|
||||||
|
initDatasource.setCreateTime(System.currentTimeMillis());
|
||||||
|
initDatasource.setUpdateTime(System.currentTimeMillis());
|
||||||
|
initDatasource.setCreateBy("1");
|
||||||
|
initDatasource.setUpdateBy(1L);
|
||||||
|
initDatasource.setStatus("success");
|
||||||
|
initDatasource.setTaskStatus("WaitingForExecution");
|
||||||
|
datasourceMapper.deleteById(985188400292302848L);
|
||||||
|
datasourceMapper.insert(initDatasource);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,877 @@
|
|||||||
|
package com.stdproject.service.provider;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.jayway.jsonpath.JsonPath;
|
||||||
|
import io.gisbi.extensions.datasource.dto.ApiDefinition;
|
||||||
|
import io.gisbi.extensions.datasource.dto.ApiDefinitionRequest;
|
||||||
|
import io.gisbi.exception.DEException;
|
||||||
|
import io.gisbi.extensions.datasource.dto.DatasetTableDTO;
|
||||||
|
import io.gisbi.extensions.datasource.dto.DatasourceRequest;
|
||||||
|
import io.gisbi.extensions.datasource.dto.TableField;
|
||||||
|
import io.gisbi.utils.*;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ApiUtils {
|
||||||
|
|
||||||
|
private static String path = "['%s']";
|
||||||
|
public static ObjectMapper objectMapper = CommonBeanFactory.getBean(ObjectMapper.class);
|
||||||
|
|
||||||
|
private static TypeReference<List<Object>> listTypeReference = new TypeReference<List<Object>>() {
|
||||||
|
};
|
||||||
|
private static TypeReference<List<Map<String, Object>>> listForMapTypeReference = new TypeReference<List<Map<String, Object>>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据源配置中解析并获取API数据表信息列表
|
||||||
|
*
|
||||||
|
* @param datasourceRequest 数据源请求对象,包含数据源配置信息
|
||||||
|
* @return 数据集表DTO列表,包含表名称、显示名称及所属数据源ID
|
||||||
|
* @throws DEException 当数据处理过程中出现异常时抛出
|
||||||
|
*/
|
||||||
|
public static List<DatasetTableDTO> getApiTables(DatasourceRequest datasourceRequest) throws DEException {
|
||||||
|
List<DatasetTableDTO> tableDescs = new ArrayList<>();
|
||||||
|
// 定义API配置的反序列化类型引用
|
||||||
|
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
// 从数据源配置中解析API定义列表
|
||||||
|
List<ApiDefinition> apiDefinitionList = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
|
||||||
|
|
||||||
|
for (ApiDefinition apiDefinition : apiDefinitionList) {
|
||||||
|
// 过滤空对象和参数类型配置
|
||||||
|
if (apiDefinition == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(apiDefinition.getType()) && apiDefinition.getType().equalsIgnoreCase("params")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建数据集表信息对象
|
||||||
|
DatasetTableDTO datasetTableDTO = new DatasetTableDTO();
|
||||||
|
datasetTableDTO.setTableName(apiDefinition.getDeTableName());
|
||||||
|
datasetTableDTO.setName(apiDefinition.getName());
|
||||||
|
datasetTableDTO.setDatasourceId(datasourceRequest.getDatasource().getId());
|
||||||
|
tableDescs.add(datasetTableDTO);
|
||||||
|
}
|
||||||
|
return tableDescs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将JSON配置字符串解析为表名映射关系
|
||||||
|
*
|
||||||
|
* @param configration 输入的JSON配置字符串,应包含包含"name"和"deTableName"字段的数组对象
|
||||||
|
* @return 返回键值对映射,key为配置中的name字段值,value为对应的deTableName字段值
|
||||||
|
* @throws DEException 当JSON解析失败时抛出异常
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getTableNamesMap(String configration) throws DEException {
|
||||||
|
Map<String, String> result = new HashMap<>();
|
||||||
|
try {
|
||||||
|
// 解析JSON根节点并遍历数组元素
|
||||||
|
JsonNode rootNode = objectMapper.readTree(configration);
|
||||||
|
for (int i = 0; i < rootNode.size(); i++) {
|
||||||
|
// 提取每个元素的name和deTableName字段构建映射关系
|
||||||
|
result.put(rootNode.get(i).get("name").asText(), rootNode.get(i).get("deTableName").asText());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 统一将底层异常转换为领域异常抛出
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Map<String, Object> fetchApiResultField(DatasourceRequest datasourceRequest) throws DEException {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
List<String[]> dataList = new ArrayList<>();
|
||||||
|
List<TableField> fieldList = new ArrayList<>();
|
||||||
|
ApiDefinition apiDefinition = getApiDefinition(datasourceRequest);
|
||||||
|
if (apiDefinition == null) {
|
||||||
|
DEException.throwException("未找到");
|
||||||
|
}
|
||||||
|
if (apiDefinition.getRequest().getPage() != null && apiDefinition.getRequest().getPage().getPageType() != null && !apiDefinition.getRequest().getPage().getPageType().equalsIgnoreCase("empty")) {
|
||||||
|
String response = execHttpRequest(false, apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
|
||||||
|
fieldList = getTableFields(apiDefinition);
|
||||||
|
result.put("fieldList", fieldList);
|
||||||
|
if (apiDefinition.getRequest().getPage().getPageType().equalsIgnoreCase("pageNumber")) {
|
||||||
|
int pageCount = Integer.valueOf(JsonPath.read(response, apiDefinition.getRequest().getPage().getResponseData().get(0).getResolutionPath()).toString());
|
||||||
|
int beginPage = Integer.valueOf(apiDefinition.getRequest().getPage().getRequestData().get(0).getParameterDefaultValue());
|
||||||
|
if (apiDefinition.getRequest().getPage().getResponseData().get(0).getResolutionPathType().equalsIgnoreCase("totalNumber")) {
|
||||||
|
pageCount = pageCount / Integer.valueOf(apiDefinition.getRequest().getPage().getRequestData().get(1).getParameterDefaultValue()) + 1;
|
||||||
|
}
|
||||||
|
for (int i = beginPage; i <= pageCount; i++) {
|
||||||
|
apiDefinition.getRequest().getPage().getRequestData().get(0).setParameterDefaultValue(String.valueOf(i));
|
||||||
|
response = execHttpRequest(false, apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
|
||||||
|
dataList.addAll(fetchResult(response, apiDefinition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (apiDefinition.getRequest().getPage().getPageType().equalsIgnoreCase("cursor")) {
|
||||||
|
dataList.addAll(fetchResult(response, apiDefinition));
|
||||||
|
String cursor = null;
|
||||||
|
try {
|
||||||
|
cursor = JsonPath.read(response, apiDefinition.getRequest().getPage().getResponseData().get(0).getResolutionPath()).toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
while (cursor != null) {
|
||||||
|
apiDefinition.getRequest().getPage().getRequestData().get(0).setParameterDefaultValue(cursor);
|
||||||
|
response = execHttpRequest(false, apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
|
||||||
|
dataList.addAll(fetchResult(response, apiDefinition));
|
||||||
|
try {
|
||||||
|
if (cursor.equalsIgnoreCase(JsonPath.read(response, apiDefinition.getRequest().getPage().getResponseData().get(0).getResolutionPath()).toString())) {
|
||||||
|
cursor = null;
|
||||||
|
} else {
|
||||||
|
cursor = JsonPath.read(response, apiDefinition.getRequest().getPage().getResponseData().get(0).getResolutionPath()).toString();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
cursor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.put("dataList", dataList);
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
String response = execHttpRequest(false, apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
|
||||||
|
fieldList = getTableFields(apiDefinition);
|
||||||
|
result.put("fieldList", fieldList);
|
||||||
|
dataList = fetchResult(response, apiDefinition);
|
||||||
|
result.put("dataList", dataList);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static List<TableField> getTableFields(ApiDefinition apiDefinition) throws DEException {
|
||||||
|
return apiDefinition.getFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<TableField> getTableFields(DatasourceRequest datasourceRequest) throws DEException {
|
||||||
|
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
List<TableField> tableFields = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
List<ApiDefinition> lists = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
|
||||||
|
for (ApiDefinition apiDefinition : lists) {
|
||||||
|
if (datasourceRequest.getTable().equalsIgnoreCase(apiDefinition.getDeTableName())) {
|
||||||
|
tableFields = getTableFields(apiDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return tableFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String checkAPIStatus(DatasourceRequest datasourceRequest) throws Exception {
|
||||||
|
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
|
||||||
|
};
|
||||||
|
List<ApiDefinition> apiDefinitionList = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
|
||||||
|
List<ObjectNode> status = new ArrayList();
|
||||||
|
for (ApiDefinition apiDefinition : apiDefinitionList) {
|
||||||
|
if (apiDefinition == null || (apiDefinition.getType() != null && apiDefinition.getType().equalsIgnoreCase("params"))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
datasourceRequest.setTable(apiDefinition.getName());
|
||||||
|
ObjectNode apiItemStatuses = objectMapper.createObjectNode();
|
||||||
|
try {
|
||||||
|
getData(datasourceRequest);
|
||||||
|
apiItemStatuses.put("name", apiDefinition.getName());
|
||||||
|
apiItemStatuses.put("status", "Success");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.error("API status Error: " + datasourceRequest.getDatasource().getName() + "-" + apiDefinition.getName(), e);
|
||||||
|
apiItemStatuses.put("name", apiDefinition.getName());
|
||||||
|
apiItemStatuses.put("status", "Error");
|
||||||
|
}
|
||||||
|
status.add(apiItemStatuses);
|
||||||
|
}
|
||||||
|
return JsonUtil.toJSONString(status).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String[]> getData(DatasourceRequest datasourceRequest) throws Exception {
|
||||||
|
ApiDefinition apiDefinition = getApiDefinition(datasourceRequest);
|
||||||
|
if (apiDefinition == null) {
|
||||||
|
DEException.throwException("未找到");
|
||||||
|
}
|
||||||
|
String response = execHttpRequest(true, apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
|
||||||
|
return fetchResult(response, apiDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String execHttpRequest(boolean preview, ApiDefinition api, int socketTimeout, List<ApiDefinition> paramsList) {
|
||||||
|
ApiDefinition apiDefinition = new ApiDefinition();
|
||||||
|
BeanUtils.copyBean(apiDefinition, api);
|
||||||
|
|
||||||
|
if (apiDefinition.getRequest().getPage() != null && apiDefinition.getRequest().getPage().getPageType() != null && apiDefinition.getRequest().getPage().getPageType().equalsIgnoreCase("pageNumber")) {
|
||||||
|
apiDefinition.setUrl(apiDefinition.getUrl().replace(apiDefinition.getRequest().getPage().getRequestData().get(0).getBuiltInParameterName(), apiDefinition.getRequest().getPage().getRequestData().get(0).getParameterDefaultValue()).replace(apiDefinition.getRequest().getPage().getRequestData().get(1).getBuiltInParameterName(), apiDefinition.getRequest().getPage().getRequestData().get(1).getParameterDefaultValue()));
|
||||||
|
apiDefinition.setRequest(JsonUtil.parseObject(JsonUtil.toJSONString(apiDefinition.getRequest()).toString().replace(apiDefinition.getRequest().getPage().getRequestData().get(0).getBuiltInParameterName(), apiDefinition.getRequest().getPage().getRequestData().get(0).getParameterDefaultValue()).replace(apiDefinition.getRequest().getPage().getRequestData().get(1).getBuiltInParameterName(), apiDefinition.getRequest().getPage().getRequestData().get(1).getParameterDefaultValue()), ApiDefinitionRequest.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apiDefinition.getRequest().getPage() != null && apiDefinition.getRequest().getPage().getPageType() != null && apiDefinition.getRequest().getPage().getPageType().equalsIgnoreCase("cursor")) {
|
||||||
|
apiDefinition.setUrl(apiDefinition.getUrl().replace(apiDefinition.getRequest().getPage().getRequestData().get(0).getBuiltInParameterName(), apiDefinition.getRequest().getPage().getRequestData().get(0).getParameterDefaultValue()).replace(apiDefinition.getRequest().getPage().getRequestData().get(1).getBuiltInParameterName(), apiDefinition.getRequest().getPage().getRequestData().get(1).getParameterDefaultValue()));
|
||||||
|
String defaultCursor = apiDefinition.getRequest().getPage().getRequestData().get(0).getParameterDefaultValue();
|
||||||
|
apiDefinition.setRequest(JsonUtil.parseObject(JsonUtil.toJSONString(apiDefinition.getRequest()).toString().replace(apiDefinition.getRequest().getPage().getRequestData().get(0).getBuiltInParameterName(), StringUtils.isEmpty(defaultCursor) ? "" : defaultCursor).replace(apiDefinition.getRequest().getPage().getRequestData().get(1).getBuiltInParameterName(), apiDefinition.getRequest().getPage().getRequestData().get(1).getParameterDefaultValue()), ApiDefinitionRequest.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String response = "";
|
||||||
|
HttpClientConfig httpClientConfig = new HttpClientConfig();
|
||||||
|
httpClientConfig.setSocketTimeout(socketTimeout * 1000);
|
||||||
|
ApiDefinitionRequest apiDefinitionRequest = apiDefinition.getRequest();
|
||||||
|
for (Map header : apiDefinitionRequest.getHeaders()) {
|
||||||
|
if (header.get("name") != null && StringUtils.isNotEmpty(header.get("name").toString()) && header.get("value") != null && StringUtils.isNotEmpty(header.get("value").toString())) {
|
||||||
|
if (header.get("nameType") != null && header.get("nameType").toString().equalsIgnoreCase("params")) {
|
||||||
|
String param = header.get("value").toString();
|
||||||
|
for (ApiDefinition definition : paramsList) {
|
||||||
|
for (int i = 0; i < definition.getFields().size(); i++) {
|
||||||
|
TableField field = definition.getFields().get(i);
|
||||||
|
if (field.getName().equalsIgnoreCase(param)) {
|
||||||
|
String resultStr = execHttpRequest(true, definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
|
||||||
|
List<String[]> dataList = fetchResult(resultStr, definition);
|
||||||
|
if (dataList.size() > 0) {
|
||||||
|
httpClientConfig.addHeader(header.get("name").toString(), dataList.get(0)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (header.get("nameType") != null && header.get("nameType").toString().equalsIgnoreCase("custom")) {
|
||||||
|
List<String> params = new ArrayList<>();
|
||||||
|
String regex = "\\$\\{(.*?)\\}";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(header.get("value").toString());
|
||||||
|
while (matcher.find()) {
|
||||||
|
params.add(matcher.group(1));
|
||||||
|
}
|
||||||
|
String result = header.get("value").toString();
|
||||||
|
for (String param : params) {
|
||||||
|
for (ApiDefinition definition : paramsList) {
|
||||||
|
for (int i = 0; i < definition.getFields().size(); i++) {
|
||||||
|
TableField field = definition.getFields().get(i);
|
||||||
|
if (field.getName().equalsIgnoreCase(param)) {
|
||||||
|
String resultStr = execHttpRequest(true, definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
|
||||||
|
List<String[]> dataList = fetchResult(resultStr, definition);
|
||||||
|
if (dataList.size() > 0) {
|
||||||
|
result = result.replace("${" + param + "}", dataList.get(0)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
httpClientConfig.addHeader(header.get("name").toString(), result);
|
||||||
|
} else if (header.get("nameType") != null && header.get("nameType").toString().equalsIgnoreCase("timeFun")) {
|
||||||
|
String timeFormat = header.get("value").toString();
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
Date date = calendar.getTime();
|
||||||
|
if (StringUtils.isNotEmpty(timeFormat) && timeFormat.split(" ")[0].equalsIgnoreCase("currentDay")) {
|
||||||
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormat.split(" ")[1]);
|
||||||
|
httpClientConfig.addHeader(header.get("name").toString(), simpleDateFormat.format(date));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
httpClientConfig.addHeader(header.get("name").toString(), header.get("value").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (apiDefinitionRequest.getAuthManager() != null
|
||||||
|
&& StringUtils.isNotBlank(apiDefinitionRequest.getAuthManager().getUsername())
|
||||||
|
&& StringUtils.isNotBlank(apiDefinitionRequest.getAuthManager().getPassword())
|
||||||
|
&& apiDefinitionRequest.getAuthManager().getVerification().equals("Basic Auth")) {
|
||||||
|
String authValue = "Basic " + Base64.getUrlEncoder().encodeToString((apiDefinitionRequest.getAuthManager().getUsername()
|
||||||
|
+ ":" + apiDefinitionRequest.getAuthManager().getPassword()).getBytes());
|
||||||
|
httpClientConfig.addHeader("Authorization", authValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> params = new ArrayList<>();
|
||||||
|
for (Map<String, String> argument : apiDefinition.getRequest().getArguments()) {
|
||||||
|
if (StringUtils.isNotEmpty(argument.get("name")) && StringUtils.isNotEmpty(argument.get("value"))) {
|
||||||
|
if (argument.get("nameType") != null && argument.get("nameType").toString().equalsIgnoreCase("params")) {
|
||||||
|
String param = argument.get("value").toString();
|
||||||
|
for (ApiDefinition definition : paramsList) {
|
||||||
|
for (int i = 0; i < definition.getFields().size(); i++) {
|
||||||
|
TableField field = definition.getFields().get(i);
|
||||||
|
if (field.getOriginName().equalsIgnoreCase(param)) {
|
||||||
|
String resultStr = execHttpRequest(true, definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
|
||||||
|
List<String[]> dataList = fetchResult(resultStr, definition);
|
||||||
|
if (dataList.size() > 0) {
|
||||||
|
params.add(argument.get("name") + "=" + dataList.get(0)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (argument.get("nameType") != null && argument.get("nameType").toString().equalsIgnoreCase("custom")) {
|
||||||
|
List<String> arrayList = new ArrayList<>();
|
||||||
|
String regex = "\\$\\{(.*?)\\}";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(argument.get("value").toString());
|
||||||
|
while (matcher.find()) {
|
||||||
|
arrayList.add(matcher.group(1));
|
||||||
|
}
|
||||||
|
String result = argument.get("value").toString();
|
||||||
|
for (String param : arrayList) {
|
||||||
|
for (ApiDefinition definition : paramsList) {
|
||||||
|
for (int i = 0; i < definition.getFields().size(); i++) {
|
||||||
|
TableField field = definition.getFields().get(i);
|
||||||
|
if (field.getName().equalsIgnoreCase(param)) {
|
||||||
|
String resultStr = execHttpRequest(true, definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
|
||||||
|
List<String[]> dataList = fetchResult(resultStr, definition);
|
||||||
|
if (dataList.size() > 0) {
|
||||||
|
result = result.replace("${" + param + "}", dataList.get(0)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params.add(argument.get("name") + "=" + result);
|
||||||
|
} else if (argument.get("nameType") != null && argument.get("nameType").toString().equalsIgnoreCase("timeFun")) {
|
||||||
|
String timeFormat = argument.get("value").toString();
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
Date date = calendar.getTime();
|
||||||
|
if (StringUtils.isNotEmpty(timeFormat) && timeFormat.split(" ")[0].equalsIgnoreCase("currentDay")) {
|
||||||
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormat.split(" ")[1]);
|
||||||
|
params.add(argument.get("name") + "=" + simpleDateFormat.format(date));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
params.add(argument.get("name") + "=" + URLEncoder.encode(argument.get("value")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(params)) {
|
||||||
|
apiDefinition.setUrl(apiDefinition.getUrl() + "?" + StringUtils.join(params, "&"));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (apiDefinition.getMethod()) {
|
||||||
|
case "GET":
|
||||||
|
response = HttpClientUtil.get(apiDefinition.getUrl().trim(), httpClientConfig);
|
||||||
|
break;
|
||||||
|
case "POST":
|
||||||
|
if (!apiDefinitionRequest.getBody().keySet().contains("type")) {
|
||||||
|
DEException.throwException("请求类型不能为空");
|
||||||
|
}
|
||||||
|
String type = apiDefinitionRequest.getBody().get("type").toString();
|
||||||
|
if (StringUtils.equalsAny(type, "JSON", "XML", "Raw")) {
|
||||||
|
String raw = null;
|
||||||
|
if (apiDefinitionRequest.getBody().get("raw") != null) {
|
||||||
|
raw = apiDefinitionRequest.getBody().get("raw").toString();
|
||||||
|
|
||||||
|
List<String> bodYparams = new ArrayList<>();
|
||||||
|
String regex = "\\$\\{(.*?)\\}";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(raw);
|
||||||
|
while (matcher.find()) {
|
||||||
|
bodYparams.add(matcher.group(1));
|
||||||
|
}
|
||||||
|
for (String param : bodYparams) {
|
||||||
|
for (ApiDefinition definition : paramsList) {
|
||||||
|
for (int i = 0; i < definition.getFields().size(); i++) {
|
||||||
|
TableField field = definition.getFields().get(i);
|
||||||
|
if (field.getOriginName().equalsIgnoreCase(param)) {
|
||||||
|
String resultStr = execHttpRequest(false, definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
|
||||||
|
List<String[]> dataList = fetchResult(resultStr, definition);
|
||||||
|
if (dataList.size() > 0) {
|
||||||
|
raw = raw.replace("${" + param + "}", dataList.get(0)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = HttpClientUtil.post(apiDefinition.getUrl(), raw, httpClientConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.equalsAny(type, "Form_Data", "WWW_FORM")) {
|
||||||
|
if (apiDefinitionRequest.getBody().get("kvs") != null) {
|
||||||
|
Map<String, String> body = new HashMap<>();
|
||||||
|
TypeReference<List<JsonNode>> listTypeReference = new TypeReference<List<JsonNode>>() {
|
||||||
|
};
|
||||||
|
List<JsonNode> rootNode = null;
|
||||||
|
try {
|
||||||
|
rootNode = objectMapper.readValue(JsonUtil.toJSONString(apiDefinition.getRequest().getBody().get("kvs")).toString(), listTypeReference);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
for (JsonNode jsonNode : rootNode) {
|
||||||
|
if (jsonNode.has("name") && jsonNode.has("value")) {
|
||||||
|
if (jsonNode.get("value") != null && StringUtils.isNotEmpty(jsonNode.get("value").asText())) {
|
||||||
|
if (jsonNode.get("nameType") != null && jsonNode.get("nameType").asText().equalsIgnoreCase("params")) {
|
||||||
|
String param = jsonNode.get("value").asText();
|
||||||
|
for (ApiDefinition definition : paramsList) {
|
||||||
|
for (int i = 0; i < definition.getFields().size(); i++) {
|
||||||
|
TableField field = definition.getFields().get(i);
|
||||||
|
if (field.getOriginName().equalsIgnoreCase(param)) {
|
||||||
|
String resultStr = execHttpRequest(false, definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
|
||||||
|
List<String[]> dataList = fetchResult(resultStr, definition);
|
||||||
|
if (dataList.size() > 0) {
|
||||||
|
body.put(jsonNode.get("name").asText(), dataList.get(0)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (jsonNode.get("nameType") != null && jsonNode.get("nameType").asText().equalsIgnoreCase("custom")) {
|
||||||
|
List<String> bodYparams = new ArrayList<>();
|
||||||
|
String regex = "\\$\\{(.*?)\\}";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(jsonNode.get("value").asText());
|
||||||
|
while (matcher.find()) {
|
||||||
|
bodYparams.add(matcher.group(1));
|
||||||
|
}
|
||||||
|
String result = jsonNode.get("value").asText();
|
||||||
|
for (String param : bodYparams) {
|
||||||
|
for (ApiDefinition definition : paramsList) {
|
||||||
|
for (int i = 0; i < definition.getFields().size(); i++) {
|
||||||
|
TableField field = definition.getFields().get(i);
|
||||||
|
if (field.getOriginName().equalsIgnoreCase(param)) {
|
||||||
|
String resultStr = execHttpRequest(false, definition, definition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), null);
|
||||||
|
List<String[]> dataList = fetchResult(resultStr, definition);
|
||||||
|
if (dataList.size() > 0) {
|
||||||
|
result = result.replace("${" + param + "}", dataList.get(0)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body.put(jsonNode.get("name").asText(), result);
|
||||||
|
} else if (jsonNode.get("nameType") != null && jsonNode.get("nameType").asText().equalsIgnoreCase("timeFun")) {
|
||||||
|
String timeFormat = jsonNode.get("value").asText();
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
Date date = calendar.getTime();
|
||||||
|
if (StringUtils.isNotEmpty(timeFormat) && timeFormat.split(" ")[0].equalsIgnoreCase("currentDay")) {
|
||||||
|
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(timeFormat.split(" ")[1]);
|
||||||
|
body.put(jsonNode.get("name").toString(), simpleDateFormat.format(date));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body.put(jsonNode.get("name").asText(), jsonNode.get("value").asText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = HttpClientUtil.post(apiDefinition.getUrl(), body, httpClientConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void previewNum(List<Map<String, Object>> field) {
|
||||||
|
for (Map<String, Object> stringObjectMap : field) {
|
||||||
|
JSONArray newArray = new JSONArray();
|
||||||
|
if (stringObjectMap.get("value") != null) {
|
||||||
|
try {
|
||||||
|
TypeReference<JSONArray> listTypeReference = new TypeReference<JSONArray>() {
|
||||||
|
};
|
||||||
|
JSONArray array = objectMapper.readValue(stringObjectMap.get("value").toString(), listTypeReference);
|
||||||
|
if (array.size() > 100) {
|
||||||
|
for (int i = 0; i < Math.min(100, array.size()); i++) {
|
||||||
|
newArray.add(array.get(i));
|
||||||
|
}
|
||||||
|
stringObjectMap.put("value", newArray);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApiDefinition checkApiDefinition(DatasourceRequest datasourceRequest) throws DEException {
|
||||||
|
ApiDefinition apiDefinition = new ApiDefinition();
|
||||||
|
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
|
||||||
|
};
|
||||||
|
List<ApiDefinition> apiDefinitionList = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
|
||||||
|
if (!CollectionUtils.isEmpty(apiDefinitionList)) {
|
||||||
|
for (ApiDefinition definition : apiDefinitionList) {
|
||||||
|
if (definition != null && (definition.getType() == null || !definition.getType().equalsIgnoreCase("params"))) {
|
||||||
|
apiDefinition = definition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String response = execHttpRequest(true, apiDefinition, apiDefinition.getApiQueryTimeout() == null || apiDefinition.getApiQueryTimeout() <= 0 ? 10 : apiDefinition.getApiQueryTimeout(), params(datasourceRequest));
|
||||||
|
return checkApiDefinition(apiDefinition, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ApiDefinition checkApiDefinition(ApiDefinition apiDefinition, String response) throws DEException {
|
||||||
|
if (StringUtils.isEmpty(response)) {
|
||||||
|
DEException.throwException("该请求返回数据为空");
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> fields = new ArrayList<>();
|
||||||
|
if (apiDefinition.isShowApiStructure() || !apiDefinition.isUseJsonPath()) {
|
||||||
|
String rootPath;
|
||||||
|
if (response.startsWith("[")) {
|
||||||
|
rootPath = "$[*]";
|
||||||
|
JsonNode jsonArray = null;
|
||||||
|
try {
|
||||||
|
jsonArray = objectMapper.readTree(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
for (Object o : jsonArray) {
|
||||||
|
handleStr(apiDefinition, o.toString(), fields, rootPath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rootPath = "$";
|
||||||
|
handleStr(apiDefinition, response, fields, rootPath);
|
||||||
|
}
|
||||||
|
previewNum(fields);
|
||||||
|
apiDefinition.setJsonFields(fields);
|
||||||
|
return apiDefinition;
|
||||||
|
} else {
|
||||||
|
List<LinkedHashMap> currentData = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
Object object = JsonPath.read(response, apiDefinition.getJsonPath());
|
||||||
|
if (object instanceof List) {
|
||||||
|
currentData = (List<LinkedHashMap>) object;
|
||||||
|
} else {
|
||||||
|
currentData.add((LinkedHashMap) object);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
try {
|
||||||
|
LinkedHashMap data = currentData.get(0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException("数据不符合规范, " + e.getMessage());
|
||||||
|
}
|
||||||
|
for (LinkedHashMap data : currentData) {
|
||||||
|
if (i >= apiDefinition.getPreviewNum()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == 0) {
|
||||||
|
for (Object o : data.keySet()) {
|
||||||
|
Map<String, Object> field = new HashMap<>();
|
||||||
|
field.put("originName", o.toString());
|
||||||
|
field.put("name", o.toString());
|
||||||
|
field.put("type", "STRING");
|
||||||
|
field.put("checked", true);
|
||||||
|
field.put("size", 65535);
|
||||||
|
field.put("deExtractType", 0);
|
||||||
|
field.put("deType", 0);
|
||||||
|
field.put("extField", 0);
|
||||||
|
fields.add(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Map<String, Object> field : fields) {
|
||||||
|
JSONArray array = new JSONArray();
|
||||||
|
if (field.get("value") != null) {
|
||||||
|
try {
|
||||||
|
TypeReference<JSONArray> listTypeReference = new TypeReference<JSONArray>() {
|
||||||
|
};
|
||||||
|
array = objectMapper.readValue(field.get("value").toString(), listTypeReference);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
array.add(Optional.ofNullable(data.get(field.get("originName"))).orElse("").toString().replaceAll("\n", " ").replaceAll("\r", " "));
|
||||||
|
} else {
|
||||||
|
array.add(Optional.ofNullable(data.get(field.get("originName"))).orElse("").toString().replaceAll("\n", " ").replaceAll("\r", " "));
|
||||||
|
}
|
||||||
|
field.put("value", array);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
apiDefinition.setJsonFields(fields);
|
||||||
|
return apiDefinition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void handleStr(ApiDefinition apiDefinition, String jsonStr, List<Map<String, Object>> fields, String rootPath) throws DEException {
|
||||||
|
if (jsonStr.startsWith("[")) {
|
||||||
|
TypeReference<List<Object>> listTypeReference = new TypeReference<List<Object>>() {
|
||||||
|
};
|
||||||
|
List<Object> jsonArray = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
jsonArray = objectMapper.readValue(jsonStr, listTypeReference);
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
for (Object o : jsonArray) {
|
||||||
|
handleStr(apiDefinition, o.toString(), fields, rootPath);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
JsonNode jsonNode = null;
|
||||||
|
try {
|
||||||
|
jsonNode = objectMapper.readTree(jsonStr);
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
Iterator<String> fieldNames = jsonNode.fieldNames();
|
||||||
|
while (fieldNames.hasNext()) {
|
||||||
|
String fieldName = fieldNames.next();
|
||||||
|
String value = jsonNode.get(fieldName).toString();
|
||||||
|
if (StringUtils.isNotEmpty(value) && !value.startsWith("[") && !value.startsWith("{")) {
|
||||||
|
value = jsonNode.get(fieldName).asText();
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(value) && value.startsWith("[")) {
|
||||||
|
Map<String, Object> o = new HashMap<>();
|
||||||
|
try {
|
||||||
|
JsonNode jsonArray = objectMapper.readTree(value);
|
||||||
|
List<Map<String, Object>> childrenField = new ArrayList<>();
|
||||||
|
for (JsonNode node : jsonArray) {
|
||||||
|
if (StringUtils.isNotEmpty(node.toString()) && !node.toString().startsWith("[") && !node.toString().startsWith("{")) {
|
||||||
|
throw new Exception(node + "is not json type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (JsonNode node : jsonArray) {
|
||||||
|
handleStr(apiDefinition, node.toString(), childrenField, rootPath + "." + String.format(path, fieldName) + "[*]");
|
||||||
|
}
|
||||||
|
o.put("children", childrenField);
|
||||||
|
o.put("childrenDataType", "LIST");
|
||||||
|
} catch (Exception e) {
|
||||||
|
JSONArray array = new JSONArray();
|
||||||
|
array.add(StringUtils.isNotEmpty(jsonNode.get(fieldName).toString()) ? jsonNode.get(fieldName).toString() : "");
|
||||||
|
o.put("value", array);
|
||||||
|
}
|
||||||
|
o.put("jsonPath", rootPath + "." + String.format(path, fieldName));
|
||||||
|
setProperty(apiDefinition, o, fieldName);
|
||||||
|
if (!hasItem(apiDefinition, fields, o)) {
|
||||||
|
fields.add(o);
|
||||||
|
}
|
||||||
|
} else if (StringUtils.isNotEmpty(value) && value.startsWith("{")) {
|
||||||
|
try {
|
||||||
|
JsonNode jsonNode1 = objectMapper.readTree(value);
|
||||||
|
List<Map<String, Object>> children = new ArrayList<>();
|
||||||
|
handleStr(apiDefinition, value, children, rootPath + "." + String.format(path, fieldName));
|
||||||
|
Map<String, Object> o = new HashMap<>();
|
||||||
|
o.put("children", children);
|
||||||
|
o.put("childrenDataType", "OBJECT");
|
||||||
|
o.put("jsonPath", rootPath + "." + fieldName);
|
||||||
|
setProperty(apiDefinition, o, fieldName);
|
||||||
|
if (!hasItem(apiDefinition, fields, o)) {
|
||||||
|
fields.add(o);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Map<String, Object> o = new HashMap<>();
|
||||||
|
o.put("jsonPath", rootPath + "." + String.format(path, fieldName));
|
||||||
|
setProperty(apiDefinition, o, fieldName);
|
||||||
|
JSONArray array = new JSONArray();
|
||||||
|
array.add(StringUtils.isNotEmpty(value) ? value : "");
|
||||||
|
o.put("value", array);
|
||||||
|
if (!hasItem(apiDefinition, fields, o)) {
|
||||||
|
fields.add(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Map<String, Object> o = new HashMap<>();
|
||||||
|
o.put("jsonPath", rootPath + "." + String.format(path, fieldName));
|
||||||
|
setProperty(apiDefinition, o, fieldName);
|
||||||
|
JSONArray array = new JSONArray();
|
||||||
|
array.add(StringUtils.isNotEmpty(value) ? value : "");
|
||||||
|
o.put("value", array);
|
||||||
|
if (!hasItem(apiDefinition, fields, o)) {
|
||||||
|
fields.add(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setProperty(ApiDefinition apiDefinition, Map<String, Object> o, String s) {
|
||||||
|
o.put("originName", s);
|
||||||
|
o.put("name", s);
|
||||||
|
o.put("type", "STRING");
|
||||||
|
o.put("size", 65535);
|
||||||
|
o.put("deExtractType", 0);
|
||||||
|
o.put("deType", 0);
|
||||||
|
o.put("checked", false);
|
||||||
|
if (!apiDefinition.isUseJsonPath()) {
|
||||||
|
for (TableField field : apiDefinition.getFields()) {
|
||||||
|
if (!ObjectUtils.isEmpty(o.get("jsonPath")) && StringUtils.isNotEmpty(field.getJsonPath()) && field.getJsonPath().equals(o.get("jsonPath").toString())) {
|
||||||
|
o.put("checked", true);
|
||||||
|
o.put("name", field.getName());
|
||||||
|
o.put("primaryKey", field.isPrimaryKey());
|
||||||
|
o.put("length", field.getLength());
|
||||||
|
o.put("deExtractType", field.getDeExtractType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasItem(ApiDefinition apiDefinition, List<Map<String, Object>> fields, Map<String, Object> item) throws DEException {
|
||||||
|
boolean has = false;
|
||||||
|
for (Map<String, Object> field : fields) {
|
||||||
|
if (field.get("jsonPath").equals(item.get("jsonPath"))) {
|
||||||
|
has = true;
|
||||||
|
mergeField(field, item);
|
||||||
|
mergeValue(field, apiDefinition, item);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return has;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void mergeField(Map<String, Object> field, Map<String, Object> item) throws DEException {
|
||||||
|
if (item.get("children") != null) {
|
||||||
|
List<Map<String, Object>> fieldChildren = null;
|
||||||
|
List<Map<String, Object>> itemChildren = null;
|
||||||
|
try {
|
||||||
|
fieldChildren = objectMapper.readValue(JsonUtil.toJSONString(field.get("children")).toString(), listForMapTypeReference);
|
||||||
|
itemChildren = objectMapper.readValue(JsonUtil.toJSONString(item.get("children")).toString(), listForMapTypeReference);
|
||||||
|
} catch (Exception e) {
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
if (fieldChildren == null) {
|
||||||
|
fieldChildren = new ArrayList<>();
|
||||||
|
}
|
||||||
|
for (Map<String, Object> itemChild : itemChildren) {
|
||||||
|
boolean hasKey = false;
|
||||||
|
for (Map<String, Object> fieldChild : fieldChildren) {
|
||||||
|
if (itemChild.get("jsonPath").toString().equals(fieldChild.get("jsonPath").toString())) {
|
||||||
|
mergeField(fieldChild, itemChild);
|
||||||
|
hasKey = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasKey) {
|
||||||
|
fieldChildren.add(itemChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void mergeValue(Map<String, Object> field, ApiDefinition apiDefinition, Map<String, Object> item) throws DEException {
|
||||||
|
TypeReference<JSONArray> listTypeReference = new TypeReference<JSONArray>() {
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
if (!ObjectUtils.isEmpty(field.get("value")) && !ObjectUtils.isEmpty(item.get("value"))) {
|
||||||
|
JSONArray array = objectMapper.readValue(JsonUtil.toJSONString(field.get("value")).toString(), listTypeReference);
|
||||||
|
array.add(objectMapper.readValue(JsonUtil.toJSONString(item.get("value")).toString(), listTypeReference).get(0));
|
||||||
|
field.put("value", array);
|
||||||
|
}
|
||||||
|
if (!ObjectUtils.isEmpty(field.get("children")) && !ObjectUtils.isEmpty(item.get("children"))) {
|
||||||
|
List<Map<String, Object>> fieldChildren = objectMapper.readValue(JsonUtil.toJSONString(field.get("children")).toString(), listForMapTypeReference);
|
||||||
|
List<Map<String, Object>> itemChildren = objectMapper.readValue(JsonUtil.toJSONString(item.get("children")).toString(), listForMapTypeReference);
|
||||||
|
List<Map<String, Object>> fieldArrayChildren = new ArrayList<>();
|
||||||
|
for (Map<String, Object> fieldChild : fieldChildren) {
|
||||||
|
Map<String, Object> find = null;
|
||||||
|
for (Map<String, Object> itemChild : itemChildren) {
|
||||||
|
if (fieldChild.get("jsonPath").toString().equals(itemChild.get("jsonPath").toString())) {
|
||||||
|
find = itemChild;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (find != null) {
|
||||||
|
mergeValue(fieldChild, apiDefinition, find);
|
||||||
|
}
|
||||||
|
fieldArrayChildren.add(fieldChild);
|
||||||
|
}
|
||||||
|
field.put("children", fieldArrayChildren);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
DEException.throwException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<String[]> fetchResult(String result, ApiDefinition apiDefinition) {
|
||||||
|
List<String[]> dataList = new LinkedList<>();
|
||||||
|
if (apiDefinition.isUseJsonPath()) {
|
||||||
|
List<LinkedHashMap> currentData = new ArrayList<>();
|
||||||
|
Object object = JsonPath.read(result, apiDefinition.getJsonPath());
|
||||||
|
if (object instanceof List) {
|
||||||
|
currentData = (List<LinkedHashMap>) object;
|
||||||
|
} else {
|
||||||
|
currentData.add((LinkedHashMap) object);
|
||||||
|
}
|
||||||
|
for (LinkedHashMap data : currentData) {
|
||||||
|
String[] row = new String[apiDefinition.getFields().size()];
|
||||||
|
int i = 0;
|
||||||
|
for (TableField field : apiDefinition.getFields()) {
|
||||||
|
row[i] = Optional.ofNullable(data.get(field.getOriginName())).orElse("").toString().replaceAll("\n", " ").replaceAll("\r", " ");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dataList.add(row);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<String> jsonPaths = apiDefinition.getFields().stream().map(TableField::getJsonPath).collect(Collectors.toList());
|
||||||
|
Long maxLength = 0l;
|
||||||
|
List<List<String>> columnDataList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < jsonPaths.size(); i++) {
|
||||||
|
List<String> data = new ArrayList<>();
|
||||||
|
Object object = JsonPath.read(result, jsonPaths.get(i));
|
||||||
|
if (object instanceof List && jsonPaths.get(i).contains("[*]")) {
|
||||||
|
data = (List<String>) object;
|
||||||
|
} else {
|
||||||
|
if (object != null) {
|
||||||
|
data.add(object.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maxLength = maxLength > data.size() ? maxLength : data.size();
|
||||||
|
columnDataList.add(data);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < maxLength; i++) {
|
||||||
|
String[] row = new String[apiDefinition.getFields().size()];
|
||||||
|
dataList.add(row);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < columnDataList.size(); i++) {
|
||||||
|
for (int j = 0; j < columnDataList.get(i).size(); j++) {
|
||||||
|
dataList.get(j)[i] = Optional.ofNullable(String.valueOf(columnDataList.get(i).get(j))).orElse("").replaceAll("\n", " ").replaceAll("\r", " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dataList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static List<ApiDefinition> params(DatasourceRequest datasourceRequest) {
|
||||||
|
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
|
||||||
|
};
|
||||||
|
List<ApiDefinition> apiDefinitionListTemp = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
|
||||||
|
return apiDefinitionListTemp.stream().filter(apiDefinition -> apiDefinition != null && apiDefinition.getType() != null && apiDefinition.getType().equalsIgnoreCase("params")).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ApiDefinition getApiDefinition(DatasourceRequest datasourceRequest) throws DEException {
|
||||||
|
List<ApiDefinition> apiDefinitionList = new ArrayList<>();
|
||||||
|
TypeReference<List<ApiDefinition>> listTypeReference = new TypeReference<List<ApiDefinition>>() {
|
||||||
|
};
|
||||||
|
List<ApiDefinition> apiDefinitionListTemp = JsonUtil.parseList(datasourceRequest.getDatasource().getConfiguration(), listTypeReference);
|
||||||
|
|
||||||
|
if (!CollectionUtils.isEmpty(apiDefinitionListTemp)) {
|
||||||
|
for (ApiDefinition apiDefinition : apiDefinitionListTemp) {
|
||||||
|
if (apiDefinition == null || apiDefinition.getType() == null || apiDefinition.getType().equalsIgnoreCase("params")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (apiDefinition.getDeTableName().equalsIgnoreCase(datasourceRequest.getTable()) || apiDefinition.getName().equalsIgnoreCase(datasourceRequest.getTable())) {
|
||||||
|
apiDefinitionList.add(apiDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isEmpty(apiDefinitionList)) {
|
||||||
|
DEException.throwException("未找到API数据表");
|
||||||
|
}
|
||||||
|
if (apiDefinitionList.size() > 1) {
|
||||||
|
DEException.throwException("存在重名的API数据表");
|
||||||
|
}
|
||||||
|
ApiDefinition find = null;
|
||||||
|
for (ApiDefinition apiDefinition : apiDefinitionList) {
|
||||||
|
if (apiDefinition == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (apiDefinition.getName().equalsIgnoreCase(datasourceRequest.getTable()) || apiDefinition.getDeTableName().equalsIgnoreCase(datasourceRequest.getTable())) {
|
||||||
|
find = apiDefinition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return find;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
31
backend/src/main/java/com/stdproject/service/type/CK.java
Normal file
31
backend/src/main/java/com/stdproject/service/type/CK.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("ck")
|
||||||
|
public class CK extends DatasourceConfiguration {
|
||||||
|
private String driver = "com.clickhouse.jdbc.ClickHouseDriver";
|
||||||
|
private String extraParams = "";
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if(StringUtils.isEmpty(extraParams.trim())){
|
||||||
|
return "jdbc:clickhouse://HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
}else {
|
||||||
|
return "jdbc:clickhouse://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("EXTRA_PARAMS", getExtraParams().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
backend/src/main/java/com/stdproject/service/type/Db2.java
Normal file
39
backend/src/main/java/com/stdproject/service/type/Db2.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("db2")
|
||||||
|
public class Db2 extends DatasourceConfiguration {
|
||||||
|
private String driver = "com.ibm.db2.jcc.DB2Driver";
|
||||||
|
private String extraParams = "";
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if(StringUtils.isEmpty(extraParams.trim())){
|
||||||
|
if (StringUtils.isEmpty(getSchema())) {
|
||||||
|
return "jdbc:db2://HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
} else {
|
||||||
|
return "jdbc:db2://HOSTNAME:PORT/DATABASE:currentSchema=SCHEMA;"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("SCHEMA",getSchema().trim());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return "jdbc:db2://HOSTNAME:PORT/DATABASE:EXTRA_PARAMS"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("EXTRA_PARAMS", getExtraParams().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
backend/src/main/java/com/stdproject/service/type/Es.java
Normal file
14
backend/src/main/java/com/stdproject/service/type/Es.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Es {
|
||||||
|
private String url;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String version;
|
||||||
|
private String uri;
|
||||||
|
|
||||||
|
}
|
11
backend/src/main/java/com/stdproject/service/type/H2.java
Normal file
11
backend/src/main/java/com/stdproject/service/type/H2.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("h2")
|
||||||
|
public class H2 extends DatasourceConfiguration {
|
||||||
|
private String driver = "org.h2.Driver";
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("impala")
|
||||||
|
public class Impala extends DatasourceConfiguration {
|
||||||
|
private String driver = "com.cloudera.impala.jdbc.Driver";
|
||||||
|
private String extraParams = "";
|
||||||
|
private List<String> illegalParameters = Arrays.asList("autoDeserialize", "queryInterceptors", "statementInterceptors", "detectCustomCollations");
|
||||||
|
private List<String> showTableSqls = Arrays.asList("show tables");
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if(StringUtils.isEmpty(extraParams.trim())){
|
||||||
|
return "jdbc:impala://HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
}else {
|
||||||
|
return "jdbc:impala://HOSTNAME:PORT/DATABASE;EXTRA_PARAMS"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("EXTRA_PARAMS", getExtraParams().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
backend/src/main/java/com/stdproject/service/type/Mongo.java
Normal file
42
backend/src/main/java/com/stdproject/service/type/Mongo.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("mongo")
|
||||||
|
public class Mongo extends DatasourceConfiguration {
|
||||||
|
private String driver = "com.mysql.cj.jdbc.Driver";
|
||||||
|
private String extraParams = "characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull";
|
||||||
|
private List<String> illegalParameters = Arrays.asList("autoDeserialize", "queryInterceptors", "statementInterceptors", "detectCustomCollations");
|
||||||
|
private List<String> showTableSqls = Arrays.asList("show tables");
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(extraParams.trim())) {
|
||||||
|
return "jdbc:mysql://HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
} else {
|
||||||
|
for (String illegalParameter : illegalParameters) {
|
||||||
|
if (getExtraParams().contains(illegalParameter)) {
|
||||||
|
throw new RuntimeException("Illegal parameter: " + illegalParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("EXTRA_PARAMS", getExtraParams().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
backend/src/main/java/com/stdproject/service/type/Mysql.java
Normal file
48
backend/src/main/java/com/stdproject/service/type/Mysql.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.exception.DEException;
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("mysql")
|
||||||
|
public class Mysql extends DatasourceConfiguration {
|
||||||
|
private String driver = "com.mysql.cj.jdbc.Driver";
|
||||||
|
private String extraParams = "characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull";
|
||||||
|
private List<String> illegalParameters = Arrays.asList("maxAllowedPacket", "autoDeserialize", "queryInterceptors", "statementInterceptors", "detectCustomCollations", "allowloadlocalinfile", "allowUrlInLocalInfile", "allowLoadLocalInfileInPath");
|
||||||
|
private List<String> showTableSqls = Arrays.asList("show tables");
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if (StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")) {
|
||||||
|
for (String illegalParameter : illegalParameters) {
|
||||||
|
if (URLDecoder.decode(getJdbcUrl()).toLowerCase().contains(illegalParameter.toLowerCase()) || URLDecoder.decode(getExtraParams()).contains(illegalParameter.toLowerCase())) {
|
||||||
|
DEException.throwException("Illegal parameter: " + illegalParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(extraParams.trim())) {
|
||||||
|
return "jdbc:mysql://HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
} else {
|
||||||
|
for (String illegalParameter : illegalParameters) {
|
||||||
|
if (URLDecoder.decode(getExtraParams()).toLowerCase().contains(illegalParameter.toLowerCase()) || URLDecoder.decode(getExtraParams()).contains(illegalParameter.toLowerCase())) {
|
||||||
|
DEException.throwException("Illegal parameter: " + illegalParameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "jdbc:mysql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("EXTRA_PARAMS", getExtraParams().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("oracle")
|
||||||
|
public class Oracle extends DatasourceConfiguration {
|
||||||
|
private String driver = "oracle.jdbc.driver.OracleDriver";
|
||||||
|
private String extraParams = "";
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(getConnectionType()) && getConnectionType().equalsIgnoreCase("serviceName")) {
|
||||||
|
return "jdbc:oracle:thin:@HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
}else {
|
||||||
|
return "jdbc:oracle:thin:@HOSTNAME:PORT:DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
backend/src/main/java/com/stdproject/service/type/Pg.java
Normal file
40
backend/src/main/java/com/stdproject/service/type/Pg.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("pg")
|
||||||
|
public class Pg extends DatasourceConfiguration {
|
||||||
|
private String driver = "org.postgresql.Driver";
|
||||||
|
private String extraParams = "";
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if(StringUtils.isEmpty(extraParams.trim())){
|
||||||
|
if (StringUtils.isEmpty(getSchema())) {
|
||||||
|
return "jdbc:postgresql://HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
} else {
|
||||||
|
return "jdbc:postgresql://HOSTNAME:PORT/DATABASE?currentSchema=SCHEMA"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("SCHEMA", getSchema().trim());
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return "jdbc:postgresql://HOSTNAME:PORT/DATABASE?EXTRA_PARAMS"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("EXTRA_PARAMS", getExtraParams().trim());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("redshift")
|
||||||
|
public class Redshift extends DatasourceConfiguration {
|
||||||
|
private String driver = "com.amazon.redshift.jdbc42.Driver";
|
||||||
|
private String extraParams = "";
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
return "jdbc:redshift://HOSTNAME:PORT/DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.stdproject.service.type;
|
||||||
|
|
||||||
|
import io.gisbi.extensions.datasource.vo.DatasourceConfiguration;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Component("sqlServer")
|
||||||
|
public class Sqlserver extends DatasourceConfiguration {
|
||||||
|
private String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
|
||||||
|
private String extraParams = "";
|
||||||
|
private List<String> illegalParameters = Arrays.asList("autoDeserialize", "queryInterceptors", "statementInterceptors", "detectCustomCollations");
|
||||||
|
private List<String> showTableSqls = Arrays.asList("show tables");
|
||||||
|
|
||||||
|
public String getJdbc() {
|
||||||
|
if(StringUtils.isNoneEmpty(getUrlType()) && !getUrlType().equalsIgnoreCase("hostName")){
|
||||||
|
return getJdbcUrl();
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(extraParams.trim())) {
|
||||||
|
return "jdbc:sqlserver://HOSTNAME:PORT;DatabaseName=DATABASE"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim());
|
||||||
|
} else {
|
||||||
|
return "jdbc:sqlserver://HOSTNAME:PORT;DatabaseName=DATABASE;EXTRA_PARAMS"
|
||||||
|
.replace("HOSTNAME", getLHost().trim())
|
||||||
|
.replace("PORT", getLPort().toString().trim())
|
||||||
|
.replace("DATABASE", getDataBase().trim())
|
||||||
|
.replace("EXTRA_PARAMS", getExtraParams().trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
61
backend/src/main/java/com/stdproject/utils/FieldUtils.java
Normal file
61
backend/src/main/java/com/stdproject/utils/FieldUtils.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package com.stdproject.utils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author bi-coder
|
||||||
|
*/
|
||||||
|
public class FieldUtils {
|
||||||
|
public static int transType2DeType(final String type) {
|
||||||
|
List<String> text = Arrays.asList("CHAR", "VARCHAR", "TEXT", "TINYTEXT", "MEDIUMTEXT", "LONGTEXT", "ENUM", "ANY", "STRING", "BOOL", "BOOLEAN");
|
||||||
|
List<String> time = Arrays.asList("DATE", "TIME", "YEAR", "DATETIME", "TIMESTAMP", "DATEV2", "DATETIMEV2", "DATETIME2", "DATETIMEOFFSET", "SMALLDATETIME", "DATETIME64", "_TIMESTAMPTZ", "TIMESTAMPTZ");
|
||||||
|
List<String> num = Arrays.asList("INT", "SMALLINT", "MEDIUMINT", "INTEGER", "BIGINT", "LONG", "INT2", "INT4", "INT8", "int2", "int4", "int8", "INT16", "INT32", "INT64", "UINT8", "UINT16", "UINT32", "UINT64");
|
||||||
|
List<String> doubleList = Arrays.asList("NUMBER", "FLOAT", "DOUBLE", "DECIMAL", "REAL", "MONEY", "NUMERIC", "float4", "float8", "FLOAT4", "FLOAT8", "DECFLOAT", "FLOAT32", "FLOAT64");
|
||||||
|
List<String> boolType = Arrays.asList("BIT", "TINYINT");
|
||||||
|
if (boolType.contains(type)) {
|
||||||
|
return 4;// 布尔
|
||||||
|
}
|
||||||
|
if (doubleList.contains(type)) {
|
||||||
|
return 3;// 浮点
|
||||||
|
}
|
||||||
|
if (num.contains(type)) {
|
||||||
|
return 2;// 整型
|
||||||
|
}
|
||||||
|
if (time.contains(type)) {
|
||||||
|
return 1;// 时间
|
||||||
|
}
|
||||||
|
if (text.contains(type)) {
|
||||||
|
return 0;// 文本
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boolType.stream().anyMatch(l -> type.contains(l))) {
|
||||||
|
return 4;// 布尔
|
||||||
|
}
|
||||||
|
if (doubleList.stream().anyMatch(l -> type.contains(l))) {
|
||||||
|
return 3;// 浮点
|
||||||
|
}
|
||||||
|
if (num.stream().anyMatch(l -> type.contains(l))) {
|
||||||
|
return 2;// 整型
|
||||||
|
}
|
||||||
|
if (time.stream().anyMatch(l -> type.contains(l))) {
|
||||||
|
return 1;// 时间
|
||||||
|
}
|
||||||
|
return 0;// 文本
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String transDeType2DQ(int deType) {
|
||||||
|
switch (deType) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 5:
|
||||||
|
return "d";
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
return "q";
|
||||||
|
default:
|
||||||
|
return "d";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -216,4 +216,5 @@ public class FileUtils {
|
|||||||
return String.format("%.1f GB", size / (1024.0 * 1024.0 * 1024.0));
|
return String.format("%.1f GB", size / (1024.0 * 1024.0 * 1024.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,6 +16,8 @@ spring:
|
|||||||
active: ${SPRING_PROFILES_ACTIVE:dev}
|
active: ${SPRING_PROFILES_ACTIVE:dev}
|
||||||
application:
|
application:
|
||||||
name: stdproject-backend
|
name: stdproject-backend
|
||||||
|
main:
|
||||||
|
allow-bean-definition-overriding: true
|
||||||
datasource:
|
datasource:
|
||||||
url: ${DB_URL:jdbc:mysql://121.37.111.42:3306/gisbi-demodb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true}
|
url: ${DB_URL:jdbc:mysql://121.37.111.42:3306/gisbi-demodb?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true}
|
||||||
username: ${DB_USERNAME:root}
|
username: ${DB_USERNAME:root}
|
||||||
@ -56,7 +58,7 @@ spring:
|
|||||||
enabled: ${JWT_ENABLED:true} # 控制是否启用JWT认证
|
enabled: ${JWT_ENABLED:true} # 控制是否启用JWT认证
|
||||||
secret: ${JWT_SECRET:YourJWTSecretKeyForStdProjectBackendApplicationWhichIsVeryLongAndSecure2024!@#$%^&*()}
|
secret: ${JWT_SECRET:YourJWTSecretKeyForStdProjectBackendApplicationWhichIsVeryLongAndSecure2024!@#$%^&*()}
|
||||||
expiration-ms: ${JWT_EXPIRATION:1800000} # Token 过期时间 (例如: 24小时)
|
expiration-ms: ${JWT_EXPIRATION:1800000} # Token 过期时间 (例如: 24小时)
|
||||||
refresh-expiration-ms: ${JWT_REFRESH_EXPIRATION:604800000} # 刷新Token过期时间 (例如: 7天)
|
refresh-expiration-ms: ${JWT_REFRESH_EXPIRATION:1800000} # 刷新Token过期时间 (例如: 30分钟)
|
||||||
|
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
mapper-locations: classpath*:/mapper/**/*.xml # MyBatis Mapper XML文件位置
|
mapper-locations: classpath*:/mapper/**/*.xml # MyBatis Mapper XML文件位置
|
||||||
@ -147,7 +149,7 @@ spring:
|
|||||||
on-profile: dev
|
on-profile: dev
|
||||||
security:
|
security:
|
||||||
jwt:
|
jwt:
|
||||||
enabled: true
|
enabled: false
|
||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
com.stdproject: DEBUG
|
com.stdproject: DEBUG
|
||||||
@ -155,7 +157,7 @@ logging:
|
|||||||
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
|
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
configuration:
|
configuration:
|
||||||
log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl #org.apache.ibatis.logging.stdout.StdOutImpl
|
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||||
springdoc:
|
springdoc:
|
||||||
swagger-ui:
|
swagger-ui:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
Loading…
Reference in New Issue
Block a user