feat: 接入新华社工商信息同步

This commit is contained in:
wkc
2026-07-29 17:56:27 +08:00
parent 2bcba71259
commit 5d004a66e8
72 changed files with 2610 additions and 59 deletions

View File

@@ -0,0 +1,62 @@
# 新华社工商信息同步接入实施计划
## 1. 实施目标
接入新华社同步工商接口 `POST /api/service/interface/invokeService/LSFXXHS`,开发环境仅连接本地 FastAPI Mock生产环境连接真实接口。接口响应直接读取 `data.mappingOutputFields`,统一社会信用代码字段固定为 `creditCode`
本次不实现异步结果查询、任务 Key 提取、轮询、结果缓存接口,也不接入 `LSFXXHSstockrelation`
## 2. 接口与日志
- 使用 `application/x-www-form-urlencoded` 提交 `entName``serialNum``orgCode=999000``runType=1`
- `serialNum` 格式为 `CCDI_GS_时间戳_UUID`,仅作为请求流水号。
- 依次校验 HTTP、JSON、外层状态、业务状态、非空结果对象、企业名称和 `creditCode`;任一校验失败均不得写缓存及业务数据。
- 所有外部 HTTP 调用显式携带不可变 `CallerContext`,异步链路沿用原始发起用户。
- 每次实际外呼写入一条 `sys_api_log`;缓存命中不写日志。日志独立事务保存,日志失败不影响业务请求。
- 接口日志仅提供列表和详情,不提供删除、清空或导出。
## 3. 数据与解析
- 新增工商原始响应缓存、实体完整股东、项目对手方企业、项目对手方股东和接口日志表。
- 缓存键为 `TRIM(entName) + EnterpriseProfile`,有效期为成功调用时间后 180 天,`query_result` 保存完整原始 JSON。
- 实体表补充注册资本、注册日期、区域、从业人数、缓存关联和工商同步时间。
- 映射 `creditCode`、注册资本、日期、机构类型、行业、区域、注册地址、从业人数、法定代表人和股东字段。
- `stock_percent` 去除 `%` 后按百分数值保存,`should_capi` 单位固定为“万元”。文档未提供字段不推断。
- `holders` 为空时整体清空旧股东和实体表前五股东字段。
## 4. 实体库同步
- 新增、导入、关系自动补全和名称变更均在原事务提交后异步执行。
- 单批按去除首尾空格后的名称去重,同名只查询一次。
- 仅在返回名称与请求名称一致且返回 `creditCode` 与实体主键完全一致时回写。
- 同名但信用代码不一致的实体不更新;成功缓存保留,历史任务记录为跳过。
- 工商字段、缓存关联、同步时间和 `data_source=API` 在短事务内更新,完整股东整体替换。
- 不覆盖风险等级、企业来源、企业性质、经营状态和业务关系。
## 5. 项目对手方同步
- 流水上传、平台拉取和历史导入在整个批次完成后各触发一次 reconcile。
- 当前项目全部非空对手方名称去重后按每批 100 条处理,外呼共用最大并发数为 3 的专用执行器。
- 按“项目 ID + 对手方名称”更新或新增,信用代码变化时更新同一记录,并事务性替换股东。
- 单项失败保留旧成功数据;批次结束后删除已不在当前流水集合中的项目工商数据。
- 删除流水后基于剩余流水同步;空集合直接清空且不外呼。删除项目时直接删除项目工商数据。
- 项目工商信息与实体库相互隔离。
## 6. API 与页面
- 实体库提供详情刷新、历史补全启动和 Redis 任务状态查询。
- 项目提供对手方详情、单个刷新、历史补全启动和 Redis 任务状态查询。
- 任务状态包含总数、完成数、成功数、跳过数、失败数和最终状态,不新增任务表。
- 实体详情展示新增工商字段和完整股东;仅未同步或缓存过期时显示重新查询。
- 流水对手方名称打开本地工商详情;打开、翻页和普通刷新不得触发外呼。
- 接口日志页面为安静的只读运维表格,详情展示请求、响应和异常原文。
## 7. 实施顺序与验收
1. 执行 `sql/migration/2026-07-29-xinhua-enterprise-profile.sql`,重复执行验证幂等性。
2. 启动 FastAPI Mock、Java 后端和 Vue 前端,开发配置必须指向本地 Mock。
3. 运行 Mock、Java 模块测试和前端生产构建,确认源码不存在 `LSFXXHSResult`
4. 构造信用代码匹配、同名信用代码不匹配、空股东和多股东场景,核对缓存、实体、项目和日志。
5. 使用应用内浏览器验收实体库、流水明细和接口日志真实页面。
6. 清理业务测试数据并关闭本轮启动的前后端及 Mock 进程。
7. 生产先对单个已知企业烟测,确认一次外呼、一条日志、原始缓存、`creditCode` 和股东一致后,再启动历史补全;任何环节失败立即停止上线。

View File

