diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d7412c5
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,158 @@
+
+
+ 4.0.0
+
+ com.huangge1199
+ bi
+ 1.0-SNAPSHOT
+ jar
+
+ bi
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.5.15
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 3.1.1
+ 2.0.53
+ 1.2.23
+ 3.0.0
+ 19.3.0.0
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+
+
+ com.oracle.ojdbc
+ ojdbc8
+ ${oracle.version}
+
+
+
+
+ com.alibaba
+ druid-spring-boot-starter
+ ${druid.version}
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ ${fastjson.version}
+
+
+
+
+ io.springfox
+ springfox-boot-starter
+ ${swagger.version}
+
+
+ io.swagger
+ swagger-models
+
+
+
+
+
+
+ io.swagger
+ swagger-models
+ 1.6.2
+
+
+
+
+ com.github.xiaoymin
+ knife4j-spring-boot-starter
+
+ 3.0.3
+
+
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+
+ public
+ aliyun nexus
+ https://maven.aliyun.com/repository/public
+
+ true
+
+
+
+
+
+
+ public
+ aliyun nexus
+ https://maven.aliyun.com/repository/public
+
+ true
+
+
+ false
+
+
+
+
+
diff --git a/src/main/java/com/huangge1199/App.java b/src/main/java/com/huangge1199/App.java
new file mode 100644
index 0000000..20dc213
--- /dev/null
+++ b/src/main/java/com/huangge1199/App.java
@@ -0,0 +1,11 @@
+package com.huangge1199;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class App {
+ public static void main(String[] args) {
+ SpringApplication.run(App.class, args);
+ }
+}
diff --git a/src/main/java/com/huangge1199/base/R.java b/src/main/java/com/huangge1199/base/R.java
new file mode 100644
index 0000000..252ed39
--- /dev/null
+++ b/src/main/java/com/huangge1199/base/R.java
@@ -0,0 +1,116 @@
+package com.huangge1199.base;
+
+import com.huangge1199.contant.HttpStatus;
+
+import java.io.Serializable;
+
+/**
+ * 响应信息主体
+ *
+ * @author ruoyi
+ */
+public class R implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
+ /** 成功 */
+ public static final int SUCCESS = HttpStatus.SUCCESS;
+
+ /** 失败 */
+ public static final int FAIL = HttpStatus.ERROR;
+
+ private int code;
+
+ private String msg;
+
+ private T data;
+
+ public static R ok()
+ {
+ return restResult(null, SUCCESS, "操作成功");
+ }
+
+ public static R ok(T data)
+ {
+ return restResult(data, SUCCESS, "操作成功");
+ }
+
+ public static R ok(T data, String msg)
+ {
+ return restResult(data, SUCCESS, msg);
+ }
+
+ public static R fail()
+ {
+ return restResult(null, FAIL, "操作失败");
+ }
+
+ public static R fail(String msg)
+ {
+ return restResult(null, FAIL, msg);
+ }
+
+ public static R fail(T data)
+ {
+ return restResult(data, FAIL, "操作失败");
+ }
+
+ public static R fail(T data, String msg)
+ {
+ return restResult(data, FAIL, msg);
+ }
+
+ public static R fail(int code, String msg)
+ {
+ return restResult(null, code, msg);
+ }
+
+ private static R restResult(T data, int code, String msg)
+ {
+ R apiResult = new R<>();
+ apiResult.setCode(code);
+ apiResult.setData(data);
+ apiResult.setMsg(msg);
+ return apiResult;
+ }
+
+ public int getCode()
+ {
+ return code;
+ }
+
+ public void setCode(int code)
+ {
+ this.code = code;
+ }
+
+ public String getMsg()
+ {
+ return msg;
+ }
+
+ public void setMsg(String msg)
+ {
+ this.msg = msg;
+ }
+
+ public T getData()
+ {
+ return data;
+ }
+
+ public void setData(T data)
+ {
+ this.data = data;
+ }
+
+ public static Boolean isError(R ret)
+ {
+ return !isSuccess(ret);
+ }
+
+ public static Boolean isSuccess(R ret)
+ {
+ return R.SUCCESS == ret.getCode();
+ }
+}
diff --git a/src/main/java/com/huangge1199/config/DataSourceConfig.java b/src/main/java/com/huangge1199/config/DataSourceConfig.java
new file mode 100644
index 0000000..d8db3c9
--- /dev/null
+++ b/src/main/java/com/huangge1199/config/DataSourceConfig.java
@@ -0,0 +1,42 @@
+package com.huangge1199.config;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import javax.sql.DataSource;
+
+/**
+ * DataSourceConfig
+ *
+ * @author huangge1199
+ * @since 2025/3/12 14:56:10
+ */
+@Configuration
+public class DataSourceConfig {
+
+ @Primary // 指定主数据源
+ @Bean(name = "masterDataSource")
+ public DataSource masterDataSource() {
+ DruidDataSource dataSource = new DruidDataSource();
+ dataSource.setUrl("jdbc:oracle:thin:@192.168.188.2:1521/xe");
+ dataSource.setUsername("ruoyi");
+ dataSource.setPassword("ruoyi");
+ dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
+ return dataSource;
+ }
+
+ // 仅当 enabled = true 时才启用从库数据源
+ @Bean(name = "slaveDataSource")
+ @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
+ public DataSource slaveDataSource() {
+ DruidDataSource dataSource = new DruidDataSource();
+ dataSource.setUrl("jdbc:oracle:thin:@192.168.188.2:1521/xe"); // 修改为实际的从库地址
+ dataSource.setUsername("slave_user");
+ dataSource.setPassword("slave_password");
+ dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
+ return dataSource;
+ }
+}
diff --git a/src/main/java/com/huangge1199/config/SwaggerConfig.java b/src/main/java/com/huangge1199/config/SwaggerConfig.java
new file mode 100644
index 0000000..7ec2014
--- /dev/null
+++ b/src/main/java/com/huangge1199/config/SwaggerConfig.java
@@ -0,0 +1,50 @@
+package com.huangge1199.config;
+
+import io.swagger.annotations.ApiOperation;
+import io.swagger.models.auth.In;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.*;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spi.service.contexts.SecurityContext;
+import springfox.documentation.spring.web.plugins.Docket;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Swagger2的接口配置
+ *
+ * @author ruoyi
+ */
+@Configuration
+public class SwaggerConfig
+{
+
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.OAS_30) // OAS_30 代表 OpenAPI 3.0
+ .apiInfo(apiInfo())
+ .select()
+ .apis(RequestHandlerSelectors.basePackage("com.huangge1199.controller")) // 修改为你的 Controller 包路径
+ .paths(PathSelectors.any())
+ .build();
+ }
+
+ /**
+ * 添加摘要信息
+ */
+ private ApiInfo apiInfo()
+ {
+ // 用ApiInfoBuilder进行定制
+ return new ApiInfoBuilder()
+ .title("Spring Boot API 文档")
+ .description("基于 Swagger3 + Knife4j 的 API 文档")
+ .version("1.0.0")
+ .build();
+ }
+}
diff --git a/src/main/java/com/huangge1199/config/SysConfig.java b/src/main/java/com/huangge1199/config/SysConfig.java
new file mode 100644
index 0000000..797f45b
--- /dev/null
+++ b/src/main/java/com/huangge1199/config/SysConfig.java
@@ -0,0 +1,111 @@
+package com.huangge1199.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * 读取项目相关配置
+ *
+ * @author ruoyi
+ */
+@Component
+@ConfigurationProperties(prefix = "sys")
+public class SysConfig
+{
+ /** 项目名称 */
+ private String name;
+
+ /** 版本 */
+ private String version;
+
+ /** 版权年份 */
+ private String copyrightYear;
+
+ /** 上传路径 */
+ private static String profile;
+
+ /** 获取地址开关 */
+ private static boolean addressEnabled;
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setVersion(String version)
+ {
+ this.version = version;
+ }
+
+ public String getCopyrightYear()
+ {
+ return copyrightYear;
+ }
+
+ public void setCopyrightYear(String copyrightYear)
+ {
+ this.copyrightYear = copyrightYear;
+ }
+
+ public static String getProfile()
+ {
+ return profile;
+ }
+
+ public void setProfile(String profile)
+ {
+ SysConfig.profile = profile;
+ }
+
+ public static boolean isAddressEnabled()
+ {
+ return addressEnabled;
+ }
+
+ public void setAddressEnabled(boolean addressEnabled)
+ {
+ SysConfig.addressEnabled = addressEnabled;
+ }
+
+ /**
+ * 获取导入上传路径
+ */
+ public static String getImportPath()
+ {
+ return getProfile() + "/import";
+ }
+
+ /**
+ * 获取头像上传路径
+ */
+ public static String getAvatarPath()
+ {
+ return getProfile() + "/avatar";
+ }
+
+ /**
+ * 获取下载路径
+ */
+ public static String getDownloadPath()
+ {
+ return getProfile() + "/download/";
+ }
+
+ /**
+ * 获取上传路径
+ */
+ public static String getUploadPath()
+ {
+ return getProfile() + "/upload";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/huangge1199/contant/HttpStatus.java b/src/main/java/com/huangge1199/contant/HttpStatus.java
new file mode 100644
index 0000000..a1c9a1a
--- /dev/null
+++ b/src/main/java/com/huangge1199/contant/HttpStatus.java
@@ -0,0 +1,94 @@
+package com.huangge1199.contant;
+
+/**
+ * 返回状态码
+ *
+ * @author ruoyi
+ */
+public class HttpStatus
+{
+ /**
+ * 操作成功
+ */
+ public static final int SUCCESS = 200;
+
+ /**
+ * 对象创建成功
+ */
+ public static final int CREATED = 201;
+
+ /**
+ * 请求已经被接受
+ */
+ public static final int ACCEPTED = 202;
+
+ /**
+ * 操作已经执行成功,但是没有返回数据
+ */
+ public static final int NO_CONTENT = 204;
+
+ /**
+ * 资源已被移除
+ */
+ public static final int MOVED_PERM = 301;
+
+ /**
+ * 重定向
+ */
+ public static final int SEE_OTHER = 303;
+
+ /**
+ * 资源没有被修改
+ */
+ public static final int NOT_MODIFIED = 304;
+
+ /**
+ * 参数列表错误(缺少,格式不匹配)
+ */
+ public static final int BAD_REQUEST = 400;
+
+ /**
+ * 未授权
+ */
+ public static final int UNAUTHORIZED = 401;
+
+ /**
+ * 访问受限,授权过期
+ */
+ public static final int FORBIDDEN = 403;
+
+ /**
+ * 资源,服务未找到
+ */
+ public static final int NOT_FOUND = 404;
+
+ /**
+ * 不允许的http方法
+ */
+ public static final int BAD_METHOD = 405;
+
+ /**
+ * 资源冲突,或者资源被锁
+ */
+ public static final int CONFLICT = 409;
+
+ /**
+ * 不支持的数据,媒体类型
+ */
+ public static final int UNSUPPORTED_TYPE = 415;
+
+ /**
+ * 系统内部错误
+ */
+ public static final int ERROR = 500;
+
+ /**
+ * 接口未实现
+ */
+ public static final int NOT_IMPLEMENTED = 501;
+
+ /**
+ * 系统警告消息
+ */
+ public static final int WARN = 601;
+}
diff --git a/src/main/java/com/huangge1199/controller/DatabaseController.java b/src/main/java/com/huangge1199/controller/DatabaseController.java
new file mode 100644
index 0000000..03e8da9
--- /dev/null
+++ b/src/main/java/com/huangge1199/controller/DatabaseController.java
@@ -0,0 +1,66 @@
+package com.huangge1199.controller;
+import com.huangge1199.base.R;
+import com.huangge1199.domain.UserTabComments;
+import com.huangge1199.service.IDatabaseService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * DatabaseController
+ *
+ * @author huangge1199
+ * @since 2025/3/12 10:16:42
+ */
+@Api("数据库可视化")
+@RestController
+@RequestMapping("/database")
+public class DatabaseController{
+
+ @Resource
+ private IDatabaseService databaseService;
+
+ @ApiOperation("获取数据库所有表名称")
+ @GetMapping("/listAllTable")
+ public
+ R> listAllTable()
+ {
+ List tableList = databaseService.listAllTable();
+ return R.ok(tableList);
+ }
+
+ @ApiOperation("根据表名获取表中所有字段")
+ @GetMapping("/listColByTable")
+ public
+ R> listColByTable(String tableName)
+ {
+ List tableList = databaseService.listColByTable(tableName);
+ return R.ok(tableList);
+ }
+
+ @ApiOperation("根据SQL进行查询")
+ @GetMapping("/executeQuery")
+ public
+ R>> getQuery(String sql)
+ {
+ List