docs: 新增HCS接入实施状态与确认清单(已实现/未实现/待确认事项与上线检查清单)

This commit is contained in:
刘泉佳
2026-09-28 00:10:20 +08:00
parent 62917c6864
commit 6dd1d67844
@@ -0,0 +1,192 @@
# 桂物合同合规系统(HCS)接入实施状态与确认清单
> **日期**:2026-09-28
> **依据**:[2026-09-27-桂物合同合规系统HCS接入技术设计.md](./2026-09-27-桂物合同合规系统HCS接入技术设计.md)(§1 决策表 D1~D15、§8 实施拆分 P0~P5、§9 未决事项 U1~U12)
> **分支**:`feature/hcs-api-p0`(基于 `feature/payment-apply-bfi-sync`),共 18 个提交(P0 一个 + P1~P5 分步 17 个),全量编译通过
> **提交范围**:`a739211`(P0 骨架)→ `61b2c62`(P5 对账端点)
本文档回答三个问题:**哪些已经实现、哪些没有实现、哪些需要确认**。供代码评审、联调准备与上线检查使用。
---
## 1. 已实现清单
### 1.1 客户端模块 blade-third-party-api/blade-hcs-api(P0,包 `org.springblade.hcs`)
| 组件 | 内容 | 状态 |
|---|---|---|
| `feign/IHcsClient` | `@FeignClient(name="HCS", url="${thirdParty.hcs.baseUrl}")`,**24 个业务接口端点全部建成**(C101-1、C102-1/2/3、C103-1/2/3/4/5/6/7/9/11/12、C106-1/3/4、C108-1/2、C109-1/2、C111-1/2/3)+ OAuth2 getToken;URI 均可被 `thirdParty.hcs.*Url` 覆盖 | ✅ |
| `interceptor/HcsAuthInterceptor` | oauth2(URL 追加 access_token)/ basic(Authorization 头)双模式并存,切换只改配置;取令牌请求有路径+空令牌双重守卫 | ✅ |
| `token/HcsTokenService` | getToken → Redis(`blade:third:hcs:token`,120s 过期缓冲),`refreshAccessToken()` 供 401 强刷重放 | ✅ |
| `config/HcsProperties` | `third-party.hcs.*` 全量配置(§7 清单 + master-data.ttl-minutes + perf-record.xform-id 两个落实性补充),含默认值 | ✅ |
| `config/HcsFeignClientConfig` | connect 10s / read 60s,空拦截器覆盖全局,**无 Retryer**(D7) | ✅ |
| `dto/`(49 个文件) | 24 接口全量请求/响应 DTO + `HcsResult`/`HcsPageVO`/引用对象等公共结构;字段按《桂物合同集成接口逻辑梳理》核对,双层嵌套(C106-3/4、C109-1/2)以 `HcsResult<HcsResult<T>>` 承接 | ✅ |
| `util/HcsPageUtil` | offset 翻页(从 0 起),默认上限 50 页 | ✅ |
| `exception/HcsException` | 客户端异常 | ✅ |
> **口径说明**:D4 明确列出 23 个接口,§2.2 又将 C103-5 附件下载标注"备用接入";为对齐"24 接口"口径并覆盖文档全部接口,C103-5 一并建了端点(当前无业务调用方)。
> **技术说明**:`@ConfigurationProperties` 注解前缀为规范要求的 `third-party.hcs`(大写驼峰前缀 Spring Boot 拒绝启动),YAML 仍按设计文档用 `thirdParty.hcs.*`,宽松绑定等价生效——与 BFI 现状一致。
### 1.2 业务侧支撑组件(`org.springblade.transport.support.hcs`,12 个)
| 组件 | 内容 | 状态 |
|---|---|---|
| `HcsProjectSyncSupport` | C102-3 判重(命中回填跳过)→ C102-1 新建 / C102-2 更新;万元×10000 换算;合规 fdId 回填;手动重推 | ✅ |
| `HcsContractSyncSupport` | 链路编排:①C101-1 甲乙双方风险校验(留痕 check_log + `hcs_risk_*`,黑名单且 block-blacklist 阻断)→ ②附件转传 → ③C103-3 判重 → ④C103-1 起草/C103-11 更新(先持久化 fdId 再走后续)→ ⑤履约规则同步 | ✅ |
| `HcsExeStageSyncSupport` | C103-9 行级同步:聚合 row_op 非 none 行(add 不带 fdId、update/delete 必带),整体操作首推 add/后续 update;fdExeplanId 与阶段 fdId 按行回填持久化;软删行经原生 SQL 照常上报 delete | ✅ |
| `HcsCreditCheckSupport` | 付款提交事务内同步校验:C101-1 黑名单阻断提交;C106-1 超额不拦截、置 over + spec=need 转特批(超额时 success 仍 true,以 fdIsCredit 为准) | ✅ |
| `HcsSpecPaySyncSupport` | C106-3 发起(双层嵌套 fdId → hcs_spec_fd_id,状态 processing)/ C106-4 更新;特批附件 fdEntityKey=fd_spc_approval_attach、发起带 fdBindType=ADD | ✅ |
| `HcsPerfRecordSyncSupport` | C108-1 新建(fdId 回填 hcs_perf_fd_id)/ C108-2 更新(实际金额);关联履约阶段 fd_id;附件 fd_plan_att | ✅ |
| `HcsPaymentSyncSupport` | 付款链编排(特批→履约记录)+ 整体状态回写 + 特批结果人工确认(§9-U1 过渡) | ✅ |
| `HcsInvoiceRegSyncSupport` | C111-1 判重 / C111-2 新增 / C111-3 票据日期回填(金蝶回写发票最新 invoiceDate);合同编号经应收结算链路回溯 | ✅ |
| `HcsReceiptBillSyncSupport` | C109-1 新建(双层嵌套 fdId)/ C109-2 更新;合同回溯 + 人工补录兜底;税率 ÷100;fd_bill_date 为 YYYY-MM-DD 字符串 | ✅ |
| `HcsAttachmentSupport` | 附件解析 → 文件服务下载 → C103-2 转传 → 合规附件ID 映射缓存(7 天,未命中重传) | ✅ |
| `HcsMasterDataSupport` | C103-6/7/12 模板/分类/币种全量拉取 + Redis 缓存(TTL 可配)+ template-mapping 存在性校验 | ✅ |
| `HcsReconSupport` | 对账回查:C102-3 / C103-3 / C103-4 / C111-1 | ✅ |
**字段组装规范**:所有 Support 按 §3.4 规范逐字段标注外部字段中文名与 TMS 取值来源(照 `pushArBill` 惯例),待联调字段带 `TODO 待确认` 并标注 §9 编号。
### 1.3 触发与任务(D9 / ADR-0001)
| 项 | 内容 | 状态 |
|---|---|---|
| 审批零埋点 | 项目立项/合同:`/approve` + MK 回调(4 处);付款申请:`/approve` + MK PaymentHandler;开票申请/收票单:`changeStatus` 到 approved 统一置 `hcs_sync_status=unsynced` | ✅ |
| 付款推进触发 | 金蝶 A103-2 付款结果回写(`applyPayApplyResult`)paidAmount 变化时,已有履约记录ID 则置待同步 → 扫描走 C108-2 | ✅ |
| 金蝶开票联动 | `syncKingdeeInvoiceResult` 推进 invoiced 时置待同步 → 扫描走 C111-3 回填票据日期(D12) | ✅ |
| 合同审批置行标记 | 合同审批通过将未同步履约规则行置 row_op=add(ADR-0002) | ✅ |
| `HcsPushTask` | `@Scheduled`(cron/开关可配,默认关),顺序:项目→合同→付款→开票→收票;Redis 分布式锁(setIfAbsent + 持有值比对释放,TTL 240s);批量 push.batch-size(默认 50);失败 failed+retry_count+1,重试上限 max-retry(默认 5)超限人工 | ✅ |
### 1.4 手动端点(`HcsSyncController` + `ContractExeStageController`)
| 端点 | 用途 |
|---|---|
| `POST /hcs/sync/{bizType}/{id}` | 单条重推(bizType:project / contract / payment / invoice-application / invoice-receipt),重置 unsynced+清零计数后立即推送 |
| `POST /hcs/sync/{bizType}` | 批量推送一轮(复用扫描逻辑) |
| `POST /hcs/spec-pay/confirm?id=&result=approved|rejected` | 特批结果人工确认(仅 processing 可确认) |
| `POST /hcs/master-data/refresh` | 刷新主数据缓存并校验模板映射 |
| `GET /hcs/recon/project?projectCode=` | 项目立项对账(C102-3) |
| `GET /hcs/recon/contract?contractNo=` | 合同对账(C103-3) |
| `GET /hcs/recon/contract/detail?fdId=|fdNumber=` | 合同详情对账(C103-4) |
| `GET /hcs/recon/invoice-registration?applicationNo=` | 开票登记对账(C111-1) |
| `GET /contract-exe-stage/list?contractId=` | 履约规则行查询 |
| `POST /contract-exe-stage/submit?contractId=` | 履约规则行保存(行级差异标记) |
| `POST /contract-exe-stage/remove?id=` | 履约规则行删除(软删+标记) |
### 1.5 数据模型与配置
| 交付物 | 内容 | 状态 |
|---|---|---|
| `doc/sql/transport/blade_hcs_sync_fields_20260927.sql` | 5 张业务表统一字段组(hcs_fd_id/sync_status/retry_count/sync_time/sync_msg),可重复执行 | ✅ |
| `blade_hcs_contract_fields_20260927.sql` | 合同扩展字段(exeplan_id/risk_level/black_status/risk_time)+ `blade_hcs_check_log` 建表 | ✅ |
| `blade_hcs_exe_stage_20260927.sql` | `blade_contract_exe_stage` 建表 | ✅ |
| `blade_hcs_payment_fields_20260927.sql` | 付款申请特批字段组 + hcs_perf_fd_id | ✅ |
| `blade_hcs_receipt_fields_20260927.sql` | 收票单合同补录字段(hcs_contract_id/no) | ✅ |
| 实体字段 | ProjectApply / ContractManage / PaymentApplication / InvoiceApplication / InvoiceReceipt 已加 hcs 字段;新实体 HcsContractExeStage / HcsContractCheckLog | ✅ |
| Nacos 配置段 | `doc/nacos/third-party-api.yaml` 新增 `thirdParty.hcs` 完整节点(凭据走 `${HCS_*:}` 环境变量注入) | ✅ |
---
## 2. 未实现清单
### 2.1 按约束明确不做
| 项 | 说明 |
|---|---|
| C104 收款流水(C104-1/2/3)、C107 认领记录(C107-1/2/3) | ADR-0003 边界排除:推送方与链路待定,TMS 不承担;Feign 端点也未建 |
| 付款申请/开票/收票的 MK 处理器**补齐** | 约束"他人负责"。注:现状 PaymentHandler 实际已由他人注册(探索发现),本次仅按零埋点约定补了 1 行状态置位,未动处理器归属;开票/收票仍无 MK 处理器,直批入口已接线,未来新处理器只要置 approved 即被扫描自动覆盖 |
| 前端页面改动 | 列表页"推送合规/重推"按钮、履约规则页签、特批结果确认入口、对账查询页——本次只交付后端端点,前端(tms-erp-web)未动 |
### 2.2 有意暂缓(待联调/待确认后补)
| 项 | 现状 | 补充条件 |
|---|---|---|
| C103-1 报文附件挂载 | 附件已转传并缓存 fdId,但 C103-1 请求不带附件字段 | §9-U8 合规方明确挂载字段后接线 |
| 收票单作废推送 C109-2 | `voidBill` 不触发推送 | v4 收票更新入参无作废状态字段,口径确认后补 |
| C106-4 特批更新的自动触发 | 仅手动重推且特批流程已存在时走 C106-4 | "单据变更"的判定口径确认后补自动触发 |
| C103-4 详情数据结构解析 | `HcsResult<Object>` 原样承接 | 联调拿到实际结构后补充 DTO |
| `blade_hcs_check_log` 查询界面/端点 | 仅写入留痕 | 需要排查页面时补查询端点 |
| 附件下载 C103-5 | 仅建 Feign 端点 | 对账/排查需要时接入业务 |
### 2.3 简化实现(功能可用但口径粗,联调后细化)
| 项 | 现状 |
|---|---|
| 付款申请与履约阶段关联 | 取合同下第一条 perform_type=payment 且已同步的规则行(fd_id/fd_property),无按款项性质等精确匹配 |
| C103-9 返回阶段ID 匹配 | 返回行数与请求一致时按行序对应;不一致时按业务属性组合键兜底,仍匹配不到的 add 行保持待同步重试 |
| 收票"票据变更"触发 | 无自动变更检测(收票单无变更流程),变更场景走手动重推 |
| C111-2 新增后金蝶已 invoiced 的竞态 | 同一轮紧跟一次 C111-3 兜底回填 |
---
## 3. 需要确认清单
### 3.1 需要合规方/联调确认(对应设计文档 §9,代码均已占位不阻塞)
| # | 事项 | 当前代码/配置占位 |
|---|---|---|
| U1 | 特批流程结果回传方式 | 人工确认端点 `POST /hcs/spec-pay/confirm`(过渡方案);若有回调/查询接口需改造 |
| U2 | 组织/人员 fdId 体系与登录名同源性 | 引用一律先传名称或登录名(经办人/创建人经 UserCache 解析 account) |
| U3 | 字典值映射:fd_settlement_type、fd_invoice_type、付款用途/性质/类型、CONTRACT_STATUS 是否必传、fdBlackStatus 取值(示例 no) | Nacos 各 mapping 空占位;未配置时该字段不传并 warn(黑名单判定按 "yes" 等值,联调校准);CONTRACT_STATUS 一期不传 |
| U4 | 判重 conditions 是否支持 fd_num/fdNumber 精确查询;HCS 是否按 fd_kingdee_id 幂等 | 按文档 conditions 精确匹配实现,联调验证;判重查询 C102-3 额外携带 curUser(文档示例如此) |
| U5 | C103-11 updateDraft 如何定位已有合同 | 入参同发起;补偿重试路径会重复调 C103-11,需确认幂等性 |
| U6 | 相对方 fdNumber 编码体系、fdType(inner/外部)判定、C101-1 用客商哪个编码 | 按甲乙方名称反查 CustomerArchive.customerCode,反查不到留空/跳过校验;fdType 不传 |
| U7 | 合规模板ID清单 | `contract.template-mapping` 空;未配置时合同推送失败并提示配置项 |
| U8 | 合同附件向 HCS 的传递方式 | 已转传+缓存 fdId,挂载点确认后接线 |
| U9 | 立项 templateCode 与 C108 fd_xform_id 环境值 | `project.template-code`、`perf-record.xform-id` 空占位;未配置时立项/履约记录推送失败(xform_id 未配置则不传) |
| U10 | 开票申请→合同关联字段 | 现实现:开票申请 → 应收结算关联表 → FormalSettlement.contractNo;回溯不到推送失败提示补录 |
| U11 | fd_ap_bill_src_subject 关联键 | 一期不传 |
| U12 | C104/C107 推送方及链路 | 范围外备忘(ADR-0003) |
### 3.2 需要用户(我方)确认/决策
| # | 事项 | 说明与建议 |
|---|---|---|
| 1 | **前端配套改动归属** | 推送/重推按钮、履约规则维护页签、特批结果确认入口、对账查询页需要前端开发。是前端团队按本文 1.4 端点对接,还是需要后端继续补前端? |
| 2 | **菜单与接口权限** | `HcsSyncController`(/hcs/**)与 `ContractExeStageController`(/contract-exe-stage/**)当前未加 `@PreAuth(menu)`(新功能无菜单,登录即可访问)。是否需要建菜单并补权限注解? |
| 3 | **特批结果人工确认的业务归属** | 谁负责在什么时机确认(财务?项目部?);确认后是否需要同步更新付款申请的其他业务状态(如是否放行后续付款) |
| 4 | **C108-2 履约记录更新的触发范围** | 当前仅金蝶 A103-2 付款结果回写触发;付款处理单记录(applyPayBillRecord)等其他 paidAmount 推进路径是否也要触发? |
| 5 | **C106-4 特批更新的触发场景** | "单据变更且特批流程存在时调用"——付款申请在特批中(processing)允许哪些变更?当前未做自动触发 |
| 6 | **收票作废是否推 HCS** | v4 无作废字段,当前不推;若合规方要求作废同步需其提供口径 |
| 7 | **付款与履约规则行的关联口径** | 当前取合同第一条付款类型规则行;若一笔付款需精确对应某一期/某性质阶段,需明确匹配规则(如按款项性质、按期次) |
| 8 | **履约规则行维护的状态限制** | 当前维护接口未限制合同状态(草稿/变更中均可编辑);是否要求仅草稿与 change_reviewing 可编辑? |
| 9 | **实体命名偏差** | 留痕表按设计叫 `blade_hcs_check_log`,实体类名为 `HcsContractCheckLog`(P1 命名,含付款校验留痕后名字略窄)。是否改名 `HcsCheckLog`?影响面小(1 实体+1 Mapper) |
| 10 | **C106-3 的 fd_id 取值** | 设计 §5.5 表格映射为 paymentNo(单据号),接口文档 §8.2 语义为"来源付款单ID(主键)"。当前按设计传 paymentNo,联调时需确认以哪个为准 |
---
## 4. 上线前检查清单(Nacos `thirdParty.hcs.*`)
| 配置 | 必填 | 说明 |
|---|---|---|
| `base-url` / `auth-type` / `app-key` / `app-secret`(或 basic 凭据) | ✅ | 合规方测试环境地址与凭据(P0 依赖项) |
| `push.sync-enabled` | — | 总开关,**默认 false**;联调稳定后灰度打开 |
| `push.cron` / `batch-size` / `max-retry` | — | 默认每 5 分钟 / 50 / 5 |
| `project.template-code` | ✅(推立项前) | U9 环境值 |
| `contract.template-mapping` | ✅(推合同前) | U7 模板清单,按合同类别配置 |
| `contract.settlement-type-mapping` | 联调 | U3;未配置 fdSettlementType 不传 |
| `invoice.currency-id-mapping`(RMB) | ✅(推开票前) | HCS 币种 fdId,可经 `/hcs/master-data/refresh` 后从币种缓存取值 |
| `invoice.invoice-type-mapping` / `receipt-bill.invoice-type-mapping` | 联调 | U3 字典值 |
| `spec-pay.payment-purpose/nature/type` | 联调 | U3 字典值 |
| `perf-record.xform-id` | 推履约记录前 | U9 环境值(不配置则不传该字段) |
| `attachment.file-download-base` | ✅(附件转传启用时) | TMS 文件服务基址 |
| `risk.block-blacklist` / `credit.require-contract-synced` 等 | — | 有默认值,按业务松紧调整 |
| SQL 脚本执行 | ✅ | 5 个 HCS SQL 脚本按文件名顺序执行(均幂等可重跑) |
---
## 5. 遗留 TODO 代码索引
| 位置 | 内容 |
|---|---|
| `HcsContractSyncSupport#buildXformFields` | CONTRACT_STATUS 是否必传(§9-U3) |
| `HcsContractSyncSupport#transferAttachmentsIfEnabled` | 附件挂载点(§9-U8) |
| `HcsContractSyncSupport#updateContract` | C103-11 定位方式(§9-U5) |
| `HcsContractSyncSupport#buildSigners` | 相对方编号/ fdType 判定(§9-U6) |
| `HcsExeStageSyncSupport#backfill` | fdChangeStages 对应关系(行序/属性匹配待联调校准) |
| `HcsExeStageSyncSupport#markRowSynced` | add 行未匹配到阶段ID 时保持待同步重试的重复建行风险 |
| `HcsPerfRecordSyncSupport#buildFormData` | fd_property/关联阶段口径 |
| `HcsInvoiceRegSyncSupport#requireContractNumber` | 应收结算回溯口径(§9-U10) |
| `HcsInvoiceRegSyncSupport#latestInvoiceDate` | 票据日期取值口径(发票日期 vs 回写时间) |
| `HcsReceiptBillSyncSupport#buildSaveParam` | fd_ap_bill_src_subject(§9-U11);作废推送缺接口依据 |
| `HcsTokenVO` / `HcsTokenService#cacheToken` | getToken 响应字段与 expires_in 单位(v4 未给出示例) |
| `HcsReconSupport#reconContractDetail` | C103-4 出参结构 |