Jelajahi Sumber

数据中心代码第一次提交:数据接口-静态数据

fuyuchuan 2 hari lalu
induk
melakukan
33e5094c4a
41 mengubah file dengan 2893 tambahan dan 1 penghapusan
  1. 2 1
      pom.xml
  2. 17 0
      service-data/pom.xml
  3. 33 0
      service-data/service-data-api/pom.xml
  4. 96 0
      service-data/service-data-biz/pom.xml
  5. 50 0
      service-data/service-data-biz/src/main/java/com/usky/data/DataApplicationRun.java
  6. 106 0
      service-data/service-data-biz/src/main/java/com/usky/data/MybatisGenerator.java
  7. 222 0
      service-data/service-data-biz/src/main/java/com/usky/data/controller/web/DataInterfaceController.java
  8. 21 0
      service-data/service-data-biz/src/main/java/com/usky/data/controller/web/DataInterfaceLogController.java
  9. 229 0
      service-data/service-data-biz/src/main/java/com/usky/data/controller/web/DataLinkController.java
  10. 179 0
      service-data/service-data-biz/src/main/java/com/usky/data/domain/DataInterface.java
  11. 122 0
      service-data/service-data-biz/src/main/java/com/usky/data/domain/DataInterfaceLog.java
  12. 136 0
      service-data/service-data-biz/src/main/java/com/usky/data/domain/DataLink.java
  13. 16 0
      service-data/service-data-biz/src/main/java/com/usky/data/mapper/DataInterfaceLogMapper.java
  14. 16 0
      service-data/service-data-biz/src/main/java/com/usky/data/mapper/DataInterfaceMapper.java
  15. 34 0
      service-data/service-data-biz/src/main/java/com/usky/data/mapper/DataLinkMapper.java
  16. 34 0
      service-data/service-data-biz/src/main/java/com/usky/data/model/DataInterfaceModel.java
  17. 52 0
      service-data/service-data-biz/src/main/java/com/usky/data/model/DbLinkBaseForm.java
  18. 24 0
      service-data/service-data-biz/src/main/java/com/usky/data/model/DbLinkCreUpForm.java
  19. 24 0
      service-data/service-data-biz/src/main/java/com/usky/data/model/FieldModel.java
  20. 14 0
      service-data/service-data-biz/src/main/java/com/usky/data/model/PaginationDbLink.java
  21. 26 0
      service-data/service-data-biz/src/main/java/com/usky/data/model/ParamModel.java
  22. 16 0
      service-data/service-data-biz/src/main/java/com/usky/data/service/DataInterfaceLogService.java
  23. 49 0
      service-data/service-data-biz/src/main/java/com/usky/data/service/DataInterfaceService.java
  24. 47 0
      service-data/service-data-biz/src/main/java/com/usky/data/service/DataLinkService.java
  25. 20 0
      service-data/service-data-biz/src/main/java/com/usky/data/service/impl/DataInterfaceLogServiceImpl.java
  26. 291 0
      service-data/service-data-biz/src/main/java/com/usky/data/service/impl/DataInterfaceServiceImpl.java
  27. 120 0
      service-data/service-data-biz/src/main/java/com/usky/data/service/impl/DataLinkServiceImpl.java
  28. 421 0
      service-data/service-data-biz/src/main/java/com/usky/data/service/util/InterfaceExecutor.java
  29. 49 0
      service-data/service-data-biz/src/main/java/com/usky/data/vo/DbLinkInfoVO.java
  30. 22 0
      service-data/service-data-biz/src/main/java/com/usky/data/vo/DbLinkListVO.java
  31. 14 0
      service-data/service-data-biz/src/main/java/com/usky/data/vo/DbLinkSelectorListVO.java
  32. 17 0
      service-data/service-data-biz/src/main/java/com/usky/data/vo/ListVO.java
  33. 19 0
      service-data/service-data-biz/src/main/java/com/usky/data/vo/PageListVO.java
  34. 14 0
      service-data/service-data-biz/src/main/java/com/usky/data/vo/PaginationVO.java
  35. 25 0
      service-data/service-data-biz/src/main/resources/bootstrap.yml
  36. 108 0
      service-data/service-data-biz/src/main/resources/doc/index.adoc
  37. 74 0
      service-data/service-data-biz/src/main/resources/logback.xml
  38. 28 0
      service-data/service-data-biz/src/main/resources/mapper/data/DataInterfaceLogMapper.xml
  39. 35 0
      service-data/service-data-biz/src/main/resources/mapper/data/DataInterfaceMapper.xml
  40. 56 0
      service-data/service-data-biz/src/main/resources/mapper/data/DataLinkMapper.xml
  41. 15 0
      service-data/service-data-biz/src/main/resources/smart-doc.json

+ 2 - 1
pom.xml

@@ -97,9 +97,10 @@
 
     <module>service-ids</module>
 
-
     <module>service-cdi</module>
 
+    <module>service-data</module>
+
   </modules>
           
   

+ 17 - 0
service-data/pom.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>usky-modules</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>service-data</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>service-data-biz</module>
+        <module>service-data-api</module>
+  </modules>
+
+</project>

+ 33 - 0
service-data/service-data-api/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>service-data</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>service-data-api</artifactId>
+    <!-- SpringCloud Openfeign -->
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>usky-common-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-openfeign-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+    </build>
+
+</project>

+ 96 - 0
service-data/service-data-biz/pom.xml

@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>service-data</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>service-data-biz</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>common-cloud-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- Pagehelper -->
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>ruoyi-common-swagger</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+
+        <!--Redis依赖-->
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-data-redis</artifactId>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>com.usky</groupId>-->
+<!--            <artifactId>usky-common-redis</artifactId>-->
+<!--        </dependency>-->
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.github.shalousun</groupId>
+                <artifactId>smart-doc-maven-plugin</artifactId>
+                <version>2.1.1</version>
+                <configuration>
+                    <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
+                    <configFile>./src/main/resources/smart-doc.json</configFile>
+                    <!--指定项目名称-->
+                    <projectName>test</projectName>
+                    <!--                    <excludes>-->
+                    <!--                        <exclude>com.bizmatics:product-service-provider</exclude>-->
+                    <!--                        <exclude>cn.afterturn:easypoi-web</exclude>-->
+                    <!--                    </excludes>-->
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 50 - 0
service-data/service-data-biz/src/main/java/com/usky/data/DataApplicationRun.java

@@ -0,0 +1,50 @@
+package com.usky.data;
+
+
+import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
+import org.mybatis.spring.annotation.MapperScan;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 应用启动模块
+ *
+ * @author fyc
+ */
+
+
+@EnableCustomSwagger2
+//@EnableSwagger2
+@EnableFeignClients(basePackages = "com.usky")
+@MapperScan(value = "com.usky.data.mapper")
+@ComponentScan(basePackages = {"com.usky"})
+@EnableAsync
+@SpringBootApplication
+public class DataApplicationRun {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(DataApplicationRun.class);
+
+    public static void main(String[] args) throws UnknownHostException {
+        ConfigurableApplicationContext application = SpringApplication.run(DataApplicationRun.class, args);
+        Environment env = application.getEnvironment();
+        String ip = InetAddress.getLocalHost().getHostAddress();
+        String port = env.getProperty("server.port");
+        String path = env.getProperty("server.servlet.context-path");
+        LOGGER.info("\n----------------------------------------------------------\n\t" +
+                "Application is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port + (null == path ? "" : path) + "/\n\t" +
+                "External: \thttp://" + ip + ":" + port + (null == path ? "" : path) + "/\n\t" +
+                "Api: \t\thttp://" + ip + ":" + port + (null == path ? "" : path) + "/swagger-ui/index.html\n\t" +
+                "----------------------------------------------------------");
+    }
+}

+ 106 - 0
service-data/service-data-biz/src/main/java/com/usky/data/MybatisGenerator.java

@@ -0,0 +1,106 @@
+package com.usky.data;
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ */
+public class MybatisGenerator {
+    public static void main(String[] args) {
+
+        shell("service-data", "service-data-biz");
+    }
+
+    private static void shell(String parentName, String model) {
+
+        AutoGenerator mpg = new AutoGenerator();
+        // 1、全局配置
+        GlobalConfig gc = new GlobalConfig();
+//        File file = new File(model);
+//        String path = file.getAbsolutePath();
+        String projectPath = System.getProperty("user.dir");
+        projectPath += "/" + parentName;
+        projectPath += "/" + model;
+        gc.setOutputDir(projectPath + "/src/main/java");  // 生成路径(一般都是生成在此项目的src/main/java下面)
+        // 修改为自己的名字
+        gc.setAuthor("fyc"); // 设置作者
+        gc.setOpen(false);
+        gc.setFileOverride(true); // 第二次生成会把第一次生成的覆盖掉
+        gc.setServiceName("%sService"); // 生成的service接口名字首字母是否为I,这样设置就没有
+        gc.setBaseResultMap(true); // 生成resultMap
+        mpg.setGlobalConfig(gc);
+
+        // 2、数据源配置
+        // 修改数据源
+        DataSourceConfig dsc = new DataSourceConfig();
+        dsc.setUrl("jdbc:mysql://192.168.10.165:3306/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setDriverName("com.mysql.jdbc.Driver");
+        dsc.setUsername("root");
+        dsc.setPassword("yt123456");
+        mpg.setDataSource(dsc);
+
+        // 3、包配置
+        PackageConfig pc = new PackageConfig();
+        pc.setParent("com.usky.data");
+        pc.setController("controller.web");
+        pc.setEntity("domain");
+        pc.setMapper("mapper");
+        pc.setService("service");
+        pc.setServiceImpl("service.impl");
+//        pc.setXml("mapper.data");
+        // pc.setModuleName("test");
+        mpg.setPackageInfo(pc);
+
+        // 4、策略配置
+        StrategyConfig strategy = new StrategyConfig();
+        strategy.setNaming(NamingStrategy.underline_to_camel);
+        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+        strategy.setSuperMapperClass("com.usky.common.mybatis.core.CrudMapper");
+        strategy.setSuperServiceClass("com.usky.common.mybatis.core.CrudService");
+        strategy.setSuperServiceImplClass("com.usky.common.mybatis.core.AbstractCrudService");
+        // strategy.setTablePrefix("t_"); // 表名前缀
+        strategy.setEntityLombokModel(true); // 使用lombok
+        // 修改自己想要生成的表
+        String[] tables = {"data_interface","data_interface_log"};
+        strategy.setInclude(tables);  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        mpg.setStrategy(strategy);
+
+        // 关闭默认 xml 生成,调整生成 至 根目录
+        // 修改对应的模块名称
+        TemplateConfig tc = new TemplateConfig();
+        // 自定义配置
+        InjectionConfig cfg = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                // to do nothing
+            }
+        };
+        // 如果模板引擎是 velocity
+        String templatePath = "/templates/mapper.xml.vm";
+        // 自定义输出配置
+        List<FileOutConfig> focList = new ArrayList<>();
+        // 自定义配置会被优先输出
+        String finalProjectPath = projectPath;
+        focList.add(new FileOutConfig(templatePath) {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
+                return finalProjectPath + "/src/main/resources/mapper/data" + "/"
+                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+            }
+        });
+        cfg.setFileOutConfigList(focList);
+        mpg.setCfg(cfg);
+        tc.setXml(null);
+        mpg.setTemplate(tc);
+        // 5、执行
+        mpg.execute();
+    }
+}

