commit 0a66cde34762bf0eb2d71e9747638c2dbfe5524f Author: ouhaolan Date: Fri Feb 27 09:41:10 2026 +0800 info diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c100e7c --- /dev/null +++ b/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + com.ydoyun + mssql-jdbc + 1.0.0 + jar + + + org.springframework.boot + spring-boot-starter-parent + 2.6.4 + + + + + 1.8 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + + + + + + + + + + com.alibaba + druid + 1.2.15 + + + + + com.microsoft.sqlserver + mssql-jdbc + 6.4.0.jre8 + + + org.projectlombok + lombok + provided + + + + org.springframework.boot + spring-boot-starter-validation + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/src/main/java/com/ydoyun/mssqljdbc/MssqlJdbcApplication.java b/src/main/java/com/ydoyun/mssqljdbc/MssqlJdbcApplication.java new file mode 100644 index 0000000..101436f --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/MssqlJdbcApplication.java @@ -0,0 +1,22 @@ +package com.ydoyun.mssqljdbc; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * 应用启动入口类。 + *

+ * 负责启动 Spring Boot 应用。 + */ +@SpringBootApplication +public class MssqlJdbcApplication { + + /** + * 启动 Spring Boot 应用。 + * + * @param args 启动参数 + */ + public static void main(String[] args) { + SpringApplication.run(MssqlJdbcApplication.class, args); + } +} \ No newline at end of file diff --git a/src/main/java/com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.java b/src/main/java/com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.java new file mode 100644 index 0000000..32ec738 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.java @@ -0,0 +1,72 @@ +package com.ydoyun.mssqljdbc.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ydoyun.mssqljdbc.controller.vo.ApiResponseVO; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 基于 API Key 的简单请求头鉴权过滤器。 + *

