Implement credit parse result polling and sentinel handling

This commit is contained in:
wkc
2026-05-18 10:56:25 +08:00
parent 9917d10e59
commit 1fadb38d99
25 changed files with 918 additions and 81 deletions

View File

@@ -196,7 +196,7 @@
| `uncle_bank_consume` | 银行 | 消费贷款 | 银行 | 未结清银行消费贷款 |
| `uncle_bank_other` | 银行 | 其他贷款 | 银行 | 未结清银行其他贷款 |
| `uncle_not_bank` | 非银 | 非银行贷款 | 非银 | 未结清非银行贷款 |
| `uncle_credit_cart` | 银行 | 信用卡 | 银行 | 未结清信用卡 |
| `uncle_credit_card` | 银行 | 信用卡 | 银行 | 未结清信用卡 |
字段映射规则:
@@ -206,6 +206,7 @@
落库过滤规则:
- 当某组 `*_state``-9999` 时,表示不存在该类型负债,不生成明细记录
- 当某组 `principal_balance``debt_total_amount` 都为空或 `0`,且 `debt_status` 为空时,不生成明细记录
- 其余情况生成一条明细
@@ -220,6 +221,8 @@
- `enforce_lmt` -> `enforce_lmt`
- `adm_lmt` -> `adm_lmt`
负面风险字段值为 `-9999``-9999.0` 时,表示不存在对应风险类型;次数按 `0` 处理,金额按空值处理。
## 10. 最新征信判定与覆盖策略
系统只保留员工最新征信,规则如下:

View File

@@ -0,0 +1,35 @@
# 征信解析双接口与结果轮询后端实施计划
## 背景
根据 `天座征信解析接口文档.xlsx`,征信解析需要拆分为发起接口和结果接口:先通过 `/api/service/interface/invokeService/xfeature` 提交 HTML 远程地址,再通过 `/api/service/interface/invokeService/xfeatureResult` 按同一业务流水号查询解析结果。
## 实施内容
1. 后端客户端
- 保持 `CreditParseClient.parse(remotePath)``parse(model, remotePath)` 对外签名不变。
- 内部生成同一个 `serialNum`,发起接口提交 `serialNum/orgCode/runType/remotePath/model`
- 结果接口提交 `serialNum/orgCode/runType`,最多查询 5 次,每次间隔 2 秒。
- 外层严格校验 `success=true``code=10000`,业务层严格校验 `status_code=0`
- 仅当结果未就绪或 `payload` 为空时继续轮询,明确业务失败立即返回失败原因。
2. 配置
- 保留 `credit-parse.api.url` 作为发起接口地址。
- 新增 `credit-parse.api.result-url` 作为结果接口地址。
- `dev/uat/nas/pro` 环境 `credit-parse.api.org-code` 统一调整为 `999000`
3. Mock 服务
- `/xfeature` 读取 `remotePath` 生成 payload`serialNum` 暂存结果,只返回发起成功结构。
- `/xfeatureResult``serialNum` 返回暂存 payload未知流水号返回业务失败。
4. 征信维护落库
- 上传入口、HTML 落盘、`remotePath` 拼接、页面接口均保持不变。
- 原有落库逻辑继续读取最终结果中的 `lx_header/lx_debt/lx_publictype`
## 验证计划
- `mvn -pl ccdi-lsfx -Dtest=CreditParseControllerTest test`
- `mvn -pl ccdi-info-collection -am -Dtest=CcdiCreditInfoServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test`
- `mvn -pl ccdi-lsfx,ccdi-info-collection -am compile`
- `cd lsfx-mock-server && pytest tests/test_credit_api.py tests/test_startup.py -q`

View File