+ 222 - 0
service-data/service-data-biz/src/main/java/com/usky/data/controller/web/DataInterfaceController.java

@@ -0,0 +1,222 @@
+package com.usky.data.controller.web;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.data.domain.DataInterface;
+import com.usky.data.service.DataInterfaceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 数据中心_数据接口表 前端控制器
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+@RestController
+@RequestMapping("/dataInterface")
+public class DataInterfaceController {
+
+    @Autowired
+    private DataInterfaceService dataInterfaceService;
+
+    /**
+     * 获取数据接口列表
+     *
+     * @param currentPage 当前页
+     * @param pageSize    每页数量
+     * @param keyword     关键字
+     * @param type        接口类型 1:SQL操作, 2:静态数据, 3:API操作
+     * @param enabledMark 启用状态 0:未启用,1:已启用
+     * @param category    接口分类
+     * @return
+     */
+    @RequestMapping
+    @GetMapping
+    public ApiResult<CommonPage<DataInterface>> getDataInterfaceList(@RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
+                                                                     @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
+                                                                     @RequestParam(value = "keyword", required = false) String keyword,
+                                                                     @RequestParam(value = "type", required = false) String type,
+                                                                     @RequestParam(value = "enabledMark", required = false) Integer enabledMark,
+                                                                     @RequestParam(value = "category", required = false) String category
+    ) {
+        return ApiResult.success(dataInterfaceService.getDataInterfaceList(currentPage, pageSize, keyword, type, enabledMark, category));
+    }
+
+    /**
+     * 获取接口列表(工作流选择时调用)
+     *
+     * @param currentPage 当前页
+     * @param pageSize    每页数量
+     * @param keyword     关键字
+     * @param type        接口类型 1:静态数据, 2:SQL操作, 3:API操作
+     * @param enabledMark 启用状态 0:未启用,1:已启用
+     * @return
+     */
+    @GetMapping("/getList")
+    public ApiResult<CommonPage<DataInterface>> getWorkflowList(@RequestParam(value = "currentPage", defaultValue = "1") Integer currentPage,
+                                                                @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize,
+                                                                @RequestParam(value = "keyword", required = false) String keyword,
+                                                                @RequestParam(value = "type", required = false) String type,
+                                                                @RequestParam(value = "enabledMark", required = false) Integer enabledMark
+    ) {
+        return ApiResult.success(dataInterfaceService.getWorkflowList(currentPage, pageSize, keyword, type, enabledMark));
+    }
+
+    /**
+     * 获取接口列表下拉框
+     *
+     * @return
+     */
+    @GetMapping("/Selector")
+    public ApiResult<List<DataInterface>> getSelector() {
+        return ApiResult.success(dataInterfaceService.getSelectorList());
+    }
+
+    /**
+     * 获取接口参数列表下拉框
+     *
+     * @param id 主键
+     * @return
+     */
+    @GetMapping("/getParam/{id}")
+    public ApiResult<String> getInterfaceParams(@PathVariable("id") String id) {
+        return ApiResult.success(dataInterfaceService.getInterfaceParameters(id));
+    }
+
+    /**
+     * 获取接口数据
+     *
+     * @param id 主键
+     * @return
+     */
+    @GetMapping("/{id}")
+    public ApiResult<DataInterface> getInterfaceInfo(@PathVariable("id") String id) {
+        return ApiResult.success(dataInterfaceService.getById(id));
+    }
+
+    /**
+     * 添加接口
+     *
+     * @param dataInterface 接口实体
+     * @return
+     */
+    @PostMapping
+    public ApiResult<Boolean> addInterface(@RequestBody DataInterface dataInterface) {
+        return ApiResult.success(dataInterfaceService.addInterface(dataInterface));
+    }
+
+    /**
+     * 修改接口
+     *
+     * @param dataInterface 接口实体
+     * @return
+     */
+    @PutMapping
+    public ApiResult<Boolean> updateInterface(@RequestBody DataInterface dataInterface) {
+        return ApiResult.success(dataInterfaceService.updateInterface(dataInterface));
+    }
+
+    /**
+     * 删除接口
+     *
+     * @param id 主键
+     * @return
+     */
+    @DeleteMapping("/{id}")
+    public ApiResult<Boolean> deleteInterface(@PathVariable("id") Long id) {
+        return ApiResult.success(dataInterfaceService.deleteInterface(id));
+    }
+
+    /**
+     * 更新接口状态
+     *
+     * @param id 主键
+     * @return
+     */
+    @PutMapping("/{id}/Actions/State")
+    public ApiResult<Boolean> updateInterfaceState(@PathVariable("id") String id) {
+        return ApiResult.success(dataInterfaceService.updateInterfaceStatus(id));
+    }
+
+    /**
+     * 测试接口
+     *
+     * @param id     主键
+     * @param params 参数、参数值对象
+     * @return
+     */
+    @PostMapping("/{id}/actions/preview")
+    public ApiResult<?> testInterface(@PathVariable("id") String id, @RequestBody(required = false) Map<String, Object> params) {
+        return dataInterfaceService.testInterface(id, params);
+    }
+
+    /**
+     * 访问接口GET
+     *
+     * @param id     主键
+     * @param params 参数、参数值对象
+     * @return
+     */
+    @GetMapping("/{id}/actions/response")
+    public ApiResult<?> getInterfaceResponse(@PathVariable("id") String id, @RequestParam(required = false) Map<String, String> params) {
+        return dataInterfaceService.getInterfaceResponse(id, params);
+    }
+
+    /**
+     * 访问接口POST
+     *
+     * @param id     主键
+     * @param params 参数、参数值对象
+     * @return
+     */
+    @PostMapping("/{id}/actions/response")
+    public ApiResult<?> postInterfaceResponse(@PathVariable("id") String id, @RequestBody(required = false) Map<String, String> params) {
+        return dataInterfaceService.postInterfaceResponse(id, params);
+    }
+
+    /**
+     * 获取接口分页数据
+     *
+     * @param id         主键
+     * @param pageParams 分页参数
+     * @return
+     */
+    @PostMapping("/{id}/actions/list")
+    public ApiResult<?> getInterfacePageData(@PathVariable("id") String id, @RequestBody Map<String, Object> pageParams) {
+        return dataInterfaceService.getInterfacePageData(id, pageParams);
+    }
+
+    /**
+     * 获取接口详情数据
+     *
+     * @param id         主键
+     * @param pageParams 分页参数
+     * @return
+     */
+    @PostMapping("/{id}/actions/infoByIds")
+    public ApiResult<List<Map<String, Object>>> getInterfaceDetailData(@PathVariable("id") String id, @RequestBody Map<String, Object> pageParams) {
+        return dataInterfaceService.getInterfaceDetailData(id, pageParams);
+    }
+
+    /**
+     * 获取接口字段
+     *
+     * @param id         主键
+     * @param pageParams 参数、参数值
+     * @return
+     */
+    @PostMapping("/{id}/actions/getFields")
+    public ApiResult<List<String>> getInterfaceFields(@PathVariable("id") String id, @RequestBody(required = false) Map<String, Object> pageParams) {
+        return dataInterfaceService.getInterfaceFields(id, pageParams);
+    }
+}
+

+ 21 - 0
service-data/service-data-biz/src/main/java/com/usky/data/controller/web/DataInterfaceLogController.java

