Merge branch 'main' of http://121.37.111.42:3000/zhengsl/stdproject
This commit is contained in:
commit
ca515c0b56
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>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.13</version>
|
||||
<version>3.3.0</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.stdproject</groupId>
|
||||
@ -14,15 +14,21 @@
|
||||
<name>stdproject</name>
|
||||
<description>Standard Project Backend</description>
|
||||
<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>
|
||||
<mybatis-plus.version>3.5.3</mybatis-plus.version>
|
||||
<mybatis-spring.version>3.0.3</mybatis-spring.version>
|
||||
<mybatis-plus.version>3.5.6</mybatis-plus.version>
|
||||
<jjwt.version>0.11.5</jjwt.version>
|
||||
<springdoc.version>2.0.2</springdoc.version>
|
||||
<calcite-core.version>1.35.18</calcite-core.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@ -45,7 +51,19 @@
|
||||
<artifactId>cache-api</artifactId>
|
||||
</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>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-spring</artifactId>
|
||||
<version>${mybatis-spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
@ -107,18 +125,9 @@
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version> <!-- 推荐使用最新稳定版本 -->
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-core</artifactId>
|
||||
<version>3.5.3.1</version> <!-- 请使用你项目中统一的版本 -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.34</version> <!-- 推荐使用最新稳定版本 --> <scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -13,8 +13,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
* @author StdProject
|
||||
* @since 2023-12-07
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.stdproject.mapper")
|
||||
@SpringBootApplication(scanBasePackages = {"com.stdproject","io.gisbi.rsa", "io.gisbi.utils", "io.gisbi.extensions"})
|
||||
@MapperScan("com.stdproject.mapper,io.gisbi.rsa.dao.mapper")
|
||||
@EnableCaching
|
||||
@EnableAsync
|
||||
@EnableTransactionManagement
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -241,17 +241,25 @@ public class AuthController {
|
||||
@PostMapping("/refreshToken")
|
||||
public Result<String> refreshToken(@RequestBody Map<String, String> params) {
|
||||
String refreshToken = params.get("refreshToken");
|
||||
|
||||
if (refreshToken == null || refreshToken.trim().isEmpty()) {
|
||||
return Result.error("刷新令牌不能为空");
|
||||
}
|
||||
// 验证refreshToken的有效性并获取用户信息
|
||||
String username = jwtUtils.getUsernameFromToken(refreshToken);
|
||||
if (username != null) {
|
||||
AppUser user = appUserService.findByUsername(username);
|
||||
// 生成新的token
|
||||
return Result.success(jwtUtils.generateToken(user.getUsername(), user.getId()));
|
||||
|
||||
try {
|
||||
String username = jwtUtils.getUsernameFromToken(refreshToken);
|
||||
|
||||
if (username != null && jwtUtils.validateToken(refreshToken, username)) {
|
||||
AppUser user = appUserService.findByUsername(username);
|
||||
String newAccessToken = jwtUtils.generateRefreshToken(user.getUsername(), user.getId());
|
||||
return Result.success(newAccessToken);
|
||||
} else {
|
||||
return Result.error("刷新令牌已失效");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("刷新 Token 失败: {}", e.getMessage());
|
||||
return Result.error("刷新 Token 失败");
|
||||
}
|
||||
return Result.error("无效的刷新令牌");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
* @since 2023-12-07
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {
|
||||
|
||||
|
@ -0,0 +1,428 @@
|
||||
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 com.stdproject.utils.EncryptUtils;
|
||||
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);
|
||||
coreDatasource.setConfiguration(String.valueOf(EncryptUtils.aesDecrypt(coreDatasource.getConfiguration())));
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
210
backend/src/main/java/com/stdproject/utils/CodingUtil.java
Normal file
210
backend/src/main/java/com/stdproject/utils/CodingUtil.java
Normal file
@ -0,0 +1,210 @@
|
||||
package com.stdproject.utils;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 加密解密工具
|
||||
*
|
||||
* @Author bi-coder
|
||||
*/
|
||||
public class CodingUtil {
|
||||
|
||||
private static final String UTF_8 = "UTF-8";
|
||||
|
||||
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
|
||||
public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f",
|
||||
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
|
||||
"t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
|
||||
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
|
||||
"W", "X", "Y", "Z" };
|
||||
/**
|
||||
* MD5加密
|
||||
*
|
||||
* @param src 要加密的串
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String md5(String src) {
|
||||
return md5(src, UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密
|
||||
*
|
||||
* @param src 要加密的串
|
||||
* @param charset 加密字符集
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String md5(String src, String charset) {
|
||||
try {
|
||||
byte[] strTemp = StringUtils.isEmpty(charset) ? src.getBytes() : src.getBytes(charset);
|
||||
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
|
||||
mdTemp.update(strTemp);
|
||||
|
||||
byte[] md = mdTemp.digest();
|
||||
int j = md.length;
|
||||
char[] str = new char[j * 2];
|
||||
int k = 0;
|
||||
|
||||
for (byte byte0 : md) {
|
||||
str[k++] = HEX_DIGITS[byte0 >>> 4 & 0xf];
|
||||
str[k++] = HEX_DIGITS[byte0 & 0xf];
|
||||
}
|
||||
|
||||
return new String(str);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("MD5 encrypt error:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BASE64解密
|
||||
*
|
||||
* @param src 待解密的字符串
|
||||
* @return 解密后的字符串
|
||||
*/
|
||||
public static String base64Decoding(String src) {
|
||||
byte[] b;
|
||||
String result = null;
|
||||
if (src != null) {
|
||||
try {
|
||||
b = Base64.decodeBase64(src);
|
||||
result = new String(b, UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("BASE64 decoding error:", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* BASE64加密
|
||||
*
|
||||
* @param src 待加密的字符串
|
||||
* @return 加密后的字符串
|
||||
*/
|
||||
public static String base64Encoding(String src) {
|
||||
String result = null;
|
||||
if (src != null) {
|
||||
try {
|
||||
result = Base64.encodeBase64String(src.getBytes(UTF_8));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("BASE64 encoding error:", e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* AES加密
|
||||
*
|
||||
* @param src 待加密字符串
|
||||
* @param secretKey 密钥
|
||||
* @param iv 向量
|
||||
* @return 加密后字符串
|
||||
*/
|
||||
public static String aesEncrypt(String src, String secretKey, String iv) {
|
||||
if (StringUtils.isBlank(secretKey)) {
|
||||
throw new RuntimeException("secretKey is empty");
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] raw = secretKey.getBytes(UTF_8);
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
|
||||
// "算法/模式/补码方式" ECB
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
IvParameterSpec iv1 = new IvParameterSpec(iv.getBytes());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv1);
|
||||
byte[] encrypted = cipher.doFinal(src.getBytes(UTF_8));
|
||||
return Base64.encodeBase64String(encrypted);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("AES encrypt error:", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* AES 解密
|
||||
*
|
||||
* @param src 待解密字符串
|
||||
* @param secretKey 密钥
|
||||
* @param iv 向量
|
||||
* @return 解密后字符串
|
||||
*/
|
||||
public static String aesDecrypt(String src, String secretKey, String iv) {
|
||||
if (StringUtils.isBlank(secretKey)) {
|
||||
throw new RuntimeException("secretKey is empty");
|
||||
}
|
||||
try {
|
||||
byte[] raw = secretKey.getBytes(UTF_8);
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(raw, "AES");
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
IvParameterSpec iv1 = new IvParameterSpec(iv.getBytes());
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv1);
|
||||
byte[] encrypted1 = Base64.decodeBase64(src);
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
return new String(original, UTF_8);
|
||||
} catch (BadPaddingException | IllegalBlockSizeException e) {
|
||||
// 解密的原字符串为非加密字符串,则直接返回原字符串
|
||||
return src;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("decrypt error,please check parameters", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String secretKey() {
|
||||
try {
|
||||
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
|
||||
keyGen.init(128);
|
||||
SecretKey secretKey = keyGen.generateKey();
|
||||
return Base64.encodeBase64String(secretKey.getEncoded());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("generate secretKey error", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isNumeric(String str){
|
||||
for (int i = str.length();--i>=0;){
|
||||
if (!Character.isDigit(str.charAt(i))){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static String shortUuid() {
|
||||
StringBuffer shortBuffer = new StringBuffer();
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
String str = uuid.substring(i * 4, i * 4 + 4);
|
||||
int x = Integer.parseInt(str, 16);
|
||||
shortBuffer.append(chars[x % 0x3E]);
|
||||
}
|
||||
return shortBuffer.toString();
|
||||
}
|
||||
|
||||
public static Integer string2Integer(String str) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (StringUtils.isBlank(str)) return null;
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char c = str.charAt(i);
|
||||
if (Character.isDigit(c)) {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.length() > 0 ? Integer.parseInt(sb.toString()) : null;
|
||||
}
|
||||
}
|
44
backend/src/main/java/com/stdproject/utils/EncryptUtils.java
Normal file
44
backend/src/main/java/com/stdproject/utils/EncryptUtils.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.stdproject.utils;
|
||||
|
||||
import io.gisbi.utils.BeanUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EncryptUtils extends CodingUtil {
|
||||
|
||||
private static final String secretKey = "www.fit2cloud.co";
|
||||
private static final String iv = "1234567890123456";
|
||||
|
||||
|
||||
public static Object aesEncrypt(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return aesEncrypt(o.toString(), secretKey, iv);
|
||||
}
|
||||
|
||||
public static Object aesDecrypt(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return aesDecrypt(o.toString(), secretKey, iv);
|
||||
}
|
||||
|
||||
public static <T> Object aesDecrypt(List<T> o, String attrName) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return o.stream()
|
||||
.filter(element -> BeanUtils.getFieldValueByName(attrName, element) != null)
|
||||
.peek(element -> BeanUtils.setFieldValueByName(element, attrName, aesDecrypt(BeanUtils.getFieldValueByName(attrName, element).toString(), secretKey, iv), String.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static Object md5Encrypt(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return md5(o.toString());
|
||||
}
|
||||
}
|
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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -28,6 +28,9 @@ public class JwtUtils {
|
||||
@Value("${spring.security.jwt.expiration-ms}")
|
||||
private Long expirationMs;
|
||||
|
||||
@Value("${spring.security.jwt.refresh-expiration-ms}")
|
||||
private Long refreshExpirationMs;
|
||||
|
||||
/**
|
||||
* 生成JWT令牌
|
||||
*
|
||||
@ -62,6 +65,33 @@ public class JwtUtils {
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建带刷新时间的 Token
|
||||
*/
|
||||
private String createRefreshToken(Map<String, Object> claims, String subject) {
|
||||
Date now = new Date();
|
||||
Date expiryDate = new Date(now.getTime() + refreshExpirationMs);
|
||||
|
||||
return Jwts.builder()
|
||||
.setClaims(claims)
|
||||
.setSubject(subject)
|
||||
.setIssuedAt(now)
|
||||
.setExpiration(expiryDate)
|
||||
.signWith(getSigningKey(), SignatureAlgorithm.HS512)
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Refresh Token
|
||||
*/
|
||||
public String generateRefreshToken(String username, String userId) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("userId", userId);
|
||||
claims.put("username", username);
|
||||
return createRefreshToken(claims, username);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从JWT令牌中获取用户名
|
||||
*
|
||||
|
@ -16,6 +16,8 @@ spring:
|
||||
active: ${SPRING_PROFILES_ACTIVE:dev}
|
||||
application:
|
||||
name: stdproject-backend
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
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}
|
||||
username: ${DB_USERNAME:root}
|
||||
@ -55,8 +57,8 @@ spring:
|
||||
jwt:
|
||||
enabled: ${JWT_ENABLED:true} # 控制是否启用JWT认证
|
||||
secret: ${JWT_SECRET:YourJWTSecretKeyForStdProjectBackendApplicationWhichIsVeryLongAndSecure2024!@#$%^&*()}
|
||||
expiration-ms: ${JWT_EXPIRATION:86400000} # Token 过期时间 (例如: 24小时)
|
||||
refresh-expiration-ms: ${JWT_REFRESH_EXPIRATION:604800000} # 刷新Token过期时间 (例如: 7天)
|
||||
expiration-ms: ${JWT_EXPIRATION:1800000} # Token 过期时间 (例如: 24小时)
|
||||
refresh-expiration-ms: ${JWT_REFRESH_EXPIRATION:1800000} # 刷新Token过期时间 (例如: 30分钟)
|
||||
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:/mapper/**/*.xml # MyBatis Mapper XML文件位置
|
||||
@ -147,7 +149,7 @@ spring:
|
||||
on-profile: dev
|
||||
security:
|
||||
jwt:
|
||||
enabled: true
|
||||
enabled: false
|
||||
logging:
|
||||
level:
|
||||
com.stdproject: DEBUG
|
||||
@ -155,7 +157,7 @@ logging:
|
||||
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #org.apache.ibatis.logging.nologging.NoLoggingImpl
|
||||
springdoc:
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
|
Loading…
Reference in New Issue
Block a user