Files
ccdi/docs/plans/2026-03-02-lsfx-integration.md

1076 lines
28 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 流水分析平台对接实施计划
> **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模块**
`<modules>` 标签内添加新模块:
```xml
<modules>
<module>ruoyi-admin</module>
<module>ruoyi-framework</module>
<module>ruoyi-system</module>
<module>ruoyi-quartz</module>
<module>ruoyi-generator</module>
<module>ruoyi-common</module>
<module>ccdi-info-collection</module>
<module>ccdi-project</module>
<module>ccdi-lsfx</module>
</modules>
```
**步骤 2: 在ruoyi-admin/pom.xml中添加ccdi-lsfx依赖**
`<dependencies>` 标签内添加:
```xml
<!-- 流水分析平台对接 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ccdi-lsfx</artifactId>
</dependency>
```
**步骤 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
<?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>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.9.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ccdi-lsfx</artifactId>
<description>流水分析平台对接模块</description>
<dependencies>
<!-- 通用工具 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- SpringDoc OpenAPI (Swagger) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
</dependencies>
</project>
```
**步骤 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> T get(String url, Map<String, String> headers, Class<T> responseType) {
HttpHeaders httpHeaders = createHeaders(headers);
HttpEntity<Void> requestEntity = new HttpEntity<>(httpHeaders);
ResponseEntity<T> 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> T postJson(String url, Object request, Map<String, String> headers, Class<T> responseType) {
HttpHeaders httpHeaders = createHeaders(headers);
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Object> requestEntity = new HttpEntity<>(request, httpHeaders);
ResponseEntity<T> response = restTemplate.postForEntity(url, requestEntity, responseType);
return response.getBody();
}
/**
* 上传文件Multipart格式
* @param url 请求URL
* @param params 参数(包含文件)
* @param headers 请求头
* @param responseType 响应类型
* @return 响应对象
*/
public <T> T uploadFile(String url, Map<String, Object> params, Map<String, String> headers, Class<T> responseType) {
HttpHeaders httpHeaders = createHeaders(headers);
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
if (params != null) {
params.forEach(body::add);
}
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, httpHeaders);
ResponseEntity<T> response = restTemplate.postForEntity(url, requestEntity, responseType);
return response.getBody();
}
/**
* 创建请求头
* @param headers 请求头Map
* @return HttpHeaders对象
*/
private HttpHeaders createHeaders(Map<String, String> 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<String, Object> params = new HashMap<>();
params.put("groupId", groupId);
params.put("files", file);
Map<String, String> 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<String, String> 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<String, Object> params = new HashMap<>();
params.put("groupId", groupId);
params.put("inprogressList", inprogressList);
Map<String, String> 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<String, String> 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<String, String> 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<String, String> 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. 添加接口调用的单元测试和集成测试