@@ -0,0 +1,21 @@
+package com.usky.data.controller.web;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+
+/**
+ * <p>
+ * 数据中心_接口调用日志表 前端控制器
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+@Controller
+@RequestMapping("/dataInterfaceLog")
+public class DataInterfaceLogController {
+
+}
+

+ 229 - 0
service-data/service-data-biz/src/main/java/com/usky/data/controller/web/DataLinkController.java

@@ -0,0 +1,229 @@
+package com.usky.data.controller.web;
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.data.domain.DataLink;
+import com.usky.data.model.DbLinkBaseForm;
+import com.usky.data.model.DbLinkCreUpForm;
+import com.usky.data.model.PaginationDbLink;
+import com.usky.data.service.DataLinkService;
+import com.usky.data.vo.*;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 数据源配置控制器
+ *
+ * @author fyc
+ * @since 2026-01-23
+ */
+@Tag(name = "数据连接", description = "DataSource")
+@RestController
+@RequestMapping("/dataSource")
+public class DataLinkController {
+
+    @Autowired
+    private DataLinkService dataLinkService;
+
+    /**
+     * 获取数据连接下拉框列表
+     */
+    @GetMapping("/selector")
+    @Operation(summary = "获取数据连接下拉框列表")
+    public ApiResult<ListVO<DbLinkSelectorListVO>> selectorList(@RequestParam(value = "dbType") String type) {
+        List<DbLinkListVO> modelAll = new LinkedList<>();
+        List<DataLink> dbLinkList = dataLinkService.getList();
+
+        // 转换为VO列表
+        for (DataLink entity : dbLinkList) {
+            DbLinkListVO model = new DbLinkListVO();
+            BeanUtils.copyProperties(entity, model);
+            modelAll.add(model);
+        }
+
+        // 按数据库类型分组
+        Map<String, List<DbLinkListVO>> groupByType = modelAll.stream()
+                .collect(Collectors.groupingBy(DbLinkListVO::getDbType));
+
+        List<DbLinkSelectorListVO> list = new ArrayList<>();
+        // type为空时返回默认库
+        if (type == null) {
+            DbLinkListVO dbLink = new DbLinkListVO();
+            dbLink.setFullName("默认数据库");
+            dbLink.setId(0);
+            // 默认数据库类型
+            dbLink.setDbType("mysql");
+            DbLinkSelectorListVO defaultDb = new DbLinkSelectorListVO();
+            defaultDb.setFullName("");
+            defaultDb.setChildren(Collections.singletonList(dbLink));
+            list.add(defaultDb);
+        }
+
+        // 添加分组后的数据源
+        for (Map.Entry<String, List<DbLinkListVO>> entry : groupByType.entrySet()) {
+            DbLinkSelectorListVO selector = new DbLinkSelectorListVO();
+            selector.setFullName(entry.getKey());
+            selector.setChildren(entry.getValue());
+            list.add(selector);
+        }
+
+        return ApiResult.success(new ListVO<>(list));
+    }
+
+    /**
+     * 获取数据连接列表
+     */
+    @GetMapping
+    @Operation(summary = "获取数据连接列表")
+    public ApiResult<PageListVO<DbLinkListVO>> getList(@RequestBody PaginationDbLink page) {
+        List<DataLink> data = dataLinkService.getList(
+                page.getCurrentPage(),
+                page.getPageSize(),
+                page.getKeyword()
+        );
+
+        // 转换为VO列表
+        List<DbLinkListVO> jsonToList = new ArrayList<>();
+        for (DataLink entity : data) {
+            DbLinkListVO vo = new DbLinkListVO();
+            BeanUtils.copyProperties(entity, vo);
+            jsonToList.add(vo);
+        }
+
+        // 构建分页信息
+        PaginationVO paginationVO = new PaginationVO();
+        paginationVO.setCurrentPage(page.getCurrentPage());
+        paginationVO.setPageSize(page.getPageSize());
+        paginationVO.setTotalRows(data.size());
+        paginationVO.setTotalPages((int) Math.ceil((double) data.size() / page.getPageSize()));
+
+        return ApiResult.success(new PageListVO<>(jsonToList, paginationVO));
+    }
+
+    /**
+     * 获取数据连接列表分组
+     */
+    @GetMapping("/getGroup")
+    @Operation(summary = "获取数据连接列表分组")
+    public ApiResult<List<Map<String, Object>>> getGroup(@RequestBody PaginationDbLink page) {
+        ApiResult<PageListVO<DbLinkListVO>> result = getList(page);
+        List<DbLinkListVO> voList = result.getData().getList();
+
+        // 按host分组
+        Set<String> hostSet = voList.stream()
+                .sorted(Comparator.comparing(DbLinkListVO::getHost))
+                .map(DbLinkListVO::getHost)
+                .collect(Collectors.toSet());
+
+        List<Map<String, Object>> groupList = new ArrayList<>();
+        for (String host : hostSet) {
+            Map<String, Object> groupMap = new HashMap<>();
+            groupMap.put("host", host);
+            groupMap.put("options", voList.stream()
+                    .filter(vo -> vo.getHost().equals(host))
+                    .toArray());
+            groupList.add(groupMap);
+        }
+
+        return ApiResult.success(groupList);
+    }
+
+    /**
+     * 获取单条数据连接
+     */
+    @GetMapping("/{id}")
+    @Operation(summary = "获取数据连接")
+    @Parameters({
+            @Parameter(name = "id", description = "主键")
+    })
+    public ApiResult<DbLinkInfoVO> get(@PathVariable("id") Integer id) {
+        DataLink entity = dataLinkService.getById(id);
+        if (entity == null) {
+            return ApiResult.error("数据源不存在");
+        }
+        DbLinkInfoVO vo = new DbLinkInfoVO();
+        return ApiResult.success(vo.getDbLinkInfoVO(entity));
+    }
+
+    /**
+     * 新建数据连接
+     */
+    @PostMapping
+    @Operation(summary = "添加数据连接")
+    @Parameters({
+            @Parameter(name = "dbLinkCreUpForm", description = "新建数据连接表单对象", required = true)
+    })
+    public ApiResult<String> create(@RequestBody @Validated DbLinkCreUpForm dbLinkCreUpForm) {
+        DataLink entity = dbLinkCreUpForm.getDbLinkEntity(dbLinkCreUpForm);
+        if (dataLinkService.isExistByFullName(entity.getFullName(), null)) {
+            return ApiResult.error("连接名称已存在");
+        }
+        return ApiResult.success(dataLinkService.save(entity) ? "新增成功" : "新增失败");
+    }
+
+    /**
+     * 更新数据连接
+     */
+    @PutMapping("/{id}")
+    @Operation(summary = "修改数据连接")
+    @Parameters({
+            @Parameter(name = "id", description = "主键", required = true),
+            @Parameter(name = "dbLinkCreUpForm", description = "更新数据连接表单对象", required = true)
+    })
+    public ApiResult<String> update(@PathVariable("id") Integer id, @RequestBody @Validated DbLinkCreUpForm dbLinkCreUpForm) {
+        dbLinkCreUpForm.setId(id);
+        DataLink entity = dbLinkCreUpForm.getDbLinkEntity(dbLinkCreUpForm);
+        if (dataLinkService.isExistByFullName(entity.getFullName(), id)) {
+            throw new BusinessException("连接名称已存在");
+        }
+        if (!dataLinkService.updateById(entity)) {
+            return ApiResult.error("更新失败");
+        }
+        return ApiResult.success("更新成功");
+    }
+
+    /**
+     * 删除数据连接
+     */
+    @DeleteMapping("/{id}")
+    @Operation(summary = "删除数据连接")
+    @Parameters({
+            @Parameter(name = "id", description = "主键", required = true)
+    })
+    public ApiResult<String> delete(@PathVariable("id") Integer id) {
+        DataLink entity = dataLinkService.getById(id);
+        if (entity != null) {
+            dataLinkService.removeById(entity);
+            return ApiResult.success("删除成功");
+        }
+        return ApiResult.error("数据源不存在");
+    }
+
+    /**
+     * 测试连接
+     */
+    @PostMapping("/actions/test")
+    @Operation(summary = "测试连接")
+    @Parameters({
+            @Parameter(name = "dbLinkBaseForm", description = "数据连接参数", required = true)
+    })
+    public ApiResult<String> test(@RequestBody DbLinkBaseForm dbLinkBaseForm) throws Exception {
+        boolean data = dataLinkService.testDbConnection(dbLinkBaseForm.getDbLinkEntity(dbLinkBaseForm));
+        if (data) {
+            return ApiResult.success("连接成功");
+        } else {
+            return ApiResult.error("连接失败");
+        }
+    }
+}
+

+ 179 - 0
service-data/service-data-biz/src/main/java/com/usky/data/domain/DataInterface.java

@@ -0,0 +1,179 @@
+package com.usky.data.domain;
+
+import java.time.LocalDateTime;
+import java.io.Serializable;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * <p>
+ * 数据中心_数据接口表
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DataInterface implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 接口名称
+     */
+    @NotBlank(message = "接口名称不能为空")
+    private String fullName;
+
+    /**
+     * 接口编码
+     */
+    @NotBlank(message = "接口编码不能为空")
+    private String enCode;
+
+    /**
+     * 接口分类
+     */
+    private String category;
+
+    /**
+     * 接口类型(1:静态数据, 2:SQL操作, 3:API操作)
+     */
+    @NotNull(message = "接口类型不能为空")
+    private Integer type;
+
+    /**
+     * 操作类型()
+     */
+    private Integer action;
+
+    /**
+     * 分页(0-禁用,1-启用)
+     */
+    private Integer hasPage;
+
+    /**
+     * 后置接口(0-否 1-是)
+     */
+    private Integer isPostposition;
+
+    /**
+     * 字段JSON
+     */
+    private String fieldJson;
+
+    /**
+     * 数据配置JSON
+     */
+    @TableField("config_json")
+    @NotBlank(message = "数据配置JSON不能为空")
+    private String dataConfigJson;
+
+    /**
+     * 数据统计json
+     */
+    @TableField("count_json")
+    @NotBlank(message = "数据统计json不能为空")
+    private String dataCountJson;
+
+    /**
+     * 数据回显json
+     */
+    @TableField("echo_json")
+    @NotBlank(message = "数据回显json不能为空")
+    private String dataEchoJson;
+
+    /**
+     * 数据处理json
+     */
+    @TableField("js_json")
+    @NotBlank(message = "数据处理json不能为空")
+    private String dataJsJson;
+
+    /**
+     * 参数配置JSON
+     */
+    private String parameterJson;
+
+    /**
+     * 异常验证JSON
+     */
+    private String exceptionJson;
+
+    /**
+     * 描述或说明
+     */
+    private String description;
+
+    /**
+     * 启用状态(0-禁用,1-启用)
+     */
+    private Integer enabledMark;
+
+    /**
+     * 排序
+     */
+    private Long sortCode;
+
+    /**
+     * 创建者
+     */
+    @NotBlank(message = "创建人不能为空")
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @NotNull(message = "创建时间不能为空")
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    @NotBlank(message = "更新人不能为空")
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    @NotNull(message = "更新时间不能为空")
+    private LocalDateTime updateTime;
+
+    /**
+     * 删除时间
+     */
+    @NotNull(message = "删除时间不能为空")
+    private LocalDateTime deleteTime;
+
+    /**
+     * 删除用户
+     */
+    @NotBlank(message = "删除人不能为空")
+    private String deleteBy;
+
+    /**
+     * 是否删除 0:未删除,1:已删除
+     */
+    private Integer isDelete;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+
+}

+ 122 - 0
service-data/service-data-biz/src/main/java/com/usky/data/domain/DataInterfaceLog.java

@@ -0,0 +1,122 @@
+package com.usky.data.domain;
+
+import java.time.LocalDateTime;
+import java.io.Serializable;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 数据中心_接口调用日志表
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DataInterfaceLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 调用接口ID
+     */
+    private Long interfaceId;
+
+    /**
+     * 执行时间
+     */
+    private LocalDateTime executeTime;
+
+    /**
+     * 操作用户ID
+     */
+    private String userId;
+
+    /**
+     * 请求ip
+     */
+    private String requestIp;
+
+    /**
+     * 请求设备
+     */
+    private String requestDevice;
+
+    /**
+     * 请求类型
+     */
+    private String requestType;
+
+    /**
+     * 请求耗时
+     */
+    private Integer requestWasteTime;
+
+    /**
+     * 接口授权AppId
+     */
+    private String oauthAppId;
+
+    /**
+     * 排序
+     */
+    private Long sortCode;
+
+    /**
+     * 执行结果
+     */
+    private String executeResult;
+
+    /**
+     * 执行状态
+     */
+    private Integer executeState;
+
+    /**
+     * 执行消息
+     */
+    private String executeMsg;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+
+}

+ 136 - 0
service-data/service-data-biz/src/main/java/com/usky/data/domain/DataLink.java