+ * 统一拦截以 /api/ 开头的接口,校验请求头中的 X-API-KEY 是否与配置一致, + * 如果不一致则直接返回未授权的 JSON 响应。 + */ +@Component +public class ApiKeyAuthFilter extends OncePerRequestFilter { + + private static final String HEADER_NAME = "X-API-KEY"; + + @Value("${security.api-key}") + private String apiKey; + + @Autowired + private ObjectMapper objectMapper; + + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + + String requestUri = request.getRequestURI(); + + // 放行非业务接口(例如静态资源、健康检查等),这里只限制 /api/ 开头的请求 + if (!requestUri.startsWith("/api/")) { + filterChain.doFilter(request, response); + return; + } + + // 预检请求直接放行,避免影响跨域 + if (HttpMethod.OPTIONS.matches(request.getMethod())) { + filterChain.doFilter(request, response); + return; + } + + String requestKey = request.getHeader(HEADER_NAME); + if (requestKey == null || !requestKey.equals(apiKey)) { + // 统一返回未授权的 JSON 结构 + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + response.setCharacterEncoding("UTF-8"); + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + + ApiResponseVO body = ApiResponseVO.unauthorized("API Key 不正确"); + response.getWriter().write(objectMapper.writeValueAsString(body)); + return; + } + + filterChain.doFilter(request, response); + } +} + + + diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/ProcedureController.java b/src/main/java/com/ydoyun/mssqljdbc/controller/ProcedureController.java new file mode 100644 index 0000000..70b4985 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/ProcedureController.java @@ -0,0 +1,112 @@ +package com.ydoyun.mssqljdbc.controller; + +import com.ydoyun.mssqljdbc.controller.vo.ApiResponseVO; +import com.ydoyun.mssqljdbc.controller.vo.ProcedureRequestVO; +import com.ydoyun.mssqljdbc.controller.vo.ReportSyncRequestVO; +import com.ydoyun.mssqljdbc.controller.vo.SqlRequestVO; +import com.ydoyun.mssqljdbc.service.ProcedureService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +/** + * 存储过程和报表相关接口控制器。 + *

+ * 对外提供: + *

+ *

+ * API Key 校验已经通过全局过滤器 {@code ApiKeyAuthFilter} 统一处理, + * 此处无需再在每个方法中手动校验请求头。 + */ +@RestController +@RequestMapping("/api/procedure") +@Slf4j +public class ProcedureController { + + @Autowired + private ProcedureService procedureService; + + /** + * 动态调用存储过程查询数据。 + * + * @param request 请求体,包含要连接的数据库信息、存储过程名称和参数 + * @return 统一封装的接口返回结果 + */ + @PostMapping("/execute") + public ApiResponseVO executeProcedure( + @RequestBody @Valid ProcedureRequestVO request + ) { + log.info("收到存储过程调用请求,dbHost={}, dbName={}, procedureName={}", + request.getReportDatabase().getHost(), + request.getReportDatabase().getDatabaseName(), + request.getProcedureName()); + try { + return ApiResponseVO.success(procedureService.callProcedure( + request.getReportDatabase(), + request.getProcedureName(), + request.getParams() + )); + } catch (Exception e) { + log.error("执行存储过程出错", e); + return ApiResponseVO.error("执行存储过程出错: " + e.getMessage()); + } + } + + /** + * 通用 SQL 执行接口。 + *

+ * 根据请求体中的 SQL 文本自动判断是查询还是更新, + * 并在指定的目标数据库上执行。 + * + * @param request 请求体,包含要连接的数据库信息和 SQL 语句 + * @return 查询时返回数据列表,更新时返回影响行数 + */ + @PostMapping("/exec-sql") + public ApiResponseVO executeSql( + @RequestBody @Valid SqlRequestVO request + ) { + log.info("收到 SQL 执行请求,dbHost={}, dbName={}", + request.getReportDatabase().getHost(), + request.getReportDatabase().getDatabaseName()); + try { + Object result = procedureService.executeSql(request.getReportDatabase(), request.getSql()); + return ApiResponseVO.success(result); + } catch (Exception e) { + log.error("执行 SQL 出错", e); + return ApiResponseVO.error("执行 SQL 出错: " + e.getMessage()); + } + } + + /** + * 报表数据同步接口。 + *

+ * 根据传入的报表 ID 以及多张报表相关表的数据, + * 在目标报表数据库中先删除旧数据,再批量插入新数据,保持数据一致。 + * + * @param request 请求体,包含报表 ID、目标报表数据库信息以及各表的数据列表 + * @return 同步结果描述 + */ + @PostMapping("/sync") + public ApiResponseVO syncReport( + @RequestBody @Valid ReportSyncRequestVO request + ) { + log.info("收到报表同步请求,dbHost={}, dbName={}, reportId={}", + request.getReportDatabase().getHost(), + request.getReportDatabase().getDatabaseName(), + request.getReportId()); + try { + Object result = procedureService.syncReportData(request); + return ApiResponseVO.success(result); + } catch (Exception e) { + log.error("报表同步失败", e); + return ApiResponseVO.error("报表同步失败: " + e.getMessage()); + } + } + +} diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.java new file mode 100644 index 0000000..49cc713 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.java @@ -0,0 +1,66 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 统一的接口返回对象。 + *

+ * 通过 code + msg + data 的形式对所有接口返回值进行封装: + *

+ */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ApiResponseVO { + + /** + * 状态码:0 = 成功, 1 = 失败, 401 = 未授权。 + */ + private int code; + + /** + * 提示信息。 + */ + private String msg; + + /** + * 业务数据,对类型不作限制。 + */ + private Object data; + + /** + * 构造一个成功响应。 + * + * @param data 业务数据 + * @return 封装后的响应对象 + */ + public static ApiResponseVO success(Object data) { + return new ApiResponseVO(0, "success", data); + } + + /** + * 构造一个通用错误响应。 + * + * @param msg 错误描述 + * @return 封装后的响应对象 + */ + public static ApiResponseVO error(String msg) { + return new ApiResponseVO(1, msg, null); + } + + /** + * 构造一个未授权错误响应。 + * + * @param msg 提示信息 + * @return 封装后的响应对象 + */ + public static ApiResponseVO unauthorized(String msg) { + return new ApiResponseVO(401, msg, null); + } +} diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.java new file mode 100644 index 0000000..03a9248 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.java @@ -0,0 +1,40 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 存储过程调用请求对象。 + *

+ * 包含要连接的数据库信息、存储过程名称以及参数列表。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ProcedureRequestVO { + + /** + * 需要连接的报表数据库信息。 + */ + @Valid + @NotNull(message = "报表数据库信息不能为空") + private ReportDatabaseRespVO reportDatabase; + + /** + * 要调用的存储过程名称。 + */ + @NotBlank(message = "存储过程名称不能为空") + private String procedureName; + + /** + * 存储过程参数,Map 的遍历顺序即为参数的传入顺序。 + */ + private LinkedHashMap params; +} diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.java new file mode 100644 index 0000000..0008ff1 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.java @@ -0,0 +1,54 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.time.LocalDateTime; + +/** + * 报表数据库连接信息对象。 + *

+ * 用于描述一个可连接的报表数据库实例,包括类型、地址、端口、账号密码等。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ReportDatabaseRespVO { + + /** 主键 ID */ + private Long id; + + /** 数据源名称 */ + private String dbName; + + /** 数据库类型(mysql、pgsql、oracle、sqlserver) */ + @NotBlank(message = "数据库类型不能为空") + private String dbType; + + /** 数据库地址 */ + @NotBlank(message = "数据库地址不能为空") + private String host; + + /** 数据库端口(可选,未传则按默认端口处理) */ + private Integer port; + + /** 数据库账号 */ + @NotBlank(message = "数据库账号不能为空") + private String username; + + /** 数据库密码(建议加密存储) */ + @NotBlank(message = "数据库密码不能为空") + private String password; + + /** 数据库名称 */ + @NotBlank(message = "数据库名称不能为空") + private String databaseName; + + /** 备注说明 */ + private String remark; + + /** 创建时间 */ + private LocalDateTime createTime; +} diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.java new file mode 100644 index 0000000..75c5ef7 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.java @@ -0,0 +1,20 @@ +package com.ydoyun.mssqljdbc.controller.vo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ReportSyncRequestVO { + private Long reportId; + + private ReportDatabaseRespVO reportDatabase; + private List ydoyunReport; + private List ydoyunReportTemplate; + private List ydoyunReportTemplateTitle; + private List ydoyunReportTemplateList; + private List ydoyunReportTemplateThreshold; +} diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.java new file mode 100644 index 0000000..c1d1436 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.java @@ -0,0 +1,31 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 通用 SQL 执行请求对象。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SqlRequestVO { + + /** + * 需要连接的报表数据库信息。 + */ + @Valid + @NotNull(message = "报表数据库信息不能为空") + private ReportDatabaseRespVO reportDatabase; + + /** + * 要执行的 SQL 语句。 + */ + @NotBlank(message = "SQL 语句不能为空") + private String sql; +} diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.java new file mode 100644 index 0000000..64fa222 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.java @@ -0,0 +1,113 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 报表模板子表(存储数据内容)同步 VO。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SyncReportTemplateListVO { + + /** + * 主键ID + */ + private Long id; + + /** + * 报表id + */ + private Long reportId; + /** + * 关联主表ID + */ + private Long templateId; + /** + * 字段名称 + */ + private String fieldName; + /** + * 预留字段1 + */ + private String reserveField1; + /** + * 预留字段2 + */ + private String reserveField2; + /** + * 预留字段3 + */ + private String reserveField3; + /** + * 预留字段4 + */ + private String reserveField4; + /** + * 预留字段5 + */ + private String reserveField5; + /** + * 预留字段6 + */ + private String reserveField6; + /** + * 预留字段7 + */ + private String reserveField7; + /** + * 预留字段8 + */ + private String reserveField8; + /** + * 预留字段9 + */ + private String reserveField9; + /** + * 预留字段10 + */ + private String reserveField10; + /** + * 预留字段11 + */ + private String reserveField11; + /** + * 预留字段12 + */ + private String reserveField12; + /** + * 预留字段13 + */ + private String reserveField13; + /** + * 预留字段14 + */ + private String reserveField14; + /** + * 预留字段15 + */ + private String reserveField15; + /** + * 预留字段16 + */ + private String reserveField16; + /** + * 预留字段17 + */ + private String reserveField17; + /** + * 预留字段18 + */ + private String reserveField18; + /** + * 预留字段19 + */ + private String reserveField19; + /** + * 预留字段20 + */ + private String reserveField20; + +} \ No newline at end of file diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.java new file mode 100644 index 0000000..aea1e05 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.java @@ -0,0 +1,109 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 报表模板子表(存储表头定义)同步 VO。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SyncReportTemplateTitleVO { + + /** + * 主键ID + */ + private Long id; + + /** + * 报表id + */ + private Long reportId; + /** + * 关联主表ID + */ + private Long templateId; + /** + * 预留字段1 + */ + private String reserveField1; + /** + * 预留字段2 + */ + private String reserveField2; + /** + * 预留字段3 + */ + private String reserveField3; + /** + * 预留字段4 + */ + private String reserveField4; + /** + * 预留字段5 + */ + private String reserveField5; + /** + * 预留字段6 + */ + private String reserveField6; + /** + * 预留字段7 + */ + private String reserveField7; + /** + * 预留字段8 + */ + private String reserveField8; + /** + * 预留字段9 + */ + private String reserveField9; + /** + * 预留字段10 + */ + private String reserveField10; + /** + * 预留字段11 + */ + private String reserveField11; + /** + * 预留字段12 + */ + private String reserveField12; + /** + * 预留字段13 + */ + private String reserveField13; + /** + * 预留字段14 + */ + private String reserveField14; + /** + * 预留字段15 + */ + private String reserveField15; + /** + * 预留字段16 + */ + private String reserveField16; + /** + * 预留字段17 + */ + private String reserveField17; + /** + * 预留字段18 + */ + private String reserveField18; + /** + * 预留字段19 + */ + private String reserveField19; + /** + * 预留字段20 + */ + private String reserveField20; + +} \ No newline at end of file diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.java new file mode 100644 index 0000000..f2c8478 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.java @@ -0,0 +1,49 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 报表规则模板同步 VO。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SyncReportTemplateVO { + + /** + * ID + */ + private Long id; + + /** + * 报表id + */ + private Long reportId; + + /** + * 模块名称 + */ + private String name; + + /** + * 存储过程名称 + */ + private String procedureName; + + /** + * 负责人 + */ + private String owner; + + /** + * 复核人 + */ + private String reviewer; + + /** + * 备注 + */ + private String remark; +} diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.java new file mode 100644 index 0000000..915a1a8 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.java @@ -0,0 +1,48 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 报表配置同步 VO(仅作为数据承载对象,不依赖持久层框架)。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SyncReportVO { + + /** + * 主键ID + */ + private Long id; + /** + * 报表名称 + */ + private String reportName; + /** + * 报表编码(唯一标识) + */ + private String reportCode; + /** + * 报表访问地址 + */ + private String reportUrl; + /** + * 地址类型(00外链接、10内连接路由) + */ + private String urlType; + /** + * 绑定的数据源ID(ydoyun_report_database.id) + */ + private Long databaseId; + /** + * 状态(00草稿、10发布) + */ + private String status; + /** + * 备注说明 + */ + private String remark; + +} \ No newline at end of file diff --git a/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.java b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.java new file mode 100644 index 0000000..bf23db5 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.java @@ -0,0 +1,56 @@ +package com.ydoyun.mssqljdbc.controller.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; + +/** + * 报表阈值相关配置同步 VO。 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SyncTemplateThresholdVO { + + /** + * 主键ID + */ + private Long id; + + /** + * 报表id + */ + private Long reportId; + /** + * 关联主表ID(ydoyun_report_template.id) + */ + private Long templateId; + /** + * 关联主表ID(ydoyun_report_template_list.id) + */ + private Long templateListId; + /** + * 最小阈值 + */ + private BigDecimal minThreshold; + /** + * 最大阈值 + */ + private BigDecimal maxThreshold; + /** + * 阈值定义 + */ + private String thresholdDef; + /** + * 话术 + */ + private String script; + /** + * 建议 + */ + private String suggestion; + + +} \ No newline at end of file diff --git a/src/main/java/com/ydoyun/mssqljdbc/service/ProcedureService.java b/src/main/java/com/ydoyun/mssqljdbc/service/ProcedureService.java new file mode 100644 index 0000000..9568e21 --- /dev/null +++ b/src/main/java/com/ydoyun/mssqljdbc/service/ProcedureService.java @@ -0,0 +1,560 @@ +package com.ydoyun.mssqljdbc.service; + +import com.ydoyun.mssqljdbc.controller.vo.ReportDatabaseRespVO; +import com.ydoyun.mssqljdbc.controller.vo.ReportSyncRequestVO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionDefinition; + +import javax.sql.DataSource; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.*; + +/** + * 存储过程调用与报表数据同步服务。 + *

+ * 核心职责: + *

+ */ +@Service +@Slf4j +public class ProcedureService { + + /** + * 根据请求中的数据库信息动态创建 DataSource。 + * + * @param reportDatabase 目标数据库连接信息 + * @return 对应的 DataSource 实例 + */ + private DataSource createDataSource(ReportDatabaseRespVO reportDatabase) { + if (reportDatabase == null) { + throw new IllegalArgumentException("reportDatabase 不能为空"); + } + + String dbType = reportDatabase.getDbType(); + String driverClassName; + String url; + + // 目前主要支持 SQLServer,其他类型可以根据需要扩展 + if (dbType == null || dbType.isEmpty() || "sqlserver".equalsIgnoreCase(dbType)) { + driverClassName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; + Integer port = reportDatabase.getPort(); + int portValue = (port != null) ? port : 1433; + url = "jdbc:sqlserver://" + reportDatabase.getHost() + ":" + portValue + + ";databaseName=" + reportDatabase.getDatabaseName(); + } else { + throw new IllegalArgumentException("暂不支持的数据库类型: " + dbType); + } + + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(driverClassName); + dataSource.setUrl(url); + dataSource.setUsername(reportDatabase.getUsername()); + dataSource.setPassword(reportDatabase.getPassword()); + return dataSource; + } + + /** + * 根据数据库信息创建对应的 JdbcTemplate。 + * + * @param reportDatabase 目标数据库连接信息 + * @return 对应的 JdbcTemplate + */ + private JdbcTemplate createJdbcTemplate(ReportDatabaseRespVO reportDatabase) { + return new JdbcTemplate(createDataSource(reportDatabase)); + } + + /** + * 处理结果集,将数据添加到结果列表中。 + * + * @param rs 结果集 + * @param resultList 结果列表 + * @param resultSetIndex 结果集索引(用于日志) + */ + private void processResultSet(ResultSet rs, List> resultList, int resultSetIndex) throws SQLException { + if (rs == null) { + log.warn("结果集 #{} 为 null", resultSetIndex); + return; + } + + ResultSetMetaData metaData = rs.getMetaData(); + int columnCount = metaData.getColumnCount(); + log.info("结果集 #{} 列数: {}", resultSetIndex, columnCount); + + // 记录列名和类型 + List columnNames = new ArrayList<>(); + List columnTypes = new ArrayList<>(); + for (int i = 1; i <= columnCount; i++) { + columnNames.add(metaData.getColumnLabel(i)); + columnTypes.add(metaData.getColumnTypeName(i)); + } + log.info("结果集 #{} 列名: {}", resultSetIndex, columnNames); + log.info("结果集 #{} 列类型: {}", resultSetIndex, columnTypes); + + int rowCount = 0; + while (rs.next()) { + Map row = new LinkedHashMap<>(); + for (int i = 1; i <= columnCount; i++) { + row.put(metaData.getColumnLabel(i), rs.getObject(i)); + } + resultList.add(row); + rowCount++; + log.debug("结果集 #{} 第 {} 行数据: {}", resultSetIndex, rowCount, row); + } + + if (rowCount == 0) { + log.info("结果集 #{} 为空(有 {} 列但无数据行)", resultSetIndex, columnCount); + } else { + log.info("结果集 #{} 读取了 {} 行数据", resultSetIndex, rowCount); + } + } + + /** + * 将参数值格式化为 SQL 字符串中的参数值。 + * 字符串类型会加单引号并转义单引号,其他类型直接转字符串。 + * + * @param value 参数值 + * @return 格式化后的 SQL 参数值 + */ + private String formatSqlParam(Object value) { + if (value == null) { + return "NULL"; + } + if (value instanceof String) { + // 转义单引号:' -> '' + String escaped = ((String) value).replace("'", "''"); + return "'" + escaped + "'"; + } + if (value instanceof Number || value instanceof Boolean) { + return value.toString(); + } + // 其他类型转为字符串并加单引号 + String str = value.toString().replace("'", "''"); + return "'" + str + "'"; + } + + /** + * 动态调用存储过程,并返回结果集。 + *

+ * 使用 exec 语句直接执行存储过程,使用命名参数方式,例如: + * exec YDY_AI_GET_SDXS @rq='2025-11-26',@ckdm='01',@p='123' + *

+ * 参数 Map 的 key 作为参数名,value 作为参数值。 + * 如果参数名不以 @ 开头,会自动添加 @ 前缀。 + * + * @param reportDatabase 目标数据库连接信息 + * @param procedureName 存储过程名称 + * @param params 存储过程的参数 Map(key 为参数名,value 为参数值) + * @return 结果集列表 + */ + public List> callProcedure(ReportDatabaseRespVO reportDatabase, + String procedureName, + Map params) { + log.info( + "开始调用存储过程,dbHost={}, dbName={}, procedureName={}, params={}", + reportDatabase.getHost(), + reportDatabase.getDatabaseName(), + procedureName, + params + ); + JdbcTemplate jdbcTemplate = createJdbcTemplate(reportDatabase); + + // 构建 exec 语句:exec 存储过程名 @参数名1=值1,@参数名2=值2,... + StringBuilder sql = new StringBuilder(); + sql.append("exec ").append(procedureName); + + if (params != null && !params.isEmpty()) { + sql.append(" "); + List namedParams = new ArrayList<>(); + // 使用命名参数方式:@参数名=参数值 + for (Map.Entry entry : params.entrySet()) { + String paramName = entry.getKey(); + String formattedValue = formatSqlParam(entry.getValue()); + // 确保参数名以 @ 开头 + if (!paramName.startsWith("@")) { + paramName = "@" + paramName; + } + namedParams.add(paramName + "=" + formattedValue); + log.info("参数 [{}] = {} (格式化后: {}={})", entry.getKey(), entry.getValue(), paramName, formattedValue); + } + sql.append(String.join(",", namedParams)); + } + + String finalSql = sql.toString(); + log.info("执行存储过程 SQL:{}", finalSql); + + // 使用 Statement 执行 exec 语句,以便处理多个结果集 + List> resultList = new ArrayList<>(); + jdbcTemplate.execute((Connection con) -> { + try (Statement stmt = con.createStatement()) { + // 尝试使用 executeQuery 直接获取结果集(会跳过前面的更新计数) + // 如果失败,则使用 execute 方式 + try { + log.info("尝试使用 executeQuery 执行存储过程"); + try (ResultSet rs = stmt.executeQuery(finalSql)) { + processResultSet(rs, resultList, 0); + } + + // 继续获取后续结果集 + int resultSetIndex = 1; + while (true) { + boolean hasMore = stmt.getMoreResults(); + log.info("getMoreResults() 返回: {}", hasMore); + if (!hasMore) { + int updateCount = stmt.getUpdateCount(); + log.info("getMoreResults() 返回 false,updateCount: {}", updateCount); + if (updateCount == -1) { + // 检查是否真的有结果集 + ResultSet rs = stmt.getResultSet(); + if (rs != null) { + // 确实有结果集,处理它 + try (ResultSet resultSet = rs) { + processResultSet(resultSet, resultList, resultSetIndex); + } + resultSetIndex++; + // 继续尝试获取下一个结果 + continue; + } else { + // updateCount 是 -1 但 getResultSet() 返回 null,说明没有更多结果了 + log.info("updateCount 为 -1 但 getResultSet() 返回 null,没有更多结果集了"); + break; + } + } else { + // 真正没有更多结果了 + break; + } + } else { + // 有更多结果,处理它 + int updateCount = stmt.getUpdateCount(); + if (updateCount == -1) { + try (ResultSet rs = stmt.getResultSet()) { + if (rs != null) { + processResultSet(rs, resultList, resultSetIndex); + } else { + log.warn("updateCount 为 -1 但 getResultSet() 返回 null"); + } + } + } else { + log.info("结果 #{} 是更新计数: {}", resultSetIndex, updateCount); + } + resultSetIndex++; + } + } + log.info("使用 executeQuery 方式完成,共收集到 {} 行数据", resultList.size()); + } catch (SQLException e) { + // executeQuery 失败,可能因为第一个结果是更新计数,改用 execute 方式 + log.info("executeQuery 失败,改用 execute 方式: {}", e.getMessage()); + // 执行存储过程 + boolean hasResultSet = stmt.execute(finalSql); + log.info("存储过程执行完成,execute() 返回: {}", hasResultSet); + + int resultSetIndex = 0; + boolean continueProcessing = true; + + // 处理所有结果集(包括空结果集) + // 即使第一个结果是更新计数,也要继续获取后续的结果集 + while (continueProcessing) { + int updateCount = stmt.getUpdateCount(); + log.info("处理结果 #{},updateCount: {}", resultSetIndex, updateCount); + + // updateCount == -1 表示当前是结果集(ResultSet) + // updateCount >= 0 表示是更新计数(DML 语句的影响行数) + if (updateCount == -1) { + // 处理结果集(即使为空也要处理) + try (ResultSet rs = stmt.getResultSet()) { + processResultSet(rs, resultList, resultSetIndex); + } catch (Exception ex) { + log.error("处理结果集 #{} 时出错", resultSetIndex, ex); + throw ex; + } + } else { + // 更新计数,记录日志但不收集数据 + log.info("结果 #{} 是更新计数: {}", resultSetIndex, updateCount); + } + + resultSetIndex++; + + // 获取下一个结果 + // getMoreResults() 返回 true 表示还有更多结果,false 表示没有更多结果 + boolean hasMoreResults = stmt.getMoreResults(); + log.info("getMoreResults() 返回: {}", hasMoreResults); + + // 检查是否还有更多结果 + if (!hasMoreResults) { + int nextUpdateCount = stmt.getUpdateCount(); + log.info("getMoreResults() 返回 false,检查 updateCount: {}", nextUpdateCount); + // 如果 updateCount 是 -1,检查是否真的有结果集 + if (nextUpdateCount == -1) { + ResultSet nextRs = stmt.getResultSet(); + if (nextRs != null) { + log.info("虽然 getMoreResults() 返回 false,但确实有结果集,继续处理"); + continueProcessing = true; + } else { + log.info("updateCount 为 -1 但 getResultSet() 返回 null,没有更多结果了"); + continueProcessing = false; + } + } else { + // 真正没有更多结果了 + continueProcessing = false; + } + } else { + continueProcessing = true; + } + } + + log.info("存储过程执行完成,共收集到 {} 行数据(来自 {} 个结果集)", resultList.size(), resultSetIndex); + } + } + return null; + }); + + return resultList; + } + + /** + * 执行任意 SQL。 + *

+ * 自动根据 SQL 前缀是否为 SELECT 判断是查询还是更新, + * 并在指定数据库上执行。 + * + * @param reportDatabase 目标数据库信息 + * @param sql 任意 SQL 语句 + * @return 如果是查询 SQL,返回 List>;如果是 DML(INSERT/UPDATE/DELETE),返回影响行数 + */ + public Object executeSql(ReportDatabaseRespVO reportDatabase, String sql) { + log.info("开始执行 SQL,dbHost={}, dbName={}, sql={}", + reportDatabase.getHost(), reportDatabase.getDatabaseName(), sql); + JdbcTemplate jdbcTemplate = createJdbcTemplate(reportDatabase); + String lowerSql = sql.trim().toLowerCase(); + if (lowerSql.startsWith("select")) { + // 查询 SQL + return jdbcTemplate.queryForList(sql); + } else { + // 非查询 SQL + return jdbcTemplate.update(sql); + } + } + + + // ===================================================================== + // ====================== ⭐ 新增:报表同步功能 ⭐ ====================== + // ===================================================================== + + /** + * 将驼峰命名的字段名转换为下划线命名。 + * + * @param str 驼峰格式字段名,例如 userName + * @return 下划线格式字段名,例如 user_name + */ + private String camelToUnderline(String str) { + if (str == null) return null; + StringBuilder result = new StringBuilder(); + for (char c : str.toCharArray()) { + if (Character.isUpperCase(c)) { + result.append("_").append(Character.toLowerCase(c)); + } else { + result.append(c); + } + } + return result.toString(); + } + + /** + * 把单条 Map 中的所有驼峰字段名转换成下划线字段名。 + * + * @param data 原始数据 Map(key 为驼峰字段名) + * @return key 已转换为下划线的 Map + */ + private Map convertCamelMap(Map data) { + Map result = new LinkedHashMap<>(); + data.forEach((key, value) -> { + result.put(camelToUnderline(key), value); + }); + return result; + } + + /** + * 将任意 Java Bean 转换为 Map,key 为属性名,value 为属性值。 + *

+ * 会向上遍历父类(例如 BaseDO),并忽略 static 字段。 + * + * @param bean Java Bean 对象 + * @return 字段名到字段值的映射 + */ + private Map beanToMap(Object bean) { + Map result = new LinkedHashMap<>(); + if (bean == null) { + return result; + } + Class clazz = bean.getClass(); + while (clazz != null && clazz != Object.class) { + for (Field field : clazz.getDeclaredFields()) { + // 跳过静态字段 + if (java.lang.reflect.Modifier.isStatic(field.getModifiers())) { + continue; + } + field.setAccessible(true); + try { + result.put(field.getName(), field.get(bean)); + } catch (IllegalAccessException e) { + log.warn("读取属性失败,class={}, field={}", clazz.getName(), field.getName(), e); + } + } + clazz = clazz.getSuperclass(); + } + return result; + } + + /** + * 批量向指定表插入数据。 + *

+ * 会先将字段名从驼峰转换为下划线,并排除指定字段, + * 然后组装 INSERT 语句并逐条执行。 + * + * @param jdbcTemplate 对应数据源的 JdbcTemplate + * @param table 目标表名 + * @param dataList 要插入的数据列表(可以是 Map 或 VO 对象) + * @param excludeColumns 需要排除的字段名列表(下划线格式) + */ + private void batchInsert(JdbcTemplate jdbcTemplate, String table, List dataList, List excludeColumns) { + if (dataList == null || dataList.isEmpty()) { + return; + } + + for (Object item : dataList) { + + // 支持原有 Map 结构,也支持新的 VO 对象 + Map source; + if (item instanceof Map) { + //noinspection unchecked + source = (Map) item; + } else { + source = beanToMap(item); + } + + // 转下划线 + Map row = convertCamelMap(source); + + StringBuilder fields = new StringBuilder(); + StringBuilder values = new StringBuilder(); + List params = new ArrayList<>(); + + row.forEach((k, v) -> { + // 排除指定列 + if (excludeColumns != null && excludeColumns.contains(k)) { + return; + } + + fields.append(k).append(","); + values.append("?,"); + + // 类型规范化 + if (v == null) { + params.add(null); + } else if (v instanceof String || v instanceof Number || v instanceof Boolean || v instanceof java.util.Date) { + if (v instanceof java.util.Date) { + params.add(new java.sql.Timestamp(((java.util.Date) v).getTime())); + } else { + params.add(v); + } + } else { + params.add(v.toString()); + } + }); + + // 如果没有字段,跳过 + if (fields.length() == 0) continue; + + fields.deleteCharAt(fields.length() - 1); + values.deleteCharAt(values.length() - 1); + + String sql = "INSERT INTO " + table + + " (" + fields + ") VALUES (" + values + ")"; + + jdbcTemplate.update(sql, params.toArray()); + } + } + + + // ====================== 需要的同步方法 ====================== + + /** + * 同步报表相关表的数据。 + *

+ * 基于传入的 {@link ReportSyncRequestVO}: + *

    + *
  1. 校验报表 ID 以及目标数据库信息
  2. + *
  3. 在同一事务中删除旧数据
  4. + *
  5. 批量插入新的报表配置和模板数据
  6. + *
+ * + * @param request 报表同步请求对象,包含报表 ID、目标库信息及各表数据 + * @return 同步结果描述 + */ + public String syncReportData(ReportSyncRequestVO request) { + + ReportDatabaseRespVO reportDatabase = request.getReportDatabase(); + Long reportId = request.getReportId(); + if (reportId == null) { + throw new RuntimeException("reportId 不能为空"); + } + if (reportDatabase == null) { + throw new RuntimeException("reportDatabase 不能为空"); + } + + log.info("开始同步报表数据,dbHost={}, dbName={}, reportId={}", + reportDatabase.getHost(), reportDatabase.getDatabaseName(), reportId); + + // 为本次同步请求创建专用数据源与事务管理器,保证多表操作在同一事务中完成 + DataSource dataSource = createDataSource(reportDatabase); + DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); + DefaultTransactionDefinition def = new DefaultTransactionDefinition(); + TransactionStatus status = transactionManager.getTransaction(def); + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + + try { + // 删除旧数据 + jdbcTemplate.update("DELETE FROM ydoyun_report WHERE id=?", reportId); + jdbcTemplate.update("DELETE FROM ydoyun_report_template WHERE report_id=?", reportId); + jdbcTemplate.update("DELETE FROM ydoyun_report_template_title WHERE report_id=?", reportId); + jdbcTemplate.update("DELETE FROM ydoyun_report_template_list WHERE report_id=?", reportId); + jdbcTemplate.update("DELETE FROM ydoyun_report_template_threshold WHERE report_id=?", reportId); + + // 新增数据,非空判断和 list size 判断 + if (request.getYdoyunReport() != null && !request.getYdoyunReport().isEmpty()) { + batchInsert(jdbcTemplate, "ydoyun_report", request.getYdoyunReport(), Arrays.asList("trans_map")); + } + if (request.getYdoyunReportTemplate() != null && !request.getYdoyunReportTemplate().isEmpty()) { + batchInsert(jdbcTemplate, "ydoyun_report_template", request.getYdoyunReportTemplate(), Arrays.asList("trans_map")); + } + if (request.getYdoyunReportTemplateTitle() != null && !request.getYdoyunReportTemplateTitle().isEmpty()) { + batchInsert(jdbcTemplate, "ydoyun_report_template_title", request.getYdoyunReportTemplateTitle(), Arrays.asList("trans_map")); + } + if (request.getYdoyunReportTemplateList() != null && !request.getYdoyunReportTemplateList().isEmpty()) { + batchInsert(jdbcTemplate, "ydoyun_report_template_list", request.getYdoyunReportTemplateList(), Arrays.asList("trans_map")); + } + if (request.getYdoyunReportTemplateThreshold() != null && !request.getYdoyunReportTemplateThreshold().isEmpty()) { + batchInsert(jdbcTemplate, "ydoyun_report_template_threshold", request.getYdoyunReportTemplateThreshold(), Arrays.asList("trans_map")); + } + + transactionManager.commit(status); + return "同步成功"; + } catch (Exception e) { + transactionManager.rollback(status); + log.error("同步报表数据失败,reportId={}, dbHost={}, dbName={}", + reportId, reportDatabase.getHost(), reportDatabase.getDatabaseName(), e); + throw new RuntimeException("同步报表数据失败: " + e.getMessage(), e); + } + } + + +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..9e72669 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,15 @@ +server: + port: 49090 + address: 0.0.0.0 # 允许外部访问 + +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver + # SQL Server 2008 一般不强制使用加密,这里不主动开启 SSL,避免 TLS 协议不兼容问题 + url: jdbc:sqlserver://106.15.62.63:9943;databaseName=ERPLJSM + username: bsai + password: ljsm@bsAI + +security: + api-key: your_secret_api_key_123456 diff --git a/target/classes/application.yml b/target/classes/application.yml new file mode 100644 index 0000000..9e72669 --- /dev/null +++ b/target/classes/application.yml @@ -0,0 +1,15 @@ +server: + port: 49090 + address: 0.0.0.0 # 允许外部访问 + +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver + # SQL Server 2008 一般不强制使用加密,这里不主动开启 SSL,避免 TLS 协议不兼容问题 + url: jdbc:sqlserver://106.15.62.63:9943;databaseName=ERPLJSM + username: bsai + password: ljsm@bsAI + +security: + api-key: your_secret_api_key_123456 diff --git a/target/classes/com/ydoyun/mssqljdbc/MssqlJdbcApplication.class b/target/classes/com/ydoyun/mssqljdbc/MssqlJdbcApplication.class new file mode 100644 index 0000000..3c3b324 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/MssqlJdbcApplication.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.class b/target/classes/com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.class new file mode 100644 index 0000000..519b8e2 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/ProcedureController.class b/target/classes/com/ydoyun/mssqljdbc/controller/ProcedureController.class new file mode 100644 index 0000000..4ce8dd3 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/ProcedureController.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.class new file mode 100644 index 0000000..f29158d Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.class new file mode 100644 index 0000000..c0bba51 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.class new file mode 100644 index 0000000..bbda0c1 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.class new file mode 100644 index 0000000..3c50498 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.class new file mode 100644 index 0000000..5b753b3 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.class new file mode 100644 index 0000000..4b0008f Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.class new file mode 100644 index 0000000..a2b4c30 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.class new file mode 100644 index 0000000..4dcf169 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.class new file mode 100644 index 0000000..9ee937b Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.class b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.class new file mode 100644 index 0000000..39e2e1c Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.class differ diff --git a/target/classes/com/ydoyun/mssqljdbc/service/ProcedureService.class b/target/classes/com/ydoyun/mssqljdbc/service/ProcedureService.class new file mode 100644 index 0000000..2cd63c0 Binary files /dev/null and b/target/classes/com/ydoyun/mssqljdbc/service/ProcedureService.class differ diff --git a/target/maven-archiver/pom.properties b/target/maven-archiver/pom.properties new file mode 100644 index 0000000..a20d578 --- /dev/null +++ b/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=mssql-jdbc +groupId=com.ydoyun +version=1.0.0 diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..04d9cd1 --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,14 @@ +com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.class +com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.class +com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.class +com/ydoyun/mssqljdbc/MssqlJdbcApplication.class +com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.class +com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.class +com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.class +com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.class +com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.class +com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.class +com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.class +com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.class +com/ydoyun/mssqljdbc/controller/ProcedureController.class +com/ydoyun/mssqljdbc/service/ProcedureService.class diff --git a/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..a8740cb --- /dev/null +++ b/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,14 @@ +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ApiResponseVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateListVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportDatabaseRespVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/MssqlJdbcApplication.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncTemplateThresholdVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ReportSyncRequestVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/ProcedureController.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateTitleVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportTemplateVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/ProcedureRequestVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SyncReportVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/controller/vo/SqlRequestVO.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/service/ProcedureService.java +/Users/ouhaolan/project/百盛科技/报表/mssql-jdbc/src/main/java/com/ydoyun/mssqljdbc/config/ApiKeyAuthFilter.java diff --git a/target/mssql-jdbc-1.0.0.jar b/target/mssql-jdbc-1.0.0.jar new file mode 100644 index 0000000..50aed29 Binary files /dev/null and b/target/mssql-jdbc-1.0.0.jar differ diff --git a/target/mssql-jdbc-1.0.0.jar.original b/target/mssql-jdbc-1.0.0.jar.original new file mode 100644 index 0000000..683b366 Binary files /dev/null and b/target/mssql-jdbc-1.0.0.jar.original differ