@@ -0,0 +1,56 @@
# 征信解析双接口与结果轮询实施记录
## 背景
本次按 `天座征信解析接口文档.xlsx` 调整征信解析调用方式:由单次发起接口直接获取 `payload`,改为发起接口 `/api/service/interface/invokeService/xfeature` 加结果接口 `/api/service/interface/invokeService/xfeatureResult` 的两步调用。
## 修改内容
1. `CreditParseClient`
- 保持原有 `parse` 方法签名不变。
- 发起接口提交 `serialNum/orgCode/runType/remotePath/model`
- 结果接口使用同一 `serialNum` 提交 `serialNum/orgCode/runType`
- 结果接口最多轮询 5 次,每次间隔 2 秒。
- 严格校验外层 `success=true``code=10000` 和业务层 `status_code=0`
2. 配置
- `application-dev.yml``application-uat.yml``application-nas.yml``application-pro.yml` 新增 `credit-parse.api.result-url`
- 上述环境的 `credit-parse.api.org-code` 统一调整为 `999000`
3. `CcdiCreditInfoServiceImpl`
- 征信维护落库前补充外层 `code=10000` 校验。
- 上传入口、HTML 保存、`remotePath` 生成和落库字段映射保持不变。
4. `lsfx-mock-server`
- `/xfeature` 改为发起接口,只暂存结果并返回发起成功结构。
- 新增 `/xfeatureResult`,按 `serialNum` 返回暂存 payload。
- Mock README 和启动路由说明同步更新。
5. 测试
- Java 测试补充同一 `serialNum` 双接口调用、5 次轮询、2 秒间隔和外层状态码校验。
- Mock 测试补充发起接口、结果接口、缺参、未知流水号和 payload 返回。
## 影响范围
- 影响征信解析客户端、征信维护上传后的解析调用、征信解析 Mock 服务和相关环境配置。
- 不涉及前端页面、前端 API、数据库表结构和业务 payload 字段变更。
## 验证
- `mvn -pl ccdi-lsfx -Dtest=CreditParseControllerTest test`通过6 个用例成功。
- `mvn -pl ccdi-info-collection -am -Dtest=CcdiCreditInfoServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test`通过4 个用例成功。
- `mvn -pl ccdi-lsfx,ccdi-info-collection -am compile`:通过。
- `cd lsfx-mock-server && python3 -m pytest tests/test_credit_api.py tests/test_startup.py -q`通过9 个用例成功。
- `git diff --check`:通过。
- 后端联调:
- 启动 `lsfx-mock-server`,并通过 `bin/restart_java_backend.sh restart` 重启后端。
- 调用 `/login/test` 获取测试令牌后,通过 `/ccdi/creditInfo/upload` 上传本轮 HTML 测试文件。
- 上传结果:`totalCount=1``successCount=1``failureCount=0`
- 列表按身份证号 `330781199001019914` 查询到 1 条征信记录。
- 后端日志确认同一个 `serialNum` 先调用 `/api/service/interface/invokeService/xfeature`,再调用 `/api/service/interface/invokeService/xfeatureResult`
- 调用删除接口清理本轮测试数据,回查列表 `total=0`
- 本轮启动的 mock 和后端进程已关闭。
- 浏览器验证说明:
- 已使用 browser-use 打开本地前端并完成登录。
- 后端重启后,浏览器旧登录态触发接口 500且 browser-use 安全策略阻止通过 `javascript:` URL 清理本地状态,因此未继续执行页面上传动作。
- 已改用真实后端接口完成上传、落库、日志和清理闭环验证。

View File

@@ -0,0 +1,30 @@
# 征信解析信用卡字段前缀调整实施记录
## 背景
征信解析负债字段中,信用卡字段前缀需要由 `uncle_credit_cart_*` 调整为 `uncle_credit_card_*`,保持字段命名与信用卡含义一致。
## 修改内容
1. 后端字段装配
- `CreditInfoPayloadAssembler` 中信用卡负债映射前缀由 `uncle_credit_cart` 调整为 `uncle_credit_card`
2. Mock 字段生成
- `lsfx-mock-server/config/credit_feature_schema.json` 中信用卡字段同步调整为:
- `uncle_credit_card_bal`
- `uncle_credit_card_lmt`
- `uncle_credit_card_state`
3. 文档
- `docs/design/2026-03-23-credit-info-maintenance-design.md` 中信用卡字段前缀同步调整。
## 影响范围
- 仅影响征信解析 payload 中信用卡负债字段的读取与本地 Mock 生成字段。
- 不涉及接口成功判断、数据库结构、前端页面和其他负债类型。
## 验证
- `mvn -pl ccdi-info-collection -am -Dtest=CreditInfoPayloadAssemblerTest,CcdiCreditInfoServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test`通过10 个用例成功。
- `cd lsfx-mock-server && python3 -m pytest tests/test_credit_api.py tests/test_startup.py -q`通过9 个用例成功。
- `git diff --check`:通过。

View File