@@ -0,0 +1,136 @@
+package com.usky.data.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 数据中心_数据连接表
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-23
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DataLink implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 连接名称
+     */
+    private String fullName;
+
+    /**
+     * 连接驱动
+     */
+    private String dbType;
+
+    /**
+     * 主机地址
+     */
+    private String host;
+
+    /**
+     * 端口
+     */
+    private Integer port;
+
+    /**
+     * 数据库用户名
+     */
+    private String dbName;
+
+    /**
+     * 密码
+     */
+    private String password;
+
+    /**
+     * 服务名称
+     */
+    private String serviceName;
+
+    /**
+     * 描述或说明
+     */
+    private String description;
+
+    /**
+     * 模式
+     */
+    private String dbSchema;
+
+    /**
+     * 表空间
+     */
+    private String tableSpace;
+
+    /**
+     * oracle连接参数
+     */
+    private String oracleParam;
+
+    /**
+     * Oracle扩展开关 1:开启 0:关闭
+     */
+    private Integer oracleExtend;
+
+    /**
+     * 排序
+     */
+    private Integer sortCode;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 创建用户
+     */
+    private String createBy;
+
+    /**
+     * 修改时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 修改用户
+     */
+    private String updateBy;
+
+    /**
+     * 删除时间
+     */
+    private LocalDateTime deleteTime;
+
+    /**
+     * 删除用户
+     */
+    private String deleteBy;
+
+    /**
+     * 是否删除 0:未删除,1:已删除
+     */
+    private Integer isDelete;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+
+}

+ 16 - 0
service-data/service-data-biz/src/main/java/com/usky/data/mapper/DataInterfaceLogMapper.java

@@ -0,0 +1,16 @@
+package com.usky.data.mapper;
+
+import com.usky.data.domain.DataInterfaceLog;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 数据中心_接口调用日志表 Mapper 接口
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+public interface DataInterfaceLogMapper extends CrudMapper<DataInterfaceLog> {
+
+}

+ 16 - 0
service-data/service-data-biz/src/main/java/com/usky/data/mapper/DataInterfaceMapper.java

@@ -0,0 +1,16 @@
+package com.usky.data.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.data.domain.DataInterface;
+
+/**
+ * <p>
+ * 数据中心_数据接口表 Mapper 接口
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+public interface DataInterfaceMapper extends CrudMapper<DataInterface> {
+
+}

+ 34 - 0
service-data/service-data-biz/src/main/java/com/usky/data/mapper/DataLinkMapper.java

@@ -0,0 +1,34 @@
+package com.usky.data.mapper;
+
+import com.usky.data.domain.DataLink;
+import com.usky.common.mybatis.core.CrudMapper;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 数据中心_数据连接表 Mapper 接口
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-23
+ */
+public interface DataLinkMapper extends CrudMapper<DataLink> {
+
+    /**
+     * 根据连接名称统计数量(排除指定ID)
+     * @param fullName 连接名称
+     * @param id 排除的主键ID
+     * @return 数量
+     */
+    int countByFullName(String fullName, Integer id);
+
+    /**
+     * 分页查询数据源列表
+     * @param startIndex 起始索引
+     * @param pageSize 每页条数
+     * @param keyword 关键字
+     * @return 数据源列表
+     */
+    List<DataLink> selectPageList(int startIndex, int pageSize, String keyword);
+}

+ 34 - 0
service-data/service-data-biz/src/main/java/com/usky/data/model/DataInterfaceModel.java

@@ -0,0 +1,34 @@
+package com.usky.data.model;
+
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class DataInterfaceModel extends ParamModel implements Serializable {
+
+    /**
+     * 是否为空(0允许,1不允许)
+     */
+    @Schema(description = "是否为空(0允许,1不允许)")
+    private Integer required;
+
+    /**
+     * 参数名称
+     */
+    @Schema(description = "参数名称")
+    private String parameter;
+    /**
+     * 参数来源
+     */
+    @Schema(description = "参数来源(1-字段,2-自定义,3-为空,4-系统变量)")
+    private Integer sourceType = 1;
+
+    /**
+     * 表单字段
+     */
+    @Schema(description = "表单字段")
+    private String relationField;
+}

+ 52 - 0
service-data/service-data-biz/src/main/java/com/usky/data/model/DbLinkBaseForm.java

@@ -0,0 +1,52 @@
+package com.usky.data.model;
+
+import com.usky.data.domain.DataLink;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 数据源基础表单
+ */
+@Data
+public class DbLinkBaseForm {
+    @NotBlank(message = "连接名称不能为空")
+    private String fullName;
+    @NotBlank(message = "数据库类型不能为空")
+    private String dbType;
+    @NotBlank(message = "主机地址不能为空")
+    private String host;
+    private Integer port;
+    @NotBlank(message = "数据库用户名不能为空")
+    private String dbName;
+    @NotBlank(message = "密码不能为空")
+    private String password;
+    private String serviceName;
+    private String description;
+    private String dbSchema;
+    private String tableSpace;
+    private String oracleParam;
+    private Integer oracleExtend;
+    private Integer sortCode;
+
+    /**
+     * 转换为实体对象
+     */
+    public DataLink getDbLinkEntity(DbLinkBaseForm form) {
+        DataLink dataLink = new DataLink();
+        dataLink.setFullName(form.getFullName());
+        dataLink.setDbType(form.getDbType());
+        dataLink.setHost(form.getHost());
+        dataLink.setPort(form.getPort());
+        dataLink.setDbName(form.getDbName());
+        dataLink.setPassword(form.getPassword());
+        dataLink.setServiceName(form.getServiceName());
+        dataLink.setDescription(form.getDescription());
+        dataLink.setDbSchema(form.getDbSchema());
+        dataLink.setTableSpace(form.getTableSpace());
+        dataLink.setOracleParam(form.getOracleParam());
+        dataLink.setOracleExtend(form.getOracleExtend());
+        dataLink.setSortCode(form.getSortCode());
+        return dataLink;
+    }
+}

+ 24 - 0
service-data/service-data-biz/src/main/java/com/usky/data/model/DbLinkCreUpForm.java

@@ -0,0 +1,24 @@
+package com.usky.data.model;
+
+import com.usky.data.domain.DataLink;
+import lombok.Data;
+
+/**
+ * 数据源创建/更新表单
+ */
+@Data
+public class DbLinkCreUpForm extends DbLinkBaseForm {
+    private Integer id;
+
+    /**
+     * 转换为实体对象
+     */
+    @Override
+    public DataLink getDbLinkEntity(DbLinkBaseForm form) {
+        DataLink dataLink = super.getDbLinkEntity(form);
+        if (this.getId() != null) {
+            dataLink.setId(this.getId());
+        }
+        return dataLink;
+    }
+}

+ 24 - 0
service-data/service-data-biz/src/main/java/com/usky/data/model/FieldModel.java

@@ -0,0 +1,24 @@
+package com.usky.data.model;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+@Data
+public class FieldModel implements Serializable {
+    @Schema(description = "主键")
+    private String id;
+
+    @Schema(description = "参数名称")
+    private String field;
+
+    @Schema(description = "默认值")
+    private String defaultValue;
+
+    public void setDefaultValue(Object defaultValue) {
+        if (Objects.isNull(defaultValue) || defaultValue.toString().trim().isEmpty()) return;
+        this.defaultValue = defaultValue.toString();
+    }
+}

+ 14 - 0
service-data/service-data-biz/src/main/java/com/usky/data/model/PaginationDbLink.java

@@ -0,0 +1,14 @@
+package com.usky.data.model;
+
+import lombok.Data;
+
+/**
+ * 数据源分页查询参数
+ */
+@Data
+public class PaginationDbLink {
+    private Integer currentPage = 1;
+    private Integer pageSize = 20;
+    private String keyword;
+    private String type;
+}

+ 26 - 0
service-data/service-data-biz/src/main/java/com/usky/data/model/ParamModel.java

@@ -0,0 +1,26 @@
+package com.usky.data.model;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ParamModel extends FieldModel implements Serializable {
+
+    @Schema(description = "列说明")
+    private String fieldName;
+
+    /**
+     * 参数类型
+     * 字符串
+     * 整型
+     * 日期时间
+     * 浮点
+     * 长整型
+     * 文本
+     */
+    @Schema(description = "参数类型")
+    private String dataType;
+
+}

+ 16 - 0
service-data/service-data-biz/src/main/java/com/usky/data/service/DataInterfaceLogService.java

@@ -0,0 +1,16 @@
+package com.usky.data.service;
+
+import com.usky.data.domain.DataInterfaceLog;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 数据中心_接口调用日志表 服务类
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+public interface DataInterfaceLogService extends CrudService<DataInterfaceLog> {
+
+}

+ 49 - 0
service-data/service-data-biz/src/main/java/com/usky/data/service/DataInterfaceService.java

@@ -0,0 +1,49 @@
+package com.usky.data.service;
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.data.domain.DataInterface;
+
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 数据中心_数据接口表 服务类
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+public interface DataInterfaceService extends CrudService<DataInterface> {
+
+    CommonPage<DataInterface> getDataInterfaceList(Integer currentPage, Integer pageSize, String keyword, String type, Integer enabledMark, String category);
+
+    CommonPage<DataInterface> getWorkflowList(Integer currentPage, Integer pageSize, String keyword, String type, Integer enabledMark);
+
+    List<DataInterface> getSelectorList();
+
+    String getInterfaceParameters(String id);
+
+    boolean updateInterfaceStatus(String id);
+
+    ApiResult<?> testInterface(String id, Map<String, Object> params);
+
+    ApiResult<?> getInterfaceResponse(String id, Map<String, String> params);
+
+    ApiResult<?> postInterfaceResponse(String id, Map<String, String> params);
+
+    ApiResult<?> getInterfacePageData(String id, Map<String, Object> pageParams);
+
+    ApiResult<List<Map<String, Object>>> getInterfaceDetailData(String id, Map<String, Object> pageParams);
+
+    ApiResult<List<String>> getInterfaceFields(String id, Map<String, Object> pageParams);
+
+    Boolean deleteInterface(Long id);
+
+    Boolean addInterface(DataInterface dataInterface);
+
+    Boolean updateInterface(DataInterface dataInterface);
+}

+ 47 - 0
service-data/service-data-biz/src/main/java/com/usky/data/service/DataLinkService.java

