From 8c1dfd258634fb316376a64f32ba31aa79138a02 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Wed, 4 Mar 2026 15:51:10 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E5=88=86=E6=9E=90=E6=8E=A5=E5=8F=A3=E6=9B=B4=E6=96=B0=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2026-03-04-lsfx-interface-update-design.md | 585 ++++++++++++++++++ 1 file changed, 585 insertions(+) create mode 100644 doc/design/2026-03-04-lsfx-interface-update-design.md diff --git a/doc/design/2026-03-04-lsfx-interface-update-design.md b/doc/design/2026-03-04-lsfx-interface-update-design.md new file mode 100644 index 0000000..1726197 --- /dev/null +++ b/doc/design/2026-03-04-lsfx-interface-update-design.md @@ -0,0 +1,585 @@ +# 流水分析接口功能更新设计文档 + +**文档版本**: v1.0 +**创建日期**: 2026-03-04 +**作者**: Claude Code +**状态**: 已批准 + +--- + +## 1. 项目背景和需求分析 + +### 1.1 背景 + +根据最新的接口文档 `assets/对接流水分析/兰溪-流水分析对接3.md`,需要对现有的流水分析对接模块(ccdi-lsfx)进行更新。当前实现包含5个接口,缺少2个关键接口。 + +### 1.2 需求 + +**主要需求:** +1. 新增2个缺失的接口(获取单个文件上传状态、删除文件) +2. 更新所有现有接口以匹配最新文档规范 +3. 保持与Mock Server的兼容性(使用当前配置) +4. 完善参数校验和错误处理 + +**当前实现状态:** +- ✅ 已实现: getToken, uploadFile, fetchInnerFlow, checkParseStatus, getBankStatement (5个) +- ❌ 缺失: getFileUploadStatus, deleteFiles (2个) + +--- + +## 2. 架构设计 + +### 2.1 整体架构 + +``` +ccdi-lsfx模块 +├── client/ +│ └── LsfxAnalysisClient.java (添加2个新方法,更新现有方法) +├── controller/ +│ └── LsfxTestController.java (添加2个测试接口,更新现有接口) +├── domain/ +│ ├── request/ +│ │ ├── GetFileUploadStatusRequest.java (新增) +│ │ ├── DeleteFilesRequest.java (新增) +│ │ └── FetchInnerFlowRequest.java (更新) +│ └── response/ +│ ├── GetFileUploadStatusResponse.java (新增) +│ └── DeleteFilesResponse.java (新增) +├── constants/ +│ └── LsfxConstants.java (添加新常量) +├── util/ +│ └── HttpUtil.java (添加GET请求支持) +└── config/ (通过application.yml配置) +``` + +### 2.2 模块职责 + +| 层级 | 职责 | 变更 | +|------|------|------| +| Controller | 接口暴露、参数校验、响应封装 | 新增2个接口,更新3个接口 | +| Client | 业务逻辑封装、API调用 | 新增2个方法,更新4个方法 | +| Domain | 数据传输对象定义 | 新增4个DTO类 | +| Util | HTTP请求工具 | 新增GET方法 | +| Constants | 常量定义 | 新增固定值和状态常量 | +| Config | 配置管理 | 新增2个endpoint配置 | + +--- + +## 3. 数据模型设计 + +### 3.1 新增Request DTO + +#### 3.1.1 GetFileUploadStatusRequest (接口5) + +```java +@Data +public class GetFileUploadStatusRequest { + /** 项目ID (必填) */ + private Integer groupId; + + /** 文件ID (可选,不传则查询所有) */ + private Integer logId; +} +``` + +**说明:** +- `groupId`: 必填,从getToken接口获取 +- `logId`: 可选,不传则查询项目下所有文件 + +#### 3.1.2 DeleteFilesRequest (接口6) + +```java +@Data +public class DeleteFilesRequest { + /** 项目ID (必填) */ + private Integer groupId; + + /** 文件ID数组 (必填) */ + private Integer[] logIds; + + /** 用户柜员号 (必填) */ + private Integer userId; +} +``` + +**说明:** +- `logIds`: 支持批量删除,传递文件ID数组 +- `userId`: 用于权限验证和审计 + +### 3.2 新增Response DTO + +#### 3.2.1 GetFileUploadStatusResponse (接口5) + +```java +@Data +public class GetFileUploadStatusResponse { + private String code; + private String status; + private Boolean successResponse; + private FileUploadStatusData data; + + @Data + public static class FileUploadStatusData { + /** 日志列表 */ + private List logs; + + /** 状态 */ + private String status; + + /** 账号ID */ + private Integer accountId; + + /** 币种 */ + private String currency; + } + + @Data + public static class LogItem { + // 完整字段定义见实施文档 + // 关键字段: + private List enterpriseNameList; // 主体名称列表 + private List accountNoList; // 账号列表 + private Integer status; // 状态值(-5表示成功) + private String uploadStatusDesc; // 状态描述 + private Integer logId; // 文件ID + } +} +``` + +**关键字段说明:** +- `enterpriseNameList`: 仅有一个空字符串""时,表示未生成主体 +- `status=-5` 且 `uploadStatusDesc="data.wait.confirm.newaccount"` 表示解析成功 + +#### 3.2.2 DeleteFilesResponse (接口6) + +```java +@Data +public class DeleteFilesResponse { + private String code; + private String status; + private Boolean successResponse; + private DeleteFilesData data; + private String message; + + @Data + public static class DeleteFilesData { + /** 删除成功消息 */ + private String message; + } +} +``` + +### 3.3 更新现有DTO + +#### 3.3.1 FetchInnerFlowRequest (接口3) + +```java +@Data +public class FetchInnerFlowRequest { + // ... 现有字段 ... + + /** 校验码 (新增,固定值"ZJRCU") */ + private String dataChannelCode; + + // ... 其他字段 ... +} +``` + +### 3.4 常量定义 + +```java +public class LsfxConstants { + // 固定值常量 + public static final String DEFAULT_USER_ID = "902001"; + public static final String DEFAULT_USER_NAME = "902001"; + public static final String DEFAULT_APP_ID = "remote_app"; + public static final String DEFAULT_ROLE = "VIEWER"; + public static final String DEFAULT_ANALYSIS_TYPE = "-1"; + public static final String DEFAULT_ORG_CODE = "902000"; + public static final String DEFAULT_DEPARTMENT_CODE = "902000"; + public static final String DEFAULT_DATA_CHANNEL_CODE = "ZJRCU"; + + // 状态常量 + public static final Integer PARSE_STATUS_SUCCESS = -5; + public static final String PARSE_STATUS_DESC_SUCCESS = "data.wait.confirm.newaccount"; +} +``` + +--- + +## 4. 接口详细设计 + +### 4.1 新增接口 + +#### 4.1.1 接口5: 获取单个文件上传状态 + +**接口信息:** +- 路径: `/watson/api/project/bs/upload` +- 方法: GET +- 请求头: `X-Xencio-Client-Id` + +**请求参数:** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| groupId | Integer | 是 | 项目ID | +| logId | Integer | 否 | 文件ID(不传则查询所有) | + +**成功标识:** +- `status = -5` +- `uploadStatusDesc = "data.wait.confirm.newaccount"` + +**使用场景:** +- 文件解析完成后获取主体名称和账号 +- 判断是否需要生成主体(`enterpriseNameList`为空字符串) + +#### 4.1.2 接口6: 删除文件 + +**接口信息:** +- 路径: `/watson/api/project/batchDeleteUploadFile` +- 方法: POST +- 请求头: `X-Xencio-Client-Id` +- Content-Type: multipart/form-data + +**请求参数:** +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| groupId | Integer | 是 | 项目ID | +| logIds | Integer[] | 是 | 文件ID数组 | +| userId | Integer | 是 | 用户柜员号 | + +**使用场景:** +- 文件解析失败后清理文件 +- 删除错误上传的文件 +- 批量删除不需要的文件 + +### 4.2 更新现有接口 + +#### 4.2.1 接口1: getToken + +**更新内容:** +- 添加固定值默认值处理 +- 简化必填参数校验 + +**默认值设置:** +```java +userId: "902001" (如果未传) +userName: "902001" (如果未传) +role: "VIEWER" (如果未传) +analysisType: "-1" (如果未传) +``` + +#### 4.2.2 接口3: fetchInnerFlow + +**更新内容:** +- 添加 `dataChannelCode` 字段 +- 默认值: "ZJRCU" + +#### 4.2.3 接口4: checkParseStatus + +**更新内容:** +- 完善方法注释,添加轮询说明 +- 明确成功状态码判断逻辑 + +**轮询说明:** +``` +建议轮询间隔: 1秒 +成功条件: parsing=false 且 status=-5 且 uploadStatusDesc="data.wait.confirm.newaccount" +``` + +#### 4.2.4 接口2,5,7 + +**更新内容:** +- 完善Swagger文档注释 +- 添加状态常量说明 + +--- + +## 5. 完整调用流程 + +### 5.1 标准流程图 + +``` +开始 + ↓ +1. getToken - 创建项目获取Token + 返回: token, projectId + ↓ +2a. uploadFile - 上传文件 + 或 +2b. fetchInnerFlow - 拉取行内流水 + 返回: logId列表 + ↓ +3. checkParseStatus - 检查解析状态(轮询) + 建议: 每隔1秒轮询,直到parsing=false + ↓ +4. 判断解析结果 + ├─ 成功(status=-5 且 desc="data.wait.confirm.newaccount") + │ ↓ + │ 5. getFileUploadStatus - 获取文件状态(可选) + │ 返回: enterpriseNameList, accountNoList + │ ↓ + │ 6. getBankStatement - 获取银行流水 + │ 返回: bankStatementList + │ ↓ + │ 结束(成功) + │ + └─ 失败(status != -5) + ↓ + 7. deleteFiles - 删除文件 + 返回: 删除成功消息 + ↓ + 结束(失败) +``` + +### 5.2 典型调用示例 + +#### 示例1: 文件上传流程 + +```bash +# 1. 获取Token +POST /lsfx/test/getToken +{ + "projectNo": "902000_1709907600000", + "entityName": "902000_202603041430" +} + +# 响应: projectId=16238 + +# 2. 上传文件 +POST /lsfx/test/uploadFile +groupId=16238, file=银行流水.csv + +# 响应: logId=19135 + +# 3. 检查解析状态(轮询) +POST /lsfx/test/checkParseStatus +groupId=16238, inprogressList=19135 + +# 响应: parsing=false, status=-5 + +# 4. 获取文件状态 +GET /lsfx/test/getFileUploadStatus +groupId=16238, logId=19135 + +# 响应: enterpriseNameList=["张三"], accountNoList=["1234567890"] + +# 5. 获取银行流水 +POST /lsfx/test/getBankStatement +{ + "groupId": 16238, + "logId": 19135, + "pageNow": 1, + "pageSize": 100 +} +``` + +#### 示例2: 解析失败处理流程 + +```bash +# 前面步骤相同... + +# 3. 检查解析状态 +响应: parsing=false, status=-1, uploadStatusDesc="data.parse.error" + +# 4. 删除文件 +POST /lsfx/test/deleteFiles +{ + "groupId": 16238, + "logIds": [19135], + "userId": 902001 +} +``` + +--- + +## 6. 测试计划 + +### 6.1 单元测试用例 + +| ID | 测试场景 | 测试接口 | 测试数据 | 预期结果 | +|----|---------|---------|---------|---------| +| UT01 | 获取Token-成功 | getToken | 完整必填参数 | code=200, 返回token | +| UT02 | 获取Token-缺少参数 | getToken | 缺少projectNo | 返回错误提示 | +| UT03 | 上传文件-成功 | uploadFile | groupId, 有效CSV | code=200, 返回logId | +| UT04 | 上传文件-文件过大 | uploadFile | 超过10MB文件 | 返回文件超限错误 | +| UT05 | 拉取流水-成功 | fetchInnerFlow | customerNo, 日期范围 | code=200, 返回logId列表 | +| UT06 | 拉取流水-日期错误 | fetchInnerFlow | 开始>结束日期 | 返回日期错误提示 | +| UT07 | 检查状态-解析中 | checkParseStatus | 刚上传的文件 | parsing=true | +| UT08 | 检查状态-完成 | checkParseStatus | 解析完成的文件 | parsing=false, status=-5 | +| UT09 | 获取文件状态-单个 | getFileUploadStatus | groupId, logId | 返回文件状态信息 | +| UT10 | 获取文件状态-全部 | getFileUploadStatus | groupId, 不传logId | 返回所有文件状态 | +| UT11 | 删除文件-成功 | deleteFiles | groupId, logIds, userId | code=200, message=success | +| UT12 | 删除文件-缺少logIds | deleteFiles | 空logIds数组 | 返回错误提示 | +| UT13 | 获取流水-分页 | getBankStatement | pageNow=1, pageSize=10 | 返回10条记录 | + +### 6.2 集成测试场景 + +**场景1: 完整文件上传流程** +``` +getToken → uploadFile → checkParseStatus(轮询) → getFileUploadStatus → getBankStatement +``` + +**场景2: 完整行内流水流程** +``` +getToken → fetchInnerFlow → checkParseStatus(轮询) → getFileUploadStatus → getBankStatement +``` + +**场景3: 解析失败处理流程** +``` +uploadFile(错误文件) → checkParseStatus(失败) → deleteFiles +``` + +**场景4: 边界条件测试** +- 大文件上传(接近10MB) +- 大量数据分页获取(pageSize=1000) +- 并发多个文件上传 + +### 6.3 Mock Server测试 + +**需要更新的Mock接口:** +- `GET /watson/api/project/bs/upload` - 返回模拟文件状态 +- `POST /watson/api/project/batchDeleteUploadFile` - 返回删除成功消息 + +--- + +## 7. 实施计划 + +### 7.1 实施阶段 + +**阶段一: 数据模型层 (1小时)** +- 创建4个新DTO类 +- 更新1个现有DTO +- 更新常量类 + +**阶段二: 工具类增强 (30分钟)** +- 扩展HttpUtil支持GET请求 + +**阶段三: 客户端层 (1.5小时)** +- 新增2个Client方法 +- 更新4个现有方法 + +**阶段四: 控制器层 (1小时)** +- 新增2个Controller接口 +- 更新3个现有接口 + +**阶段五: 配置更新 (15分钟)** +- 更新application-dev.yml + +**阶段六: Mock Server更新 (30分钟)** +- 更新Python Mock Server + +**阶段七: 测试验证 (1小时)** +- 单元测试 +- 集成测试 +- Swagger文档测试 + +**阶段八: 文档编写 (30分钟)** +- API文档 +- 测试报告 + +**总计: 约6小时** + +### 7.2 文件清单 + +**新增文件 (8个):** +``` +ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/request/ +├── GetFileUploadStatusRequest.java +└── DeleteFilesRequest.java + +ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/ +├── GetFileUploadStatusResponse.java +└── DeleteFilesResponse.java + +doc/ +├── api-docs/lsfx-api-v3.md +├── design/2026-03-04-lsfx-interface-update-design.md +└── test-scripts/lsfx-test-report-20260304.md +``` + +**修改文件 (7个):** +``` +ccdi-lsfx/src/main/java/com/ruoyi/lsfx/ +├── client/LsfxAnalysisClient.java +├── controller/LsfxTestController.java +├── constants/LsfxConstants.java +├── util/HttpUtil.java +└── domain/request/FetchInnerFlowRequest.java + +ruoyi-admin/src/main/resources/ +└── application-dev.yml + +lsfx-mock-server/ +└── app.py +``` + +--- + +## 8. 风险分析 + +### 8.1 技术风险 + +| 风险项 | 影响 | 概率 | 缓解措施 | +|--------|------|------|---------| +| GET请求参数传递方式不明确 | 中 | 低 | 参考文档示例,进行实际测试 | +| 数组参数传递格式问题 | 中 | 中 | 查阅HTTP规范,使用正确的传递方式 | +| 状态码判断逻辑错误 | 高 | 低 | 严格按文档实现,添加详细日志 | + +### 8.2 兼容性风险 + +| 风险项 | 影响 | 概率 | 缓解措施 | +|--------|------|------|---------| +| 现有接口调用者受影响 | 中 | 低 | 保持接口签名兼容,只增加功能 | +| 配置变更需要重启 | 低 | 高 | 在文档中明确说明 | + +### 8.3 测试风险 + +| 风险项 | 影响 | 概率 | 缓解措施 | +|--------|------|------|---------| +| Mock数据与真实接口不一致 | 中 | 中 | 严格按照文档构造Mock响应 | +| 边界条件未覆盖 | 中 | 中 | 设计全面的测试用例 | + +--- + +## 9. 验收标准 + +### 9.1 功能验收 + +- ✅ 所有7个接口都能正常调用 +- ✅ 参数校验正确(必填、格式、范围) +- ✅ 响应格式符合文档定义 +- ✅ 错误处理完善(异常捕获、日志记录) + +### 9.2 代码质量 + +- ✅ 遵循项目编码规范 +- ✅ 代码注释完整清晰 +- ✅ 日志记录完善 +- ✅ 无明显的性能问题 + +### 9.3 文档完整性 + +- ✅ API文档完整 +- ✅ 测试报告完整 +- ✅ 设计文档已保存 + +--- + +## 10. 附录 + +### 10.1 参考资料 + +- `assets/对接流水分析/兰溪-流水分析对接3.md` - 最新接口文档 +- `CLAUDE.md` - 项目开发规范 +- Spring Boot 3 文档 +- MyBatis Plus 文档 + +### 10.2 变更历史 + +| 版本 | 日期 | 作者 | 变更内容 | +|------|------|------|---------| +| v1.0 | 2026-03-04 | Claude Code | 初始版本 | + +--- + +**文档结束**