# 征信解析客户端与接口设计方案 ## 1. 背景 本次需求来自以下两份输入材料: - `assets/征信解析/HTML引擎服务_ 接口设计说明书_1.docx` - `assets/征信解析/征信解析接口payload.xlsx` 根据说明书,本次目标外部接口为 `POST /xfeature-mngs/conversation/htmlEval`,请求格式为 `multipart/form-data`,核心入参为: - `model` - `file` - `hType` 返回体结构为: - `message` - `status_code` - `payload` 根据 Excel,`payload` 当前至少包含以下三个主题域对象: - `lx_header` - `lx_debt` - `lx_publictype` 当前仓库中已有银行流水分析平台的集成代码,集中在 `ccdi-lsfx` 模块;但征信解析服务与流水分析平台不是同一套接口语义和配置边界。本次目标是在不破坏现有 `lsfx` 链路的前提下,新增一套独立的征信解析调用能力,并在 `ccdi-lsfx` 中暴露一个可供联调使用的后端接口。 ## 2. 目标 - 在 `ccdi-lsfx` 模块中新增独立的征信解析 `Client`。 - 在 `ccdi-lsfx` 模块中新增对外联调接口,用于接收 HTML 文件并调用征信解析服务。 - 征信解析配置与现有 `lsfx` 配置完全隔离,不共用同一配置前缀。 - 配置项使用单一完整 URL,不拆分 `base-url` 和 `endpoints`。 - 外部服务成功响应时,保留 `message`、`status_code`、`payload` 的原始语义。 - 控制器仅做最小参数校验,不额外引入项目上传记录、异步任务、状态轮询或结果落库。 ## 3. 非目标 - 不接入 `ccdi-project` 现有项目文件上传主链路。 - 不新增征信解析结果落库逻辑。 - 不补充前端页面接入。 - 不把征信解析 `Client` 并入现有 `LsfxAnalysisClient`。 - 不将征信解析配置挂到 `lsfx.api.*` 下。 - 不额外设计说明书之外的兜底流程、降级流程或兼容协议。 ## 4. 方案对比 ### 4.1 方案 A:直接扩展现有 `LsfxAnalysisClient` 把征信解析方法直接加到现有 `LsfxAnalysisClient`,并继续使用 `lsfx.api.*` 配置。 优点: - 改动文件数最少。 缺点: - 语义上把两套不同外部服务混在同一个 Client 中。 - 配置边界不清晰,后续切换环境容易误改现有流水分析配置。 - 不符合本次“新增 Client,并在配置文件里与 lsfx 分开”的要求。 ### 4.2 方案 B:在 `ccdi-lsfx` 中新增独立 `CreditParseClient` 在 `ccdi-lsfx` 中新增独立控制器和独立 `Client`,并使用新的配置前缀承载完整 URL。 优点: - 满足“接口加在 `ccdi-lsfx` 中”的要求。 - 满足“新增 Client,在配置文件里与 lsfx 分开”的要求。 - 与现有银行流水分析集成边界清晰,不会污染主链路。 - 仍然复用现有 `HttpUtil`,实现路径最短。 缺点: - 需要新增少量类和配置项。 ### 4.3 方案 C:在 `ccdi-project` 中直接暴露业务接口并自行发起调用 由 `ccdi-project` 新增控制器和 service,直接使用 `RestTemplate` 调征信解析平台。 优点: - 对业务模块看起来更直接。 缺点: - 与用户已确认的“接口加在 `ccdi-lsfx` 中”不一致。 - 会把外部平台调用能力分散到多个模块。 - 后续复用和维护成本更高。 ## 5. 推荐方案 采用方案 B:在 `ccdi-lsfx` 中新增独立 `CreditParseClient`、独立配置和独立联调接口。 推荐原因: - 与已确认需求完全一致。 - 保持最短路径实现,不引入无关业务改造。 - 外部服务边界清晰,后续如果还要补企业征信或更多解析接口,可以继续沿用这一结构。 ## 6. 模块边界与目录设计 本次改动集中在 `ccdi-lsfx` 模块。 建议落点如下: - `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/controller/CreditParseController.java` - `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/client/CreditParseClient.java` - `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/CreditParseResponse.java` - `ccdi-lsfx/src/main/java/com/ruoyi/lsfx/domain/response/CreditParsePayload.java` - `ruoyi-admin/src/main/resources/application-dev.yml` - `ruoyi-admin/src/main/resources/application-nas.yml` 职责划分如下: - `CreditParseController` - 接收联调方上传的 HTML 文件和可选参数。 - 做最小参数校验。 - 将 `MultipartFile` 转换为临时文件。 - 调用 `CreditParseClient`。 - 返回 `AjaxResult`。 - `CreditParseClient` - 读取独立配置中的完整 URL。 - 组装 `multipart/form-data` 参数。 - 调用现有 `HttpUtil.uploadFile(...)`。 - 统一记录调用日志和抛出平台调用异常。 - `CreditParseResponse` - 映射外部接口返回的 `message`、`status_code`、`payload`。 - `CreditParsePayload` - 承载 `lx_header`、`lx_debt`、`lx_publictype` 三个主题域对象。 ## 7. 配置设计 征信解析配置独立于 `lsfx`,使用新的配置前缀。 建议配置结构如下: ```yml credit-parse: api: url: http://64.202.94.120:8081/xfeature-mngs/conversation/htmlEval ``` 说明: - `url` 保存单一完整地址,不拆分为 `base-url` 和 `endpoints`。 - 不复用 `lsfx.api.connection-timeout`、`lsfx.api.read-timeout` 等配置项。 - 本次实现优先沿用现有 `RestTemplate` Bean;若后续确需独立超时配置,再单独扩展专用 HTTP 配置,不在本次设计中预埋。 ## 8. 对外接口设计 ### 8.1 接口定义 - 方法:`POST` - 路径:`/lsfx/credit/parse` - Content-Type:`multipart/form-data` 接口放在 `ccdi-lsfx` 模块中,作为征信解析联调入口。 ### 8.2 请求参数 | 参数名 | 类型 | 必填 | 默认值 | 说明 | | ------ | ---- | ---- | ------ | ---- | | `file` | `MultipartFile` | 是 | 无 | 征信 HTML 文件 | | `model` | `String` | 否 | `LXCUSTALL` | 主题域编码 | | `hType` | `String` | 否 | `PERSON` | 报文类型 | ### 8.3 本地校验规则 控制器层只做最小必要校验: - `file` 不能为空。 - 文件名不能为空。 - 文件后缀必须为 `.html` 或 `.htm`。 - `model` 为空时补默认值 `LXCUSTALL`。 - `hType` 为空时补默认值 `PERSON`。 不在控制器层重复实现外部平台业务码校验,不提前限制: - `model` 是否只能取 `LXCUSTALL` - `hType` 是否只能取 `PERSON` 或 `ENTERPRISE` 上述业务校验结果以外部服务返回的 `status_code` 为准。 ### 8.4 返回规则 返回采用若依标准 `AjaxResult` 包装,规则如下: - 本地参数校验失败:返回 `AjaxResult.error(...)` - 外部调用成功拿到响应:返回 `AjaxResult.success(responseBody)` - 网络异常、超时、反序列化异常或其他调用异常:返回 `AjaxResult.error("征信解析调用失败:" + e.getMessage())` 其中 `AjaxResult.data` 中保留外部原始业务语义,例如: ```json { "code": 200, "msg": "操作成功", "data": { "message": "成功", "status_code": "0", "payload": { "lx_header": {}, "lx_debt": {}, "lx_publictype": {} } } } ``` 这意味着: - 外部业务失败码如 `ERR_99999`、`ERR_10002` 仍然作为正常 HTTP 调用结果返回。 - 调用方根据 `data.status_code` 判断业务成功与否。 - 本地接口不对外部业务码做二次翻译,避免语义偏移。 ## 9. Client 设计 ### 9.1 调用链 调用链固定为: `CreditParseController` -> `CreditParseClient` -> `HttpUtil.uploadFile(...)` -> 征信解析服务 ### 9.2 请求组装 `CreditParseClient` 发送 `multipart/form-data`,参数仅包含: - `model` - `file` - `hType` 不新增说明书之外的扩展字段。 ### 9.3 URL 读取 `CreditParseClient` 直接读取: - `credit-parse.api.url` 不做 URL 拼接。 ### 9.4 日志 日志风格保持与 `ccdi-lsfx` 现有习惯一致,至少包含: - 请求开始:文件名、`model`、`hType` - 请求结束:耗时、返回 `status_code` - 请求失败:错误信息和异常堆栈 ### 9.5 异常 `CreditParseClient` 统一抛出 `LsfxApiException` 风格异常,保持 `ccdi-lsfx` 模块内部异常语义一致。 ## 10. 响应对象设计 ### 10.1 请求 DTO 本次不新增请求 DTO。 原因: - 控制器直接接收 `MultipartFile file, String model, String hType` 即可。 - `Client` 内部直接构造 `Map` 最短路径实现。 - 纯透传场景下,引入请求 DTO 只会增加样板代码。 ### 10.2 响应 DTO 建议新增以下响应对象: #### `CreditParseResponse` - `String message` - `String statusCode` - `CreditParsePayload payload` 其中 `statusCode` 使用注解映射 JSON 字段 `status_code`。 #### `CreditParsePayload` - `Map lxHeader` - `Map lxDebt` - `Map lxPublictype` 其中字段名使用注解映射: - `lx_header` - `lx_debt` - `lx_publictype` ### 10.3 为何不展开成 30+ 强类型字段 本次目标是“添加调用征信解析接口的方法”,不是“建立完整征信指标领域模型”。因此本次不把 Excel 中的 30 余个字段全部定义为强类型 Java 属性,原因如下: - 当前需求核心是打通调用,不是做复杂业务计算。 - 外部字段后续仍可能调整,强类型化会增加维护成本。 - 三段 `Map` 已足够支撑联调与响应透传。 后续如果业务明确需要对单个字段做服务内计算或落库,再单独收敛更细的领域对象。 ## 11. 文件处理设计 由于现有 `HttpUtil.uploadFile(...)` 接收的是 `File` 对象,控制器层需要把上传的 `MultipartFile` 转为临时文件。 处理规则如下: - 使用系统临时目录创建临时文件。 - 临时文件名保留原始后缀,方便外部服务识别文件类型。 - `Client` 调用结束后,在 `finally` 中删除临时文件。 - 临时文件删除失败只记录日志,不覆盖主流程结果。 该处理仅用于本次同步调用,不沉淀到项目上传目录,不复用 `ccdi-project` 的文件上传记录表。 ## 12. 测试设计 本次测试只覆盖后端最小闭环,不扩展到前端。 建议至少覆盖以下场景: 1. 合法 HTML 文件上传,外部服务返回 `status_code = 0` 2. 文件为空,本地接口直接返回参数错误 3. 文件后缀非法,本地接口直接返回参数错误 4. 外部服务不可达或超时,接口返回调用失败信息 5. 外部服务返回业务失败码,例如 `ERR_99999`,本地接口仍然按成功调用返回 `AjaxResult.success(...)` 如果测试过程中需要临时启动后端进程,测试完成后必须主动关闭,避免残留进程占用端口。 ## 13. 实施边界确认 本次实施只包含以下内容: - 新增 `CreditParseClient` - 新增 `CreditParseController` - 新增征信解析响应对象 - 新增独立配置项 `credit-parse.api.url` - 补充后端测试 本次明确不包含: - `ccdi-project` 主上传链路改造 - 项目上传记录表扩展 - 征信结果落库 - 前端接入 - 额外的兼容性补丁或兜底方案 ## 14. 风险与约束 - 外部服务返回结构以说明书和联调实际为准;若实际返回字段名与说明书不一致,需要在实现阶段按真实返回修正映射。 - 本次沿用现有 `RestTemplate` Bean;若后续征信解析服务需要独立连接池或独立超时,再单独设计,不在本次范围内扩展。 - 由于本次不做落库,调用结果仅用于联调和即时查看。 ## 15. 预期交付物 - 一份后端设计实现代码,落在 `ccdi-lsfx` 模块 - 一份后端实施计划文档,落在 `docs/plans/backend/` - 一份前端实施计划文档,落在 `docs/plans/frontend/`,明确本次无前端实施项 - 一份本次改动实施记录文档,落在 `docs/reports/implementation/` 本方案采用“`ccdi-lsfx` 内新增独立征信解析 Client 与联调接口、配置与 `lsfx` 完全隔离”的方式,以最短路径补齐征信解析调用能力,同时保证与现有银行流水分析链路边界清晰,符合当前需求边界。