@@ -0,0 +1,47 @@
+package com.usky.data.service;
+
+import com.usky.data.domain.DataLink;
+import com.usky.common.mybatis.core.CrudService;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 数据中心_数据连接表 服务类
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-23
+ */
+public interface DataLinkService extends CrudService<DataLink> {
+
+    /**
+     * 测试数据库连接
+     * @param dataLink 数据源信息
+     * @return 是否连接成功
+     */
+    boolean testDbConnection(DataLink dataLink);
+
+    /**
+     * 根据连接名称检查是否存在
+     * @param fullName 连接名称
+     * @param id 排除的主键ID
+     * @return 是否存在
+     */
+    boolean isExistByFullName(String fullName, Integer id);
+
+    /**
+     * 获取所有数据源列表
+     * @return 数据源列表
+     */
+    List<DataLink> getList();
+
+    /**
+     * 分页获取数据源列表
+     * @param page 页码
+     * @param pageSize 每页条数
+     * @param keyword 关键字
+     * @return 数据源列表
+     */
+    List<DataLink> getList(int page, int pageSize, String keyword);
+}

+ 20 - 0
service-data/service-data-biz/src/main/java/com/usky/data/service/impl/DataInterfaceLogServiceImpl.java

@@ -0,0 +1,20 @@
+package com.usky.data.service.impl;
+
+import com.usky.data.domain.DataInterfaceLog;
+import com.usky.data.mapper.DataInterfaceLogMapper;
+import com.usky.data.service.DataInterfaceLogService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 数据中心_接口调用日志表 服务实现类
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+@Service
+public class DataInterfaceLogServiceImpl extends AbstractCrudService<DataInterfaceLogMapper, DataInterfaceLog> implements DataInterfaceLogService {
+
+}

+ 291 - 0
service-data/service-data-biz/src/main/java/com/usky/data/service/impl/DataInterfaceServiceImpl.java

