# 流水分析平台对接实施计划 > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **目标:** 实现与见知现金流尽调系统的对接,封装7个核心接口调用 **架构:** 创建ccdi-lsfx独立模块,使用RestTemplate发起HTTP请求,通过HttpUtil工具类统一处理各类请求,LsfxAnalysisClient封装7个接口调用逻辑 **技术栈:** Spring Boot 3.5.8, RestTemplate, Lombok, SpringDoc OpenAPI --- ## 前置准备 ### Task 0: 更新根POM和Admin POM **文件:** - 修改: `pom.xml:221-230` - 修改: `ruoyi-admin/pom.xml` **步骤 1: 在根pom.xml中添加ccdi-lsfx模块** 在 `` 标签内添加新模块: ```xml ruoyi-admin ruoyi-framework ruoyi-system ruoyi-quartz ruoyi-generator ruoyi-common ccdi-info-collection ccdi-project ccdi-lsfx ``` **步骤 2: 在ruoyi-admin/pom.xml中添加ccdi-lsfx依赖** 在 `` 标签内添加: ```xml com.ruoyi ccdi-lsfx ``` **步骤 3: 提交更改** ```bash git add pom.xml ruoyi-admin/pom.xml git commit -m "chore: 添加ccdi-lsfx模块依赖" ``` --- ## 模块基础结构 ### Task 1: 创建ccdi-lsfx模块目录和pom.xml **文件:** - 创建: `ccdi-lsfx/pom.xml` **步骤 1: 创建pom.xml文件** ```xml com.ruoyi ruoyi 3.9.1 4.0.0 ccdi-lsfx 流水分析平台对接模块 com.ruoyi ruoyi-common org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springdoc springdoc-openapi-starter-webmvc-ui ``` **步骤 2: 创建基础目录结构** ```bash mkdir -p ccdi-lsfx/src/main/java/com/ruoyi/lsfx/{config,constants,client,domain/{request,response},exception,util,controller} mkdir -p ccdi-lsfx/src/main/resources ``` **步骤 3: 提交更改** ```bash git add ccdi-lsfx/ git commit -m "feat: 创建ccdi-lsfx模块基础结构" ``` --- ## 配置层 ### Task 2: 添加配置到application-dev.yml **文件:** - 修改: `ruoyi-admin/src/main/resources/application-dev.yml` **步骤 1: 在文件末尾添加lsfx配置** ```yaml # 流水分析平台配置 lsfx: api: # 测试环境 base-url: http://158.234.196.5:82/c4c3 # 生产环境(注释掉测试环境后启用) # base-url: http://64.202.32.176/c4c3 # 认证配置 app-id: remote_app app-secret: your_app_secret_here # 从见知获取 client-id: c2017e8d105c435a96f86373635b6a09 # 测试环境固定值 # 接口路径配置 endpoints: get-token: /account/common/getToken upload-file: /watson/api/project/remoteUploadSplitFile fetch-inner-flow: /watson/api/project/getJZFileOrZjrcuFile check-parse-status: /watson/api/project/upload/getpendings generate-report: /watson/api/project/confirmStageUploadLogs check-report-status: /watson/api/project/upload/getallpendings get-bank-statement: /watson/api/project/upload/getBankStatement # RestTemplate配置 connection-timeout: 30000 # 连接超时30秒 read-timeout: 60000 # 读取超时60秒 ``` **步骤 2: 提交更改** ```bash git add ruoyi-admin/src/main/resources/application-dev.yml git commit -m "config: 添加流水分析平台配置" ``` --- ### Task 3: 创建RestTemplate配置类 **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/config/RestTemplateConfig.java` **步骤 1: 创建配置类** ```java package com.ruoyi.lsfx.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; /** * RestTemplate配置 */ @Configuration public class RestTemplateConfig { @Value("${lsfx.api.connection-timeout:30000}") private int connectionTimeout; @Value("${lsfx.api.read-timeout:60000}") private int readTimeout; @Bean public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(connectionTimeout); factory.setReadTimeout(readTimeout); return new RestTemplate(factory); } } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/config/RestTemplateConfig.java git commit -m "feat: 添加RestTemplate配置类" ``` --- ### Task 4: 创建常量类 **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/constants/LsfxConstants.java` **步骤 1: 创建常量类** ```java package com.ruoyi.lsfx.constants; /** * 流水分析平台常量 */ public class LsfxConstants { /** 基础URL配置键 */ public static final String BASE_URL_KEY = "lsfx.api.base-url"; /** 成功状态码 */ public static final String SUCCESS_CODE = "200"; /** 文件解析成功状态 */ public static final int PARSE_SUCCESS_STATUS = -5; public static final String PARSE_SUCCESS_DESC = "data.wait.confirm.newaccount"; /** 数据渠道编码 */ public static final String DATA_CHANNEL_ZJRCU = "ZJRCU"; /** 分析类型 */ public static final String ANALYSIS_TYPE = "-1"; /** 请求头 */ public static final String HEADER_CLIENT_ID = "X-Xencio-Client-Id"; public static final String HEADER_CONTENT_TYPE = "Content-Type"; /** 默认角色 */ public static final String DEFAULT_ROLE = "VIEWER"; } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/constants/LsfxConstants.java git commit -m "feat: 添加流水分析常量类" ``` --- ## 工具类层 ### Task 5: 创建MD5工具类 **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/util/MD5Util.java` **步骤 1: 创建MD5工具类** ```java package com.ruoyi.lsfx.util; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * MD5加密工具类 */ public class MD5Util { /** * MD5加密 * @param input 待加密字符串 * @return MD5加密后的32位小写字符串 */ public static String encrypt(String input) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] messageDigest = md.digest(input.getBytes()); StringBuilder hexString = new StringBuilder(); for (byte b : messageDigest) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException("MD5加密失败", e); } } /** * 生成安全码 * @param projectNo 项目编号 * @param entityName 项目名称 * @param appSecret 应用密钥 * @return MD5安全码 */ public static String generateSecretCode(String projectNo, String entityName, String appSecret) { String raw = projectNo + "_" + entityName + "_" + appSecret; return encrypt(raw); } } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/util/MD5Util.java git commit -m "feat: 添加MD5加密工具类" ``` --- ### Task 6: 创建HttpUtil工具类 **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/util/HttpUtil.java` **步骤 1: 创建HttpUtil工具类** ```java package com.ruoyi.lsfx.util; import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; import java.util.Map; /** * HTTP请求工具类 */ @Component public class HttpUtil { @Resource private RestTemplate restTemplate; /** * 发送GET请求(带请求头) * @param url 请求URL * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T get(String url, Map headers, Class responseType) { HttpHeaders httpHeaders = createHeaders(headers); HttpEntity requestEntity = new HttpEntity<>(httpHeaders); ResponseEntity response = restTemplate.exchange( url, HttpMethod.GET, requestEntity, responseType ); return response.getBody(); } /** * 发送POST请求(JSON格式,带请求头) * @param url 请求URL * @param request 请求对象 * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T postJson(String url, Object request, Map headers, Class responseType) { HttpHeaders httpHeaders = createHeaders(headers); httpHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity requestEntity = new HttpEntity<>(request, httpHeaders); ResponseEntity response = restTemplate.postForEntity(url, requestEntity, responseType); return response.getBody(); } /** * 上传文件(Multipart格式) * @param url 请求URL * @param params 参数(包含文件) * @param headers 请求头 * @param responseType 响应类型 * @return 响应对象 */ public T uploadFile(String url, Map params, Map headers, Class responseType) { HttpHeaders httpHeaders = createHeaders(headers); httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap body = new LinkedMultiValueMap<>(); if (params != null) { params.forEach(body::add); } HttpEntity> requestEntity = new HttpEntity<>(body, httpHeaders); ResponseEntity response = restTemplate.postForEntity(url, requestEntity, responseType); return response.getBody(); } /** * 创建请求头 * @param headers 请求头Map * @return HttpHeaders对象 */ private HttpHeaders createHeaders(Map headers) { HttpHeaders httpHeaders = new HttpHeaders(); if (headers != null && !headers.isEmpty()) { headers.forEach(httpHeaders::set); } return httpHeaders; } } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/util/HttpUtil.java git commit -m "feat: 添加HTTP请求工具类" ``` --- ## 异常处理层 ### Task 7: 创建异常类 **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/exception/LsfxApiException.java` **步骤 1: 创建异常类** ```java package com.ruoyi.lsfx.exception; /** * 流水分析平台API异常 */ public class LsfxApiException extends RuntimeException { private String errorCode; public LsfxApiException(String message) { super(message); } public LsfxApiException(String message, Throwable cause) { super(message, cause); } public LsfxApiException(String errorCode, String message) { super(message); this.errorCode = errorCode; } public String getErrorCode() { return errorCode; } } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/exception/LsfxApiException.java git commit -m "feat: 添加流水分析API异常类" ``` --- ## DTO层 - 接口1(获取Token) ### Task 8: 创建GetTokenRequest **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/request/GetTokenRequest.java` **步骤 1: 创建请求DTO** ```java package com.ruoyi.lsfx.domain.request; import lombok.Data; /** * 获取Token请求参数 */ @Data public class GetTokenRequest { /** 项目编号 */ private String projectNo; /** 项目名称 */ private String entityName; /** 操作人员编号 */ private String userId; /** 操作人员姓名 */ private String userName; /** 见知提供appId */ private String appId; /** 安全码 md5(projectNo + "_" + entityName + "_" + appSecret) */ private String appSecretCode; /** 人员角色 */ private String role; /** 行社机构号 */ private String orgCode; /** 企业统信码或个人身份证号 */ private String entityId; /** 信贷关联人信息 */ private String xdRelatedPersons; /** 金综链流水日期ID */ private String jzDataDateId; /** 行内流水开始日期 */ private String innerBSStartDateId; /** 行内流水结束日期 */ private String innerBSEndDateId; /** 分析类型 */ private String analysisType; /** 客户经理所属营业部机构编码 */ private String departmentCode; } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/request/GetTokenRequest.java git commit -m "feat: 添加获取Token请求DTO" ``` --- ### Task 9: 创建GetTokenResponse **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetTokenResponse.java` **步骤 1: 创建响应DTO** ```java package com.ruoyi.lsfx.domain.response; import lombok.Data; /** * 获取Token响应 */ @Data public class GetTokenResponse { /** 返回码 */ private String code; /** 响应状态 */ private String status; /** 消息 */ private String message; /** 成功标识 */ private Boolean successResponse; /** 响应数据 */ private TokenData data; @Data public static class TokenData { /** token */ private String token; /** 见知项目Id */ private Integer projectId; /** 项目编号 */ private String projectNo; /** 项目名称 */ private String entityName; /** 分析类型 */ private Integer analysisType; } } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetTokenResponse.java git commit -m "feat: 添加获取Token响应DTO" ``` --- ## DTO层 - 接口2-7(简化示例) ### Task 10: 创建其他接口DTO(批量创建) **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/request/FetchInnerFlowRequest.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/request/GenerateReportRequest.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/request/GetBankStatementRequest.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/UploadFileResponse.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/FetchInnerFlowResponse.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/CheckParseStatusResponse.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GenerateReportResponse.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/CheckReportStatusResponse.java` - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/GetBankStatementResponse.java` **步骤 1: 参考设计文档创建各个DTO类** 根据 `docs/plans/2026-03-02-lsfx-integration-design.md` 中的DTO设计,创建剩余的请求和响应对象。每个DTO都使用 `@Data` 注解,字段根据接口文档定义。 **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/ git commit -m "feat: 添加其他接口的DTO对象" ``` --- ## 客户端层 ### Task 11: 创建LsfxAnalysisClient(接口1-3) **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/client/LsfxAnalysisClient.java` **步骤 1: 创建客户端类(第一部分)** ```java package com.ruoyi.lsfx.client; import com.ruoyi.lsfx.constants.LsfxConstants; import com.ruoyi.lsfx.domain.request.*; import com.ruoyi.lsfx.domain.response.*; import com.ruoyi.lsfx.util.HttpUtil; import com.ruoyi.lsfx.util.MD5Util; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.Resource; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; /** * 流水分析平台客户端 */ @Component public class LsfxAnalysisClient { @Resource private HttpUtil httpUtil; @Value("${lsfx.api.base-url}") private String baseUrl; @Value("${lsfx.api.app-id}") private String appId; @Value("${lsfx.api.app-secret}") private String appSecret; @Value("${lsfx.api.client-id}") private String clientId; /** * 获取Token */ public GetTokenResponse getToken(GetTokenRequest request) { String secretCode = MD5Util.generateSecretCode( request.getProjectNo(), request.getEntityName(), appSecret ); request.setAppSecretCode(secretCode); request.setAppId(appId); if (request.getAnalysisType() == null) { request.setAnalysisType(LsfxConstants.ANALYSIS_TYPE); } if (request.getRole() == null) { request.setRole(LsfxConstants.DEFAULT_ROLE); } String url = baseUrl + "/account/common/getToken"; return httpUtil.postJson(url, request, GetTokenResponse.class); } /** * 上传文件 */ public UploadFileResponse uploadFile(Integer groupId, Resource file) { String url = baseUrl + "/watson/api/project/remoteUploadSplitFile"; Map params = new HashMap<>(); params.put("groupId", groupId); params.put("files", file); Map headers = new HashMap<>(); headers.put(LsfxConstants.HEADER_CLIENT_ID, clientId); return httpUtil.uploadFile(url, params, headers, UploadFileResponse.class); } /** * 拉取行内流水 */ public FetchInnerFlowResponse fetchInnerFlow(FetchInnerFlowRequest request) { String url = baseUrl + "/watson/api/project/getJZFileOrZjrcuFile"; Map headers = new HashMap<>(); headers.put(LsfxConstants.HEADER_CLIENT_ID, clientId); return httpUtil.postJson(url, request, headers, FetchInnerFlowResponse.class); } } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/client/LsfxAnalysisClient.java git commit -m "feat: 添加流水分析客户端(接口1-3)" ``` --- ### Task 12: 完善LsfxAnalysisClient(接口4-7) **文件:** - 修改: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/client/LsfxAnalysisClient.java` **步骤 1: 添加剩余接口方法** 在LsfxAnalysisClient类中添加: ```java /** * 检查文件解析状态 */ public CheckParseStatusResponse checkParseStatus(Integer groupId, String inprogressList) { String url = baseUrl + "/watson/api/project/upload/getpendings"; Map params = new HashMap<>(); params.put("groupId", groupId); params.put("inprogressList", inprogressList); Map headers = new HashMap<>(); headers.put(LsfxConstants.HEADER_CLIENT_ID, clientId); return httpUtil.postJson(url, params, headers, CheckParseStatusResponse.class); } /** * 生成尽调报告 */ public GenerateReportResponse generateReport(GenerateReportRequest request) { String url = baseUrl + "/watson/api/project/confirmStageUploadLogs"; Map headers = new HashMap<>(); headers.put(LsfxConstants.HEADER_CLIENT_ID, clientId); return httpUtil.postJson(url, request, headers, GenerateReportResponse.class); } /** * 检查报告生成状态 */ public CheckReportStatusResponse checkReportStatus(Integer groupId) { String url = baseUrl + "/watson/api/project/upload/getallpendings?groupId=" + groupId; Map headers = new HashMap<>(); headers.put(LsfxConstants.HEADER_CLIENT_ID, clientId); return httpUtil.get(url, headers, CheckReportStatusResponse.class); } /** * 获取银行流水 */ public GetBankStatementResponse getBankStatement(GetBankStatementRequest request) { String url = baseUrl + "/watson/api/project/upload/getBankStatement"; Map headers = new HashMap<>(); headers.put(LsfxConstants.HEADER_CLIENT_ID, clientId); return httpUtil.postJson(url, request, headers, GetBankStatementResponse.class); } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/client/LsfxAnalysisClient.java git commit -m "feat: 完善流水分析客户端(接口4-7)" ``` --- ## 控制器层 ### Task 13: 创建测试Controller **文件:** - 创建: `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/controller/LsfxTestController.java` **步骤 1: 创建测试Controller** ```java package com.ruoyi.lsfx.controller; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.lsfx.client.LsfxAnalysisClient; import com.ruoyi.lsfx.domain.request.*; import com.ruoyi.lsfx.domain.response.*; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.core.io.Resource; import javax.annotation.Resource; /** * 流水分析平台接口测试控制器 */ @Tag(name = "流水分析平台接口测试", description = "用于测试流水分析平台的7个接口") @RestController @RequestMapping("/lsfx/test") public class LsfxTestController { @Resource private LsfxAnalysisClient lsfxAnalysisClient; @Operation(summary = "获取Token", description = "创建项目并获取访问Token") @PostMapping("/getToken") public AjaxResult getToken(@RequestBody GetTokenRequest request) { GetTokenResponse response = lsfxAnalysisClient.getToken(request); return AjaxResult.success(response); } @Operation(summary = "上传流水文件", description = "上传银行流水文件到流水分析平台") @PostMapping("/uploadFile") public AjaxResult uploadFile( @Parameter(description = "项目ID") @RequestParam Integer groupId, @Parameter(description = "流水文件") @RequestParam("file") MultipartFile file ) { Resource fileResource = file.getResource(); UploadFileResponse response = lsfxAnalysisClient.uploadFile(groupId, fileResource); return AjaxResult.success(response); } @Operation(summary = "拉取行内流水", description = "从数仓拉取行内流水数据") @PostMapping("/fetchInnerFlow") public AjaxResult fetchInnerFlow(@RequestBody FetchInnerFlowRequest request) { FetchInnerFlowResponse response = lsfxAnalysisClient.fetchInnerFlow(request); return AjaxResult.success(response); } @Operation(summary = "检查文件解析状态", description = "轮询检查上传文件的解析状态") @PostMapping("/checkParseStatus") public AjaxResult checkParseStatus( @Parameter(description = "项目ID") @RequestParam Integer groupId, @Parameter(description = "文件ID列表") @RequestParam String inprogressList ) { CheckParseStatusResponse response = lsfxAnalysisClient.checkParseStatus(groupId, inprogressList); return AjaxResult.success(response); } @Operation(summary = "生成尽调报告", description = "确认文件后生成尽调报告") @PostMapping("/generateReport") public AjaxResult generateReport(@RequestBody GenerateReportRequest request) { GenerateReportResponse response = lsfxAnalysisClient.generateReport(request); return AjaxResult.success(response); } @Operation(summary = "检查报告生成状态", description = "轮询检查尽调报告生成状态") @GetMapping("/checkReportStatus") public AjaxResult checkReportStatus( @Parameter(description = "项目ID") @RequestParam Integer groupId ) { CheckReportStatusResponse response = lsfxAnalysisClient.checkReportStatus(groupId); return AjaxResult.success(response); } @Operation(summary = "获取银行流水列表", description = "分页获取银行流水数据") @PostMapping("/getBankStatement") public AjaxResult getBankStatement(@RequestBody GetBankStatementRequest request) { GetBankStatementResponse response = lsfxAnalysisClient.getBankStatement(request); return AjaxResult.success(response); } } ``` **步骤 2: 提交更改** ```bash git add ccdi-lsfx/src/main/java/com/ruoyi/lsfx/controller/LsfxTestController.java git commit -m "feat: 添加流水分析测试控制器" ``` --- ## 测试验证 ### Task 14: 编译项目验证依赖 **文件:** - 无文件修改 **步骤 1: 编译项目** ```bash mvn clean compile ``` 预期:编译成功,无错误 **步骤 2: 修复可能的编译错误** 如果出现编译错误,检查: 1. 所有import语句是否正确 2. Lombok是否正确配置 3. 依赖是否正确添加 --- ### Task 15: 启动应用验证配置 **文件:** - 无文件修改 **步骤 1: 启动应用** 提示用户手动启动应用: ```bash # 方式1: 使用Maven mvn spring-boot:run # 方式2: 使用启动脚本(Windows) ry.bat # 方式3: 使用启动脚本(Linux/Mac) ./ry.sh start ``` **步骤 2: 验证启动成功** 检查日志中是否包含: - RestTemplate bean创建成功 - ccdi-lsfx模块加载成功 访问:http://localhost:8080/swagger-ui/index.html 预期:在Swagger UI中能看到 "流水分析平台接口测试" 分组 --- ### Task 16: 测试接口1(获取Token) **文件:** - 无文件修改 **步骤 1: 通过Swagger测试获取Token接口** 访问:http://localhost:8080/swagger-ui/index.html 找到 "流水分析平台接口测试" → "获取Token" 请求示例: ```json { "projectNo": "test-project-001", "entityName": "测试项目001", "userId": "test001", "userName": "测试用户001", "orgCode": "800000", "departmentCode": "800111" } ``` 预期:返回200状态码,包含token和projectId **步骤 2: 记录测试结果** 如果成功,记录返回的 token 和 projectId,后续测试需要使用。 --- ## 完成标记 ### Task 17: 标记实施完成 **文件:** - 无文件修改 **步骤 1: 确认所有功能正常** 检查清单: - [ ] 项目编译成功 - [ ] 应用启动成功 - [ ] Swagger UI可访问 - [ ] 获取Token接口测试通过 - [ ] 其他接口可正常调用(可选) **步骤 2: 创建完成标记** ```bash git tag -a v1.0.0-lsfx -m "完成流水分析平台对接模块" git push origin v1.0.0-lsfx ``` --- ## 备注 ### 关键注意事项 1. **安全码生成**: Token接口需要MD5加密,格式为 `projectNo_entityName_appSecret` 2. **请求头设置**: 除Token接口外,其他接口都需要设置 `X-Xencio-Client-Id` 请求头 3. **文件上传**: 上传文件接口使用 `multipart/form-data` 格式 4. **配置管理**: 生产环境需要修改 `application-dev.yml` 中的 `base-url` 和 `client-id` 5. **app-secret**: 需要从见知获取真实的 `app-secret` 配置 ### 后续优化建议 1. 添加接口调用日志记录 2. 实现接口调用失败重试机制 3. 添加接口响应数据缓存 4. 实现流水数据持久化到本地数据库 5. 添加接口调用的单元测试和集成测试