@@ -0,0 +1,36 @@
# 征信解析缺失标记过滤实施记录
## 背景
征信解析返回中,负债字段的 `*_state` 若为 `-9999`,表示不存在该类型负债;负面风险字段中 `-9999``-9999.0` 也表示不存在对应风险类型,不能按真实负债或负面风险指标落库。
## 修改内容
1. 负债明细装配
- `CreditInfoPayloadAssembler` 中新增 `-9999` 缺失标记识别。
- 当某组负债的 `*_state``-9999` 时,直接跳过该负债类型,不生成 `ccdi_debts_info` 明细。
- 数值和状态转换过程中同步将 `-9999` 视为空值,避免缺失标记落库。
2. 负面风险装配
- `lx_publictype` 中次数字段为 `-9999` 时按 `0` 处理。
- `lx_publictype` 中金额字段为 `-9999``-9999.0` 时按空值处理。
3. 测试
- 补充 `*_state=-9999` 时跳过负债类型的单测。
- 补充负面风险 `-9999` 转换为 `0/null` 的单测。
4. 文档
- 更新 `docs/design/2026-03-23-credit-info-maintenance-design.md` 中负债过滤和负面风险缺失值规则。
## 影响范围
- 仅影响征信解析 payload 到负债明细、负面风险表的装配逻辑。
- 不涉及接口调用、成功判断、数据库结构和前端页面。
## 验证
- `mvn -pl ccdi-info-collection -am -Dtest=CreditInfoPayloadAssemblerTest,CcdiCreditInfoServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test`通过10 个用例成功。
- `git diff --check`:通过。
- 使用 `/Users/wkc/Downloads/zxjx.txt` 按当前规则复核:
- 负债明细仅保留 `uncle_bank_manage``uncle_not_bank` 两类。
- 负面风险 `civil/enforce/adm``-9999` 均按无对应风险处理。

View File

@@ -0,0 +1,39 @@
# 征信解析发起接口成功判断调整实施记录
## 背景
联调日志显示,征信解析发起接口 `/api/service/interface/invokeService/xfeature` 已返回外层 `success=true``code=10000`,并在 `data.mappingOutputFields.message` 中返回“文件写入成功,流水号为...”。但系统仍按结果接口的 `mappingOutputFields.status_code=0` 判断发起接口成功,导致“文件写入成功”被误判为失败,后续结果接口未继续查询。
## 修改内容
1. `CreditParseClient`
- 发起接口改为校验外层 `success=true``code=10000`,并校验发起层 `data.status=1``data.reasonCode=200`
- 结果接口改为与发起接口一致,校验外层 `success=true``code=10000`,并校验 `data.status=1``data.reasonCode=200`
- `mappingOutputFields.status_code` 不再作为 `/xfeatureResult` 是否成功的判断条件;结果接口返回成功后,仅通过 `payload` 是否为空判断是否继续轮询。
- 接口异常时优先返回 `reasonMessage`,其次返回 `mappingOutputFields.message`
2. 响应对象
- `CreditParseInvokeData` 新增 `status``reasonCode``reasonMessage` 字段。
-`data` 层开启未知字段忽略,适配发起接口返回的 `traceId``procCode``bizId` 等额外字段。
3. Mock 与文档
- `lsfx-mock-server` 发起接口和结果接口成功返回均补充 `status=1``reasonCode=200`
- Mock README 示例同步更新。
4. 测试
- Java 单测改为使用发起接口真实成功结构。
- 新增发起接口 `status/reasonCode` 失败时不继续查询结果接口的断言。
- Java 单测增加 `/xfeatureResult` 返回 `status_code` 非 0 但 `status/reasonCode` 成功时仍继续落库的覆盖。
- Mock 测试同步校验发起接口和结果接口的 `data.status=1``data.reasonCode=200`
## 影响范围
- 仅影响征信解析双接口调用链的成功判断与本地 Mock 返回结构。
- 不涉及前端页面、数据库结构、征信 payload 字段映射和落库逻辑。
## 验证
- `mvn -pl ccdi-lsfx -Dtest=CreditParseControllerTest test`通过8 个用例成功。
- `mvn -pl ccdi-info-collection -am -Dtest=CcdiCreditInfoServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test`通过5 个用例成功。
- `cd lsfx-mock-server && python3 -m pytest tests/test_credit_api.py tests/test_startup.py -q`通过9 个用例成功。
- `git diff --check`:通过。