@@ -0,0 +1,291 @@
+package com.usky.data.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.data.domain.DataInterface;
+import com.usky.data.mapper.DataInterfaceMapper;
+import com.usky.data.service.DataInterfaceService;
+import com.usky.data.service.util.InterfaceExecutor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 数据中心_数据接口表 服务实现类
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-24
+ */
+@Service
+@Slf4j
+public class DataInterfaceServiceImpl extends AbstractCrudService<DataInterfaceMapper, DataInterface> implements DataInterfaceService {
+
+    @Override
+    public CommonPage<DataInterface> getDataInterfaceList(Integer currentPage, Integer pageSize, String keyword, String type, Integer enabledMark, String category) {
+
+        // if (StringUtils.isBlank(category)) {
+        //     throw new BusinessException("接口分类不能为空!");
+        // }
+
+        IPage<DataInterface> page = new Page<>(currentPage, pageSize);
+        LambdaQueryWrapper<DataInterface> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(StringUtils.isNotBlank(category), DataInterface::getCategory, category)
+                .eq(DataInterface::getTenantId, SecurityUtils.getTenantId())
+                .eq(DataInterface::getIsDelete, 0)
+                .orderByDesc(DataInterface::getSortCode);
+        queryWrapper.eq(StringUtils.isNotBlank(type), DataInterface::getType, type)
+                .eq(enabledMark != null, DataInterface::getEnabledMark, enabledMark);
+        if (StringUtils.isNotBlank(keyword)) {
+            queryWrapper.like(DataInterface::getFullName, keyword)
+                    .or()
+                    .like(DataInterface::getEnCode, keyword);
+        }
+        page = baseMapper.selectPage(page, queryWrapper);
+        return new CommonPage<>(page.getRecords(), page.getTotal(), page.getCurrent(), page.getSize());
+    }
+
+    @Override
+    public CommonPage<DataInterface> getWorkflowList(Integer currentPage, Integer pageSize, String keyword, String type, Integer enabledMark) {
+        IPage<DataInterface> page = new Page<>(currentPage, pageSize);
+        LambdaQueryWrapper<DataInterface> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DataInterface::getTenantId, SecurityUtils.getTenantId())
+                .like(StringUtils.isNotBlank(keyword), DataInterface::getFullName, keyword)
+                .like(StringUtils.isNotBlank(keyword), DataInterface::getEnCode, keyword)
+                .eq(StringUtils.isNotBlank(type), DataInterface::getType, type)
+                .eq(enabledMark != null, DataInterface::getEnabledMark, enabledMark)
+                .eq(DataInterface::getEnabledMark, 1); // 工作流选择时只显示启用的接口
+        page = baseMapper.selectPage(page, queryWrapper);
+        return new CommonPage<>(page.getRecords(), page.getTotal(), page.getCurrent(), page.getSize());
+    }
+
+    @Override
+    public List<DataInterface> getSelectorList() {
+        LambdaQueryWrapper<DataInterface> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DataInterface::getTenantId, SecurityUtils.getTenantId())
+                .eq(DataInterface::getEnabledMark, 1); // 只返回启用的接口
+        return baseMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    public String getInterfaceParameters(String id) {
+        DataInterface entity = baseMapper.selectById(id);
+        return entity != null ? entity.getParameterJson() : "[]";
+    }
+
+    @Override
+    public boolean updateInterfaceStatus(String id) {
+        DataInterface entity = baseMapper.selectById(id);
+        if (entity == null) {
+            return false;
+        }
+        // 切换启用状态
+        entity.setEnabledMark(entity.getEnabledMark() == 1 ? 0 : 1);
+        return baseMapper.updateById(entity) > 0;
+    }
+
+    @Override
+    public ApiResult<?> testInterface(String id, Map<String, Object> params) {
+        // 根据ID获取接口配置
+        DataInterface interfaceEntity = baseMapper.selectById(id);
+        if (interfaceEntity == null) {
+            return ApiResult.error("接口不存在");
+        }
+
+        try {
+            // 执行接口逻辑
+            Object result = InterfaceExecutor.executeInterface(interfaceEntity, params);
+            return ApiResult.success(result);
+        } catch (Exception e) {
+            return ApiResult.error("接口测试失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ApiResult<?> getInterfaceResponse(String id, Map<String, String> params) {
+        // 这里是访问接口GET的实现,实际逻辑需要根据接口类型和配置进行处理
+        DataInterface interfaceEntity = baseMapper.selectById(id);
+        if (interfaceEntity == null) {
+            return ApiResult.error("接口不存在");
+        }
+
+        try {
+            // 将String类型的Map转换为Object类型的Map
+            Map<String, Object> objectParams = new HashMap<>();
+            if (params != null) {
+                params.forEach((k, v) -> objectParams.put(k, v));
+            }
+
+            // 执行接口逻辑
+            Object result = InterfaceExecutor.executeInterface(interfaceEntity, objectParams);
+            return ApiResult.success(result);
+        } catch (Exception e) {
+            return ApiResult.error("接口访问失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ApiResult<?> postInterfaceResponse(String id, Map<String, String> params) {
+        // 这里是访问接口POST的实现,实际逻辑需要根据接口类型和配置进行处理
+        DataInterface interfaceEntity = baseMapper.selectById(id);
+        if (interfaceEntity == null) {
+            return ApiResult.error("接口不存在");
+        }
+
+        try {
+            // 将String类型的Map转换为Object类型的Map
+            Map<String, Object> objectParams = new HashMap<>();
+            if (params != null) {
+                params.forEach((k, v) -> objectParams.put(k, v));
+            }
+
+            // 执行接口逻辑
+            Object result = InterfaceExecutor.executeInterface(interfaceEntity, objectParams);
+            return ApiResult.success(result);
+        } catch (Exception e) {
+            return ApiResult.error("接口访问失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ApiResult<?> getInterfacePageData(String id, Map<String, Object> pageParams) {
+        // 这里是获取接口分页数据的实现,实际逻辑需要根据接口类型和配置进行处理
+        DataInterface interfaceEntity = baseMapper.selectById(id);
+        if (interfaceEntity == null) {
+            return ApiResult.error("接口不存在");
+        }
+
+        try {
+            // 获取接口分页数据
+            Map<String, Object> result = InterfaceExecutor.getInterfacePageData(interfaceEntity, pageParams);
+            return ApiResult.success(result);
+        } catch (Exception e) {
+            return ApiResult.error("获取接口分页数据失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ApiResult<List<Map<String, Object>>> getInterfaceDetailData(String id, Map<String, Object> pageParams) {
+        // 这里是获取接口详情数据的实现,实际逻辑需要根据接口类型和配置进行处理
+        DataInterface interfaceEntity = baseMapper.selectById(id);
+        if (interfaceEntity == null) {
+            return ApiResult.error("接口不存在");
+        }
+
+        try {
+            // 执行接口逻辑获取数据
+            Object result = InterfaceExecutor.executeInterface(interfaceEntity, pageParams);
+
+            // 转换结果为List<Map<String, Object>>类型
+            List<Map<String, Object>> resultList = new ArrayList<>();
+            if (result instanceof List) {
+                List<?> listResult = (List<?>) result;
+                for (Object item : listResult) {
+                    if (item instanceof Map) {
+                        @SuppressWarnings("unchecked")
+                        Map<String, Object> mapItem = (Map<String, Object>) item;
+                        resultList.add(mapItem);
+                    }
+                }
+            }
+
+            return ApiResult.success(resultList);
+        } catch (Exception e) {
+            return ApiResult.error("获取接口详情数据失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    public ApiResult<List<String>> getInterfaceFields(String id, Map<String, Object> pageParams) {
+        // 这里是获取接口字段的实现,实际逻辑需要根据接口类型和配置进行处理
+        DataInterface interfaceEntity = baseMapper.selectById(id);
+        if (interfaceEntity == null) {
+            return ApiResult.error("接口不存在");
+        }
+
+        try {
+            // 获取接口字段
+            List<String> fields = InterfaceExecutor.getInterfaceFields(interfaceEntity, pageParams);
+            return ApiResult.success(fields);
+        } catch (Exception e) {
+            return ApiResult.error("获取接口字段失败: " + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional
+    public Boolean deleteInterface(Long id) {
+        LambdaQueryWrapper<DataInterface> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DataInterface::getId, id);
+        DataInterface entity = baseMapper.selectOne(queryWrapper);
+        String username = SecurityUtils.getUsername();
+
+        if (entity == null) {
+            log.warn("尝试删除不存在的接口,ID: {},操作人{}", id, username);
+            throw new BusinessException("接口不存在!");
+        }
+
+        entity.setIsDelete(1);
+        entity.setDeleteTime(LocalDateTime.now());
+        entity.setDeleteBy(username);
+
+        return baseMapper.update(entity, queryWrapper) > 0;
+    }
+
+
+    @Override
+    @Transactional
+    public Boolean addInterface(DataInterface dataInterface) {
+        Integer tenantId = SecurityUtils.getTenantId();
+        if (!selectNameAndCode(dataInterface.getFullName(), dataInterface.getEnCode(), tenantId).isEmpty()) {
+            throw new BusinessException("接口名称或编码已存在");
+        }
+
+        dataInterface.setCreateBy(SecurityUtils.getUsername());
+        dataInterface.setCreateTime(LocalDateTime.now());
+        dataInterface.setIsDelete(0);
+        dataInterface.setEnabledMark(1);
+        dataInterface.setTenantId(tenantId);
+        return baseMapper.insert(dataInterface) > 0;
+    }
+
+    private List<DataInterface> selectNameAndCode(String name, String code, Integer tenantId) {
+        LambdaQueryWrapper<DataInterface> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(DataInterface::getTenantId, tenantId)
+                .and(w -> w.eq(DataInterface::getFullName, name)
+                        .or()
+                        .eq(DataInterface::getEnCode, code));
+        return baseMapper.selectList(queryWrapper);
+    }
+
+
+    @Override
+    public Boolean updateInterface(DataInterface dataInterface) {
+
+        if (dataInterface == null || dataInterface.getId() <= 0) {
+            throw new BusinessException("接口id为空或不合规");
+        }
+
+        if (!selectNameAndCode(dataInterface.getFullName(), dataInterface.getEnCode(), dataInterface.getTenantId()).isEmpty()) {
+            throw new BusinessException("接口名称或编码已存在");
+        }
+
+        dataInterface.setUpdateBy(SecurityUtils.getUsername());
+        dataInterface.setUpdateTime(LocalDateTime.now());
+        return baseMapper.updateById(dataInterface) > 0;
+    }
+}

+ 120 - 0
service-data/service-data-biz/src/main/java/com/usky/data/service/impl/DataLinkServiceImpl.java

@@ -0,0 +1,120 @@
+package com.usky.data.service.impl;
+
+import com.usky.data.domain.DataLink;
+import com.usky.data.mapper.DataLinkMapper;
+import com.usky.data.service.DataLinkService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.List;
+
+/**
+ * <p>
+ * 数据中心_数据连接表 服务实现类
+ * </p>
+ *
+ * @author fyc
+ * @since 2026-01-23
+ */
+@Service
+public class DataLinkServiceImpl extends AbstractCrudService<DataLinkMapper, DataLink> implements DataLinkService {
+
+    @Autowired
+    private DataLinkMapper dataLinkMapper;
+
+    @Override
+    public boolean testDbConnection(DataLink dataLink) {
+        Connection connection = null;
+        try {
+            // 根据数据库类型加载驱动
+            String driverClass = getDriverClass(dataLink.getDbType());
+            Class.forName(driverClass);
+
+            // 构建连接URL
+            String url = buildJdbcUrl(dataLink);
+
+            // 建立连接
+            connection = DriverManager.getConnection(url, dataLink.getDbName(), dataLink.getPassword());
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        } finally {
+            if (connection != null) {
+                try {
+                    connection.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean isExistByFullName(String fullName, Integer id) {
+        int count = dataLinkMapper.countByFullName(fullName, id);
+        return count > 0;
+    }
+
+    @Override
+    public List<DataLink> getList() {
+        return dataLinkMapper.selectList(null);
+    }
+
+    @Override
+    public List<DataLink> getList(int page, int pageSize, String keyword) {
+        // 计算起始索引
+        int startIndex = (page - 1) * pageSize;
+        return dataLinkMapper.selectPageList(startIndex, pageSize, keyword);
+    }
+
+    /**
+     * 根据数据库类型获取驱动类名
+     */
+    private String getDriverClass(String dbType) {
+        switch (dbType.toLowerCase()) {
+            case "mysql":
+                return "com.mysql.cj.jdbc.Driver";
+            case "oracle":
+                return "oracle.jdbc.OracleDriver";
+            case "sqlserver":
+                return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
+            case "postgresql":
+                return "org.postgresql.Driver";
+            default:
+                throw new IllegalArgumentException("不支持的数据库类型: " + dbType);
+        }
+    }
+
+    /**
+     * 构建JDBC连接URL
+     */
+    private String buildJdbcUrl(DataLink dataLink) {
+        String dbType = dataLink.getDbType().toLowerCase();
+        String host = dataLink.getHost();
+        Integer port = dataLink.getPort();
+        String dbName = dataLink.getDbName();
+
+        switch (dbType) {
+            case "mysql":
+                return String.format("jdbc:mysql://%s:%d/%s?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%%2B8",
+                        host, port, dbName);
+            case "oracle":
+                // Oracle支持SID和Service Name两种方式
+                if (dataLink.getServiceName() != null && !dataLink.getServiceName().isEmpty()) {
+                    return String.format("jdbc:oracle:thin:@//%s:%d/%s", host, port, dataLink.getServiceName());
+                } else {
+                    return String.format("jdbc:oracle:thin:@%s:%d:%s", host, port, dbName);
+                }
+            case "sqlserver":
+                return String.format("jdbc:sqlserver://%s:%d;databaseName=%s;encrypt=false", host, port, dbName);
+            case "postgresql":
+                return String.format("jdbc:postgresql://%s:%d/%s", host, port, dbName);
+            default:
+                throw new IllegalArgumentException("不支持的数据库类型: " + dbType);
+        }
+    }
+}

+ 421 - 0
service-data/service-data-biz/src/main/java/com/usky/data/service/util/InterfaceExecutor.java

@@ -0,0 +1,421 @@
+package com.usky.data.service.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.usky.data.domain.DataInterface;
+import org.apache.commons.lang3.StringUtils;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 接口执行器,用于处理不同类型接口的执行逻辑
+ * <p>
+ * 支持三种接口类型:
+ * 1. SQL操作(type=1)
+ * 2. 静态数据(type=2)
+ * 3. API操作(type=3)
+ * </p>
+ */
+public class InterfaceExecutor {
+
+    /**
+     * 执行接口逻辑,参考原始infoToId方法
+     *
+     * @param dataInterface 接口实体
+     * @param params        请求参数
+     * @return 执行结果
+     */
+    public static Object executeInterface(DataInterface dataInterface, Map<String, Object> params) {
+        if (dataInterface == null) {
+            throw new IllegalArgumentException("接口配置不能为空");
+        }
+
+        // 转换params为Map<String, String>用于参数处理
+        Map<String, String> stringParams = new HashMap<>();
+        if (params != null) {
+            params.forEach((k, v) -> stringParams.put(k, v != null ? v.toString() : null));
+        }
+
+        // 替换默认值
+        replaceDefaultValue(dataInterface.getParameterJson(), stringParams);
+
+        // 验证参数必填或类型
+        String checkResult = checkRequestParams(dataInterface.getParameterJson(), stringParams);
+        if (StringUtils.isNotEmpty(checkResult)) {
+            throw new IllegalArgumentException(checkResult);
+        }
+
+        Object result = null;
+        try {
+            // 根据接口类型执行不同逻辑
+            Integer type = dataInterface.getType();
+            switch (type) {
+                case 1:
+                    // 静态数据
+                    result = callStaticData(dataInterface.getDataConfigJson());
+                    break;
+                case 3:
+                    // API调用
+                    result = callApi(dataInterface.getDataConfigJson(), stringParams);
+                    break;
+                case 2:
+                    // SQL操作
+                    result = executeSql(dataInterface, stringParams);
+                    break;
+                default:
+                    throw new IllegalArgumentException("不支持的接口类型: " + type);
+            }
+
+            // 处理结果,执行JS脚本
+            if (StringUtils.isNotEmpty(dataInterface.getDataJsJson())) {
+                // 这里模拟JS脚本执行,实际项目中需要引入JS引擎
+                result = processResult(result, dataInterface.getDataJsJson());
+            }
+
+            return result;
+        } catch (Exception e) {
+            throw new RuntimeException("接口执行失败: " + e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 替换默认值
+     *
+     * @param parameterJson 参数配置JSON
+     * @param params        请求参数
+     */
+    private static void replaceDefaultValue(String parameterJson, Map<String, String> params) {
+        if (StringUtils.isEmpty(parameterJson)) {
+            return;
+        }
+
+        JSONArray paramArray = JSON.parseArray(parameterJson);
+        if (paramArray == null || paramArray.isEmpty()) {
+            return;
+        }
+
+        for (Object obj : paramArray) {
+            JSONObject paramObj = (JSONObject) obj;
+            String field = paramObj.getString("field");
+            String defaultValue = paramObj.getString("defaultValue");
+
+            // 如果参数中没有该字段或值为空,则设置默认值
+            if (!params.containsKey(field) || StringUtils.isEmpty(params.get(field))) {
+                params.put(field, defaultValue == null ? "" : defaultValue);
+            }
+        }
+    }
+
+    /**
+     * 检查请求参数
+     *
+     * @param parameterJson 参数配置JSON
+     * @param params        请求参数
+     * @return 检查结果,空字符串表示通过
+     */
+    private static String checkRequestParams(String parameterJson, Map<String, String> params) {
+        if (StringUtils.isEmpty(parameterJson)) {
+            return "";
+        }
+
+        JSONArray paramArray = JSON.parseArray(parameterJson);
+        if (paramArray == null || paramArray.isEmpty()) {
+            return "";
+        }
+
+        StringBuilder message = new StringBuilder();
+        for (Object obj : paramArray) {
+            JSONObject paramObj = (JSONObject) obj;
+
+            // 验证必填字段
+            Integer required = paramObj.getInteger("required");
+            if (required != null && required == 1) {
+                String field = paramObj.getString("field");
+                String value = params.get(field);
+                if (StringUtils.isEmpty(value)) {
+                    message.append(field).append("不能为空;");
+                }
+            }
+
+            // 验证数据类型
+            String dataType = paramObj.getString("dataType");
+            if (StringUtils.isNotEmpty(dataType)) {
+                String field = paramObj.getString("field");
+                String value = params.get(field);
+                if (StringUtils.isEmpty(value)) {
+                    continue;
+                }
+                try {
+                    if ("int".equals(dataType)) {
+                        Integer.parseInt(value);
+                    } else if ("decimal".equals(dataType)) {
+                        Double.parseDouble(value);
+                    } else if ("datetime".equals(dataType)) {
+                        try {
+                            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                            formatter.parse(value);
+                        } catch (Exception e) {
+                            // 尝试解析时间戳
+                            Long.parseLong(value);
+                        }
+                    }
+                } catch (Exception e) {
+                    message.append(field).append("类型必须为").append(dataType).append(";");
+                }
+            }
+        }
+
+        return message.length() > 0 ? message.substring(0, message.length() - 1) : "";
+    }
+
+    /**
+     * 执行静态数据类型接口
+     *
+     * @param dataConfigJson 数据配置JSON
+     * @return 静态数据结果
+     */
+    private static Object callStaticData(String dataConfigJson) {
+        JSONObject configJson = JSON.parseObject(dataConfigJson);
+        String staticData = configJson.getString("staticData");
+
+        Object obj;
+        try {
+            Object parse = JSON.parse(staticData);
+            if (parse instanceof JSONArray) {
+                obj = JSON.parseArray(staticData, Map.class);
+            } else {
+                obj = JSON.parseObject(staticData, Map.class);
+            }
+        } catch (Exception e) {
+            obj = staticData;
+        }
+
+        if (obj == null) {
+            return new ArrayList<>();
+        }
+
+        return obj;
+    }
+
+    /**
+     * 执行API类型接口
+     *
+     * @param dataConfigJson 数据配置JSON
+     * @param params        请求参数
+     * @return API调用结果
+     */
+    private static Object callApi(String dataConfigJson, Map<String, String> params) {
+        JSONObject configJson = JSON.parseObject(dataConfigJson);
+        JSONObject apiData = configJson.getJSONObject("apiData");
+
+        if (apiData == null) {
+            throw new IllegalArgumentException("API配置不能为空");
+        }
+
+        String url = apiData.getString("url");
+        String method = apiData.getString("method");
+        JSONObject headers = apiData.getJSONObject("headers");
+        JSONObject apiParams = apiData.getJSONObject("params");
+
+        // 合并参数
+        if (apiParams == null) {
+            apiParams = new JSONObject();
+        }
+        if (params != null) {
+            JSONObject finalApiParams = apiParams;
+            params.forEach((k, v) -> {
+                if (StringUtils.isNotEmpty(v)) {
+                    finalApiParams.put(k, v);
+                }
+            });
+        }
+
+        // 模拟API调用,实际项目中需要使用HTTP客户端
+        Map<String, Object> result = new HashMap<>();
+        result.put("success", true);
+        result.put("message", "API调用成功");
+        result.put("data", apiParams);
+        result.put("url", url);
+        result.put("method", method);
+
+        return result;
+    }
+
+    /**
+     * 执行SQL类型接口
+     *
+     * @param dataInterface 接口实体
+     * @param params        请求参数
+     * @return SQL执行结果
+     */
+    private static Object executeSql(DataInterface dataInterface, Map<String, String> params) {
+        JSONObject configJson = JSON.parseObject(dataInterface.getDataConfigJson());
+        JSONObject sqlData = configJson.getJSONObject("sqlData");
+
+        if (sqlData == null) {
+            throw new IllegalArgumentException("SQL配置不能为空");
+        }
+
+        String sql = sqlData.getString("sql");
+        if (StringUtils.isEmpty(sql)) {
+            throw new IllegalArgumentException("SQL语句不能为空");
+        }
+
+        // 替换SQL中的参数占位符
+        sql = replaceSqlParams(sql, params);
+
+        // 模拟SQL执行结果
+        List<Map<String, Object>> resultList = new ArrayList<>();
+        for (int i = 0; i < 5; i++) {
+            Map<String, Object> map = new HashMap<>();
+            map.put("id", i + 1);
+            map.put("name", "测试数据" + (i + 1));
+            map.put("value", i * 100);
+            map.put("created_at", "2026-01-24 10:00:00");
+            resultList.add(map);
+        }
+
+        // 如果是分页查询,处理分页信息
+        if (dataInterface.getHasPage() != null && dataInterface.getHasPage() == 1) {
+            Map<String, Object> pageResult = new HashMap<>();
+            pageResult.put("list", resultList);
+            pageResult.put("total", 100);
+            pageResult.put("current", params.getOrDefault("currentPage", "1"));
+            pageResult.put("pageSize", params.getOrDefault("pageSize", "20"));
+            return pageResult;
+        }
+
+        return resultList;
+    }
+
+    /**
+     * 替换SQL中的参数占位符
+     *
+     * @param sql    SQL语句
+     * @param params 请求参数
+     * @return 替换后的SQL语句
+     */
+    private static String replaceSqlParams(String sql, Map<String, String> params) {
+        if (StringUtils.isEmpty(sql) || params == null || params.isEmpty()) {
+            return sql;
+        }
+
+        // 匹配 {参数名} 格式的占位符
+        Pattern pattern = Pattern.compile("\\{(\\w+)\\}");
+        Matcher matcher = pattern.matcher(sql);
+
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            String paramName = matcher.group(1);
+            String paramValue = params.getOrDefault(paramName, "");
+            matcher.appendReplacement(sb, paramValue);
+        }
+        matcher.appendTail(sb);
+
+        return sb.toString();
+    }
+
+    /**
+     * 处理结果,执行JS脚本
+     *
+     * @param result    原始结果
+     * @param jsScript  JS脚本
+     * @return 处理后的结果
+     */
+    private static Object processResult(Object result, String jsScript) {
+        // 这里模拟JS脚本执行,实际项目中需要引入JS引擎
+        // 例如使用javax.script.ScriptEngine
+        return result;
+    }
+
+    /**
+     * 判断是否为内部接口返回格式
+     *
+     * @param jsonObject JSON对象
+     * @return 是否为内部接口格式
+     */
+    private static boolean isInternal(JSONObject jsonObject) {
+        if (jsonObject != null) {
+            return jsonObject.size() == 3 &&
+                    jsonObject.containsKey("code") &&
+                    jsonObject.containsKey("msg") &&
+                    jsonObject.containsKey("data");
+        }
+        return false;
+    }
+
+    /**
+     * 获取接口字段信息
+     *
+     * @param dataInterface 接口实体
+     * @param params        请求参数
+     * @return 接口字段列表
+     */
+    public static List<String> getInterfaceFields(DataInterface dataInterface, Map<String, Object> params) {
+        // 执行接口获取数据
+        Object result = executeInterface(dataInterface, params);
+
+        // 解析结果获取字段列表
+        List<String> fields = new ArrayList<>();
+        if (result instanceof List) {
+            List<?> resultList = (List<?>) result;
+            if (!resultList.isEmpty() && resultList.get(0) instanceof Map) {
+                Map<?, ?> firstItem = (Map<?, ?>) resultList.get(0);
+                for (Object key : firstItem.keySet()) {
+                    fields.add(key.toString());
+                }
+            }
+        } else if (result instanceof Map) {
+            Map<?, ?> resultMap = (Map<?, ?>) result;
+            // 如果是分页结果,获取list中的字段
+            if (resultMap.containsKey("list") && resultMap.get("list") instanceof List) {
+                List<?> list = (List<?>) resultMap.get("list");
+                if (!list.isEmpty() && list.get(0) instanceof Map) {
+                    Map<?, ?> firstItem = (Map<?, ?>) list.get(0);
+                    for (Object key : firstItem.keySet()) {
+                        fields.add(key.toString());
+                    }
+                }
+            } else {
+                // 直接获取map中的字段
+                for (Object key : resultMap.keySet()) {
+                    fields.add(key.toString());
+                }
+            }
+        }
+
+        return fields;
+    }
+
+    /**
+     * 获取接口分页数据
+     *
+     * @param dataInterface 接口实体
+     * @param params        请求参数
+     * @return 分页数据结果
+     */
+    public static Map<String, Object> getInterfacePageData(DataInterface dataInterface, Map<String, Object> params) {
+        // 执行接口获取数据
+        Object result = executeInterface(dataInterface, params);
+
+        // 处理分页
+        Map<String, Object> pageResult = new HashMap<>();
+
+        if (result instanceof Map && ((Map<?, ?>) result).containsKey("list")) {
+            // 如果已经是分页格式,直接返回
+            pageResult.putAll((Map<? extends String, ?>) result);
+        } else {
+            // 否则包装成分页格式
+            pageResult.put("list", result);
+            pageResult.put("total", result instanceof List ? ((List<?>) result).size() : 1);
+            pageResult.put("current", params != null ? params.getOrDefault("currentPage", 1) : 1);
+            pageResult.put("pageSize", params != null ? params.getOrDefault("pageSize", 20) : 20);
+        }
+
+        return pageResult;
+    }
+}

+ 49 - 0
service-data/service-data-biz/src/main/java/com/usky/data/vo/DbLinkInfoVO.java

@@ -0,0 +1,49 @@
+package com.usky.data.vo;
+
+import com.usky.data.domain.DataLink;
+import lombok.Data;
+
+/**
+ * 数据源详细信息VO
+ */
+@Data
+public class DbLinkInfoVO {
+    private Integer id;
+    private String fullName;
+    private String dbType;
+    private String host;
+    private Integer port;
+    private String dbName;
+    private String serviceName;
+    private String description;
+    private String dbSchema;
+    private String tableSpace;
+    private String oracleParam;
+    private Integer oracleExtend;
+    private Integer sortCode;
+    private String createBy;
+    private String updateBy;
+
+    /**
+     * 转换为VO对象
+     */
+    public DbLinkInfoVO getDbLinkInfoVO(DataLink dataLink) {
+        DbLinkInfoVO vo = new DbLinkInfoVO();
+        vo.setId(dataLink.getId());
+        vo.setFullName(dataLink.getFullName());
+        vo.setDbType(dataLink.getDbType());
+        vo.setHost(dataLink.getHost());
+        vo.setPort(dataLink.getPort());
+        vo.setDbName(dataLink.getDbName());
+        vo.setServiceName(dataLink.getServiceName());
+        vo.setDescription(dataLink.getDescription());
+        vo.setDbSchema(dataLink.getDbSchema());
+        vo.setTableSpace(dataLink.getTableSpace());
+        vo.setOracleParam(dataLink.getOracleParam());
+        vo.setOracleExtend(dataLink.getOracleExtend());
+        vo.setSortCode(dataLink.getSortCode());
+        vo.setCreateBy(dataLink.getCreateBy());
+        vo.setUpdateBy(dataLink.getUpdateBy());
+        return vo;
+    }
+}

+ 22 - 0
service-data/service-data-biz/src/main/java/com/usky/data/vo/DbLinkListVO.java

@@ -0,0 +1,22 @@
+package com.usky.data.vo;
+
+import lombok.Data;
+
+/**
+ * 数据源列表VO
+ */
+@Data
+public class DbLinkListVO {
+    private Integer id;
+    private String fullName;
+    private String dbType;
+    private String host;
+    private Integer port;
+    private String dbName;
+    private String serviceName;
+    private String description;
+    private String dbSchema;
+    private String tableSpace;
+    private String createBy;
+    private String updateBy;
+}

+ 14 - 0
service-data/service-data-biz/src/main/java/com/usky/data/vo/DbLinkSelectorListVO.java

@@ -0,0 +1,14 @@
+package com.usky.data.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 数据源选择器列表VO
+ */
+@Data
+public class DbLinkSelectorListVO {
+    private String fullName;
+    private List<DbLinkListVO> children;
+}

+ 17 - 0
service-data/service-data-biz/src/main/java/com/usky/data/vo/ListVO.java

@@ -0,0 +1,17 @@
+package com.usky.data.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 通用列表包装类
+ */
+@Data
+public class ListVO<T> {
+    private List<T> list;
+
+    public ListVO(List<T> list) {
+        this.list = list;
+    }
+}

+ 19 - 0
service-data/service-data-biz/src/main/java/com/usky/data/vo/PageListVO.java

@@ -0,0 +1,19 @@
+package com.usky.data.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 分页列表包装类
+ */
+@Data
+public class PageListVO<T> {
+    private List<T> list;
+    private PaginationVO pagination;
+
+    public PageListVO(List<T> list, PaginationVO pagination) {
+        this.list = list;
+        this.pagination = pagination;
+    }
+}

+ 14 - 0
service-data/service-data-biz/src/main/java/com/usky/data/vo/PaginationVO.java

@@ -0,0 +1,14 @@
+package com.usky.data.vo;
+
+import lombok.Data;
+
+/**
+ * 分页信息包装类
+ */
+@Data
+public class PaginationVO {
+    private int currentPage;
+    private int pageSize;
+    private int totalRows;
+    private int totalPages;
+}

+ 25 - 0
service-data/service-data-biz/src/main/resources/bootstrap.yml

@@ -0,0 +1,25 @@
+# Tomcat
+server:
+  port: 9902
+
+# Spring
+spring: 
+  application:
+    # 应用名称
+    name: service-data
+  profiles:
+    # 环境配置
+    active: dev
+  cloud:
+    nacos:
+      discovery:
+        # 服务注册地址
+        server-addr: usky-cloud-nacos:8848
+      config:
+        # 配置中心地址
+        server-addr: usky-cloud-nacos:8848
+        # 配置文件格式
+        file-extension: yml
+        # 共享配置
+        shared-configs:
+          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

+ 108 - 0
service-data/service-data-biz/src/main/resources/doc/index.adoc

@@ -0,0 +1,108 @@
+= 安防项目
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Version |  Update Time  | Status | Author |  Description
+|v2022-04-21 16:57:08|2022-04-21 16:57:08|auto|@yq|Created by smart-doc
+|====================
+
+
+== &lt;p&gt;参数配置表 前端控制器&lt;/p&gt;
+== &lt;p&gt;部门信息&lt;/p&gt;
+=== 查看部门信息
+*URL:* http:10.23.39.1:8082/sysDept/list
+
+*Type:* POST
+
+*Author:* ya
+
+*Content-Type:* application/json; charset=utf-8
+
+
+
+
+*Body-parameters:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Parameter | Type|Description|Required|Since
+|deptId|int64|部门id|false|-
+|parentId|int64|父部门id|false|-
+|ancestors|string|祖级列表|false|-
+|deptName|string|部门名称|false|-
+|orderNum|int32|显示顺序|false|-
+|leader|string|负责人|false|-
+|phone|string|联系电话|false|-
+|email|string|邮箱|false|-
+|status|string|部门状态(0正常 1停用)|false|-
+|delFlag|string|删除标志(0代表存在 2代表删除)|false|-
+|createBy|string|创建者|false|-
+|createTime|string|创建时间|false|-
+|updateBy|string|更新者|false|-
+|updateTime|string|更新时间|false|-
+|bId|int64|建筑id|false|-
+|====================
+
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|status|object|No comments found.|-
+|code|string|No comments found.|-
+|msg|string|No comments found.|-
+|data|object|No comments found.|-
+|└─deptId|int64|部门id|-
+|└─parentId|int64|父部门id|-
+|└─ancestors|string|祖级列表|-
+|└─deptName|string|部门名称|-
+|└─orderNum|int32|显示顺序|-
+|└─leader|string|负责人|-
+|└─phone|string|联系电话|-
+|└─email|string|邮箱|-
+|└─status|string|部门状态(0正常 1停用)|-
+|└─delFlag|string|删除标志(0代表存在 2代表删除)|-
+|└─createBy|string|创建者|-
+|└─createTime|string|创建时间|-
+|└─updateBy|string|更新者|-
+|└─updateTime|string|更新时间|-
+|└─bId|int64|建筑id|-
+|exception|string|No comments found.|-
+|====================
+
+*Response-example:*
+----
+{
+	"status": {
+		
+	},
+	"code": "97564",
+	"msg": "wnr5qt",
+	"data": [
+		{
+			"deptId": 540,
+			"parentId": 858,
+			"ancestors": "o5lg60",
+			"deptName": "文.沈",
+			"orderNum": 260,
+			"leader": "ufz93p",
+			"phone": "17852835049",
+			"email": "智渊.徐@yahoo.com",
+			"status": "nu6cnp",
+			"delFlag": "72oiji",
+			"createBy": "5fxr6j",
+			"createTime": "2022-04-21 16:57:10",
+			"updateBy": "4kcs4e",
+			"updateTime": "2022-04-21 16:57:10",
+			"bId": 977
+		}
+	],
+	"exception": "53u6bg"
+}
+----
+
+== &lt;p&gt;用户信息表 前端控制器&lt;/p&gt;
+

+ 74 - 0
service-data/service-data-biz/src/main/resources/logback.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="/var/log/uskycloud/usky-data" />
+   <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+    <!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+
+    <!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 系统模块日志级别控制  -->
+	<logger name="com.usky" level="info" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="warn" />
+
+	<root level="info">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+</configuration>

+ 28 - 0
service-data/service-data-biz/src/main/resources/mapper/data/DataInterfaceLogMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.data.mapper.DataInterfaceLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.data.domain.DataInterfaceLog">
+        <id column="id" property="id" />
+        <result column="interface_id" property="interfaceId" />
+        <result column="execute_time" property="executeTime" />
+        <result column="user_id" property="userId" />
+        <result column="request_ip" property="requestIp" />
+        <result column="request_device" property="requestDevice" />
+        <result column="request_type" property="requestType" />
+        <result column="request_waste_time" property="requestWasteTime" />
+        <result column="oauth_app_id" property="oauthAppId" />
+        <result column="sort_code" property="sortCode" />
+        <result column="execute_result" property="executeResult" />
+        <result column="execute_state" property="executeState" />
+        <result column="execute_msg" property="executeMsg" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="dept_id" property="deptId" />
+        <result column="tenant_id" property="tenantId" />
+    </resultMap>
+
+</mapper>

+ 35 - 0
service-data/service-data-biz/src/main/resources/mapper/data/DataInterfaceMapper.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.data.mapper.DataInterfaceMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.data.domain.DataInterface">
+        <id column="id" property="id"/>
+        <result column="full_name" property="fullName"/>
+        <result column="en_code" property="enCode"/>
+        <result column="category" property="category"/>
+        <result column="type" property="type"/>
+        <result column="action" property="action"/>
+        <result column="has_page" property="hasPage"/>
+        <result column="is_postposition" property="isPostposition"/>
+        <result column="config_json" property="dataConfigJson"/>
+        <result column="count_json" property="dataCountJson"/>
+        <result column="echo_json" property="dataEchoJson"/>
+        <result column="js_json" property="dataJsJson"/>
+        <result column="field_json" property="fieldJson"/>
+        <result column="parameter_json" property="parameterJson"/>
+        <result column="exception_json" property="exceptionJson"/>
+        <result column="description" property="description"/>
+        <result column="enabled_mark" property="enabledMark"/>
+        <result column="sort_code" property="sortCode"/>
+        <result column="create_by" property="createBy"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_by" property="updateBy"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="delete_time" property="deleteTime"/>
+        <result column="delete_by" property="deleteBy"/>
+        <result column="is_delete" property="isDelete"/>
+        <result column="tenant_id" property="tenantId"/>
+    </resultMap>
+
+</mapper>

+ 56 - 0
service-data/service-data-biz/src/main/resources/mapper/data/DataLinkMapper.xml

@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.data.mapper.DataLinkMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.data.domain.DataLink">
+        <id column="id" property="id" />
+        <result column="full_name" property="fullName" />
+        <result column="db_type" property="dbType" />
+        <result column="host" property="host" />
+        <result column="port" property="port" />
+        <result column="db_name" property="dbName" />
+        <result column="password" property="password" />
+        <result column="service_name" property="serviceName" />
+        <result column="description" property="description" />
+        <result column="db_schema" property="dbSchema" />
+        <result column="table_space" property="tableSpace" />
+        <result column="oracle_param" property="oracleParam" />
+        <result column="oracle_extend" property="oracleExtend" />
+        <result column="sort_code" property="sortCode" />
+        <result column="create_time" property="createTime" />
+        <result column="create_by" property="createBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="delete_time" property="deleteTime" />
+        <result column="delete_by" property="deleteBy" />
+        <result column="is_delete" property="isDelete" />
+        <result column="tenant_id" property="tenantId" />
+    </resultMap>
+
+    <!-- 根据连接名称统计数量(排除指定ID) -->
+    <select id="countByFullName" resultType="int">
+        SELECT COUNT(*)
+        FROM data_link
+        WHERE full_name = #{fullName}
+        AND is_delete = 0
+        <if test="id != null">
+            AND id != #{id}
+        </if>
+    </select>
+
+    <!-- 分页查询数据源列表 -->
+    <select id="selectPageList" resultMap="BaseResultMap">
+        SELECT *
+        FROM data_link
+        WHERE is_delete = 0
+        <if test="keyword != null and keyword != ''">
+            AND (full_name LIKE CONCAT('%', #{keyword}, '%')
+            OR host LIKE CONCAT('%', #{keyword}, '%')
+            OR db_name LIKE CONCAT('%', #{keyword}, '%'))
+        </if>
+        ORDER BY create_time DESC
+        LIMIT #{startIndex}, #{pageSize}
+    </select>
+
+</mapper>

+ 15 - 0
service-data/service-data-biz/src/main/resources/smart-doc.json

@@ -0,0 +1,15 @@
+{
+  "outPath":"./src/main/resources/doc",
+  "serverUrl": "http:10.23.39.1:9902/",
+  "isStrict": false,
+  "coverOld": true,
+  "allInOne": true,
+  "packageFilters": "com.usky.data.controller.web",
+  "requestExample":"false",
+  "responseExample":"true",
+  "projectName": "数据中心",
+  "appKey": "20211216921084883495813120",
+  "appToken":"36bde2426ad546a5a50311bb747e7e61",
+  "secret": "N@Pd,KXAHki*BW3=zK.XPNykf!=CM79J",
+  "openUrl": "http://101.133.214.75:7700/api"
+}