@@ -0,0 +1,70 @@
# 新华社工商信息同步接入实施报告
## 1. 实施结果
已按同步接口契约完成新华社工商信息接入。开发环境通过 FastAPI Mock 联调,生产配置保留真实接口地址;代码、配置和 Mock 均未实现 `LSFXXHSResult``LSFXXHSstockrelation`
## 2. 主要改动
### 外部接口与日志
- `ccdi-lsfx` 新增新华社同步客户端、同步响应模型和不可变 `CallerContext`
- 重构共享 HTTP 工具统一记录调用人、URL、方法、请求头和参数、HTTP 状态、响应头、原始响应、异常堆栈和耗时。
- `sys_api_log` 使用独立事务写入HTTP 200 的业务失败仍按传输成功保存,业务失败信息保留在原始响应中。
- 恢复只读接口日志列表、详情 API 和页面,无删除、清空、导出能力。
### 缓存、解析与实体库
- 新增 180 天成功缓存,缓存保存同步接口完整原始 JSON。
- 新增工商字段解析、实体完整股东表和股东整体替换。
- 实体新增、导入、关系自动补全及名称变化后,在原事务提交后异步同步。
- 单批按企业名称去重,返回 `creditCode` 仅回写主键完全匹配的实体;同名不匹配实体保持不变。
- 手工刷新和历史补全使用 Redis 状态,不增加任务表。
### 项目对手方
- 新增项目对手方企业、股东、详情、刷新和历史补全能力。
- 流水上传、平台拉取及历史导入完成后按项目当前对手方集合 reconcile。
- 查询按每批 100 条执行,新华社查询共用最大并发数 3 的执行器。
- 项目删除直接清理项目工商数据,流水删除后按剩余流水同步,空集合不外呼。
### 前端与 Mock
- 实体详情新增注册资本、注册日期、区域、从业人数、同步时间和完整股东表。
- 流水对手方名称可打开本地工商详情,仅无数据或缓存过期时显示重新查询。
- Mock 覆盖公司、个体、空股东、多股东、HTTP 失败、超时、空响应、非法 JSON、外层失败、业务失败、结果缺失、名称不一致和信用代码缺失。
## 3. 数据库实施
- 新增迁移:`sql/migration/2026-07-29-xinhua-enterprise-profile.sql`
- 已通过 `bin/mysql_utf8_exec.sh` 连续执行两次,均成功。
- 已核对 5 张新增或校准表均为 `utf8mb4_general_ci`
- 已核对缓存 `query_result``LONGTEXT`,缓存唯一键为 `(query_param, query_type)`,项目唯一键为 `(project_id, counterparty_name)`
- 已核对实体工商扩展字段、菜单权限和管理员角色权限落库。
## 4. 自动化验证
- `python3 -m pytest tests/test_enterprise_api.py -v`:新华社 Mock 专项 4 项通过。
- `mvn -pl ccdi-info-collection -am test`构建成功覆盖新华社客户端、HTTP 日志、字段解析和信息采集模块回归。
- 项目模块定向测试53 项通过,覆盖上传、拉取、历史导入、项目删除及调用人传递。
- `mvn -pl ccdi-project -am -DskipTests compile`:构建成功。
- 前端在 Node 14.21.3 下执行 `npm run build:prod`:构建成功。
- `git diff --check`:通过。
全量项目测试当前仍有 3 个失败和 1 个错误,均位于既有结果总览和银行标签基线断言:按钮文案、规则数量、`modelParamService` 结构断言及对应未配置 Mock。本次新增链路的定向测试均通过未修改这些无关基线。
Mock 子项目全量 99 项测试为 75 项通过、24 项失败;失败用例均属于既有流水 Mock 链路,原因是测试尝试使用账号 `znsj` 从当前宿主连接 MySQL 时被拒绝。新华社工商专项 4 项不依赖该连接并全部通过。
## 5. 应用内浏览器验收
- 实体库真实页面成功展示接口返回的统一社会信用代码、注册资本、日期、区域、从业人数及 7 条完整股东。
- 新增同名但不同信用代码的实体后,确认该实体保持手工数据且无股东回写;缓存命中后新华社日志仍为 1 条。
- 补充验证同名未同步实体即使存在有效缓存仍可发起刷新,并明确返回“工商信用代码与实体主键不一致”;项目无本地记录时可复用有效缓存补齐,两种缓存命中均不新增接口日志。
- 流水明细真实页面确认对手方名称为本地详情入口,打开弹窗不触发新华社;无数据时显示重新查询。
- 对手方手工刷新后展示接口返回的信用代码、结构化工商字段和完整股东。
- 接口日志真实页面确认每次缓存未命中对应一条日志,详情包含调用账号、表单参数、`CCDI_GS_时间戳_UUID`、HTTP 状态、响应头和原始 JSON。
- 联调业务数据已清理;接口历史日志按设计保留。
## 6. 上线要求
生产环境不得配置或恢复异步结果查询。上线先使用一个已知企业完成单次烟测,逐项确认单次外呼、单条日志、原始缓存、`creditCode` 和股东落库一致;确认后才能启动实体和项目历史补全,失败时停止上线。