docs: 新增收款认领同步合同合规业务流程梳理文档

- 收款认领推送金蝶完成后同步合同合规(C103-9履约计划/C107-1认领记录/C108-1履约流水)
  含业务逻辑总览、全链路流程、接口与字段映射、代码改动清单、启用操作过程与边界说明
This commit is contained in:
刘泉佳
2026-10-22 19:11:13 +08:00
parent 62f523928a
commit 3e01a32cc6
@@ -0,0 +1,182 @@
# 收款认领推送金蝶完成后同步合同合规系统(C103-9 履约计划 + C107-1 认领记录 + C108-1 履约流水)业务流程梳理
> 需求:金蝶认领推送(A301-3)完成后,把认领记录推送给合同合规系统(HCS)——① C103-9 更新合同履约计划(认领金额累加到收款计划行并重推);② C107-1 新增认领记录;③ C108-1 新增履约流水。整体做一个开关。
> 关键口径:C107-1 的 `fdCollectionFlow.fdId` 为**合规系统自己的收款流水ID**(非 TMS 本地主键),经 C104-2 按明细流水号定位(合规侧流水由合规自 ERP 同步,与 TMS A301-2 镜像同源);C107-1/C108-1 引用的履约项ID 均为 C103-9 返回的阶段ID(hcs_stage_fd_id)。
> 代码改动日期:2026-10-22,`mvn compile` 通过。
---
## 1. 业务逻辑总览
| # | 规则 | 说明 |
| --- | --- | --- |
| 1 | 触发点唯一:A301-3 推送成功之后 | 挂在 `pushClaimLocked`(金蝶认领推送事务模板)返回成功后执行,手动「推送金蝶」按钮与定时任务两条路共用;金蝶推送事务已提交,合规推送失败不影响金蝶推送结果 |
| 2 | 总开关 | `thirdParty.hcs.claim.sync-enabled`(`HcsProperties.claim.syncEnabled`,默认 false),关闭时整个认领链不执行、零开销 |
| 3 | 按合同分组推送 | 有效认领分摊行(`blade_receipt_claim_settlement` status=1 且未删)经结算单 `contract_id` 归集,逐合同推送;**单合同失败不影响其余合同** |
| 4 | 编排顺序:C103-9 → C107-1 → C108-1 | 先更新履约计划(认领金额累加重推),因为 C107-1 的 `fdExePlanStageId` 与 C108-1 的 `fd_plan_id` 都引用 C103-9 返回的阶段ID(与付款链 C103-9→C108 同口径) |
| 5 | 认领金额累加口径 | `coalesce(fund_amount, 0) + 认领金额` 原子累加到收款计划行(防并发丢更新);已同步行置 `row_op=update` 凭阶段ID 重推 C103-9,未同步行保持 `add` 待合同链路首推(首推即携带累加后金额)——与付款审批累加逻辑完全对称 |
| 6 | 只推未作废认领 | 认领主单 `claim_status=claimed` 才推;作废认领的分摊行在作废时已置 status=0,天然排除。且已推送金蝶的认领禁止作废(voidClaim 闸门),已同步合规的认领不存在后续被作废的场景 |
| 7 | 合同未推送合规降级 | `hcs_fd_id` 为空时只累加本地计划行金额,不推 C103-9/C107-1 的合同引用/C108-1,随合同链路首推补齐 |
| 8 | 失败只留痕不重试 | 认领链任何一步失败仅 error 日志,**无自动重试、无失败状态落库**;且金蝶推送 `push_status=pushed` 为终态闸门,重推金蝶不会再触发合规链(见 §6 边界) |
---
## 2. 业务流程
### 2.1 全链路(业务视角)
```
金蝶认领公告同步(A301-2)→ 流水落库 blade_kingdee_receipt_flow
▼
用户认领(选应收正式结算单 + 分摊金额)→ 认领主单 + 分摊行落库,流水累计认领金额
▼
推送金蝶 A301-3(手动「推送金蝶」按钮 / 定时任务 ReceiptClaimPushTask,10分钟)
│ 闸门:公告id存在 + 未推送过(pushed 终态)+ 认领完成(claimed)+ 公告对账一致
▼
A301-3 推送成功(push_status=pushed、回填金蝶收款单号)★事务已提交
▼
HCS 收款认领链(开关 thirdParty.hcs.claim.sync-enabled,失败仅日志)
├─① 归集:有效分摊行 × 结算单 → 按合同分组(合同id → 认领主单id → 金额)
└─② 逐合同推送(单合同失败 continue 下一合同)
├─ C103-9 更新履约计划:认领金额累加收款计划行 → 已同步行重推
├─ C104-2 定位合规收款流水ID(明细流水号精确匹配,一次定位全程共用;失败仅跳过 C107-1)
├─ C107-1 认领记录 × N(按「认领主单 × 合同」分组,每组合一条)
└─ C108-1 履约流水 × 1(按合同一条:金额=该合同累计认领金额)
```
### 2.2 代码视角(HcsClaimSyncSupport.pushClaimToHcs)
```
ReceiptFlowServiceImpl.pushClaimLocked(flowId, announce)
│ transactionTemplate.execute(doPushClaimToKingdee) ← 金蝶推送事务
│ result.isSuccess() ?
▼ yes
hcsClaimSyncSupport.pushClaimToHcs(flowId)
├─ 开关关闭 → return(静默)
├─ try doPushClaimToHcs(flowId) catch → log.error(不外抛)
│
├─ 查询数据(流水重读 + 认领主单 claimed + 分摊行 status=1/is_deleted=0)
├─ 结算单批量 selectBatchIds → 合同id 归集(LinkedHashMap 保序)
├─ locateHcsCollectionFlowId:C104-2 按 detail_serial_no 查 fdId
│ └─ 异常/查不到 → null,后续 C107-1 跳过(C103-9/C108-1 照常)
│
└─ for each contractId:
├─ accumulateClaimedAmountOnPush(contractId, 合同累计认领金额)
│ ├─ findCollectionStageRow(progress 精确匹配 → 首条已同步收款行兜底)
│ ├─ fund_amount 原子累加(setSql coalesce)
│ └─ 行已同步 → row_op=update + unsynced("收款认领金额累加,待重推C103-9")
├─ 合同已推送合规(hcs_fd_id 非空)→ syncExeStages 重推 C103-9(无待同步行返回提示非失败)
├─ C107-1 × 认领主单数:claimRecordAdd(流水引用+合同+阶段ID+认领人+金额+日期+备注,fdStatus=0)
└─ C108-1 × 1:perfRecordAdd(须有已同步收款计划行提供 fd_plan_id,否则跳过)
```
---
## 3. 接口清单(本次涉及 HCS 接口)
| 接口 | Feign 方法 | 路径 | 触发时机 | 说明 |
| --- | --- | --- | --- | --- |
| C103-9 履约规则同步 | `exeplanAdd` | `/openapi/eop-exeplan/lcode/ext-eop-exeplan/extEopExeplanMainOpen/syncExeplan` | 认领金额累加后(合同已推送合规时) | 复用既有 `HcsExeStageSyncSupport.syncExeStages`,聚合 row_op≠none 行整体 update |
| C104-2 查询收款流水列表 | `collectionFlowList`(**新增**) | `/openapi/eop-data/eopDataCollectionFlowOpen/list` | C107-1 推送前一次 | conditions `fdDetailSerialNumber`=流水明细流水号 → 取合规 `fdId` |
| C107-1 新增认领记录 | `claimRecordAdd` | `/openapi/eop-data/eopDataCollectionFlowClaimRecordOpen/add` | 每个认领主单 × 合同一条 | 必填:fdCollectionFlow.fdId、fdContractNumber、fdClaimAmount;fdStatus 固定 0 |
| C108-1 履约记录新建 | `perfRecordAdd` | `/openapi/sys-modeling/apis/data/km-pay-receive/V1/dataSync/add` | 每合同一条 | 必填:fd_apply_no、fd_contract_id、fd_plan_date、**fd_plan_id**(接口新版必填,取收款计划行阶段ID) |
> Feign 降级工厂与本地 Mock 均为通用代理实现,新增方法零改动;本地联调可在 mock 目录放 `collectionFlowList.json` / `claimRecordAdd.json` / `perfRecordAdd.json` 桩文件(有桩走桩、无桩透传真实接口)。
### 3.1 C107-1 请求字段映射
| HCS 字段 | TMS 取值 | 说明 |
| --- | --- | --- |
| `fdCollectionFlow.fdId` | C104-2 按流水 `detail_serial_no` 定位的合规流水ID | 【必填】合规侧收款流水,非 TMS 主键 |
| `fdContract` | 合同 `hcs_fd_id` + `contract_name` | 合规合同引用 |
| `fdContractNumber` | 合同 `contract_no` | 【必填】须在合规本地存在 |
| `fdExePlanStageId` | 收款计划行 `hcs_stage_fd_id`(无已同步行不传) | 对应履约项 |
| `fdFundNature` | 收款计划行 `fund_nature`(无行不传) | 认领款项类型 |
| `fdClaimer` / `fdClaimerName` | 认领主单 `claimer_name`(仅名称引用) | TMS 与合规用户不同源(§9-U2) |
| `fdClaimerDept` / `fdClaimerDeptName` | 认领主单 `claimer_dept_name` | 同上 |
| `fdClaimAmount` | 该认领主单分摊到本合同的金额合计 | 【必填】>0 |
| `fdClaimDate` | 认领主单 `claim_date`(毫秒时间戳) | |
| `fdRemark` | 认领主单 `remark` | |
| `fdStatus` | 固定 0(已认领) | 作废=1 本期未接 |
### 3.2 C108-1 请求字段映射(dynamicProps)
| HCS 字段 | TMS 取值 | 说明 |
| --- | --- | --- |
| `fd_apply_no` | 流水 `receipt_notice_no`(兜底 `detail_serial_no`) | 【必填】申请编号=收款通知单号 |
| `fd_apply_amount` / `fd_fact_amount` | 该合同累计认领金额(字符串传值) | 申请=实际(认领即到账口径) |
| `fd_plan_date` | 名下认领主单最近 `claim_date`(毫秒) | 【必填】履约日期 |
| `fd_paln_type` | 固定 `collection` | 履约类型(原文拼写 paln) |
| `fd_property` | 收款计划行 `fund_nature` | 履约性质 |
| `fd_id` / `fd_plan_id` | 收款计划行 `hcs_stage_fd_id` | 履约计划id【必填】,无已同步行整条跳过 |
| `fd_jd_doc_no` | 流水 `kingdee_bill_no`(A301-3 返回收款单号) | 金蝶单据号溯源 |
| `fd_contract_id` | 合同 `hcs_fd_id` | 【必填】 |
| `fd_business_id` | 流水主键 `id` | 溯源 |
| `fd_xform_id` | 配置 `thirdParty.hcs.perf-record.xform-id`(未配置不传) | 表单模板 |
| `mechanisms.attachment` | 空列表 | C108-1 必填节点;认领附件暂不转传 |
---
## 4. 代码改动清单(2026-10-22)
| 文件 | 改动 |
| --- | --- |
| `support/hcs/HcsClaimSyncSupport.java`(新增) | 认领链编排:归集分组 → C103-9 累加重推 → C104-2 定位 → C107-1 × N → C108-1 × 1;开关守卫 + 异常内吞(不影响金蝶推送) |
| `service/impl/ReceiptFlowServiceImpl.java` | `pushClaimLocked` 金蝶推送事务成功后挂钩 `pushClaimToHcs`(手动/定时共用);注入 support |
| `feign/IHcsClient.java` | 新增 C104-2 `collectionFlowList` 与路径常量 |
| `dto/HcsCollectionFlowVO.java`(新增) | C104-2 分页行出参 |
| `dto/HcsPerfRecordPropsDTO.java` | 补充 `fd_plan_id`(fd_plan_id)、`fdJdDocNo`(fd_jd_doc_no)——接口文档新版必填/新增字段 |
| `config/HcsProperties.java` | 新增 `Claim` 配置节(`claim.syncEnabled`,默认 false) |
| `service/IContractExeStageService.java` + Impl | 新增 `findCollectionStageRow`(progress 精确匹配→首条收款行兜底)与 `accumulateClaimedAmountOnPush`(原子累加+标记重推) |
| `doc/nacos/third-party-api.yaml`、`blade-dev.yaml` | hcs 节点新增 `claim.sync-enabled` 配置样例 |
> 无数据库表结构变更、无新增定时任务、无新增页面。
---
## 5. 操作过程
### 5.1 前置条件(联调/生产启用前逐项确认)
| # | 条件 | 不满足时的表现 |
| --- | --- | --- |
| 1 | 合同已推送合规(`blade_contract_manage.hcs_fd_id` 非空)且 C103-9 计划行已同步 | 只累加本地金额不推合规;C108-1 跳过(缺 fd_plan_id) |
| 2 | 合同下有**已同步**收款履约计划行(performType=collection,优先 progress) | 金额不累加、C107-1 不带履约项、C108-1 跳过 |
| 3 | 合规侧已存在同明细流水号的收款流水(合规自 ERP 同步) | C104-2 查不到 → 仅 C107-1 跳过 |
| 4 | HCS 配置可用(baseUrl/鉴权头/xform-id 等,与付款链共用) | 对应接口失败,error 日志留痕 |
### 5.2 开关配置(Nacos `third-party-api.yaml` / 环境覆盖)
```yaml
thirdParty:
hcs:
claim:
sync-enabled: ${HCS_CLAIM_SYNC_ENABLED:false} # 默认关,联调/灰度后打开
```
代码内配置键为 `third-party.hcs.claim.sync-enabled`(横线小写),YAML 驼峰 `thirdParty.hcs.claim.*` 经宽松绑定等价生效,与既有 hcs 配置同节点。
### 5.3 业务操作步骤
1. 收款流水页「同步流水」(A301-2)拉取认领公告;
2. 流水认领(选应收正式结算单、分摊金额);
3. 「推送金蝶」手动推送,或等定时任务(10 分钟一轮)自动推送;
4. A301-3 成功后系统自动推合规,无需人工操作;日志关键字 `HCS收款认领链` / `HCS认领记录推送` / `HCS履约流水`。
### 5.4 失败排查
- 看应用日志 `HCS收款认领链推送失败`(含 contractId)与 `HCS收款流水定位失败`,失败原因随 HCS 响应 msg/traceId 记录;
- **无自动重试**:修复问题后无法通过「重推金蝶」重新触发(pushed 终态闸门拦截);数据修正需人工在合规侧补录,或后续迭代增加按流水的合规重推入口。
---
## 6. 边界与注意事项
1. **失败无重试、无状态落库**(本期 shortcut):认领链失败仅日志,金蝶推送终态后不可重触发;如需闭环,后续给流水加 hcs 同步状态列 + 定时补偿(照付款链模式)。
2. **认领作废与合规数据天然隔离**:已推送金蝶的认领禁止作废(`voidClaim` 闸门:「该认领已推送金蝶,不允许作废」),而认领链仅在推送金蝶成功后触发——已同步合规的认领不可能再被作废,无需 C107-3 作废同步;作废只发生在推送金蝶前(认领链未触发),仅在本地回退(认领主单置 voided、分摊行置无效、流水累计金额/认领状态重算、结算单收款汇总刷新)。若未来放开「推送后作废」,需先持久化 C107-1/履约流水 fdId 再接 C107-3。
3. **认领附件未转传**:C108-1 的 mechanisms.attachment 传空列表;需附件时接 C103-2 转传(照付款链 HcsAttachmentSupport 模式)。
4. **款项性质无来源**:认领分摊不区分款项性质,累加固定落在 progress(精确匹配)→ 首条收款行(兜底);若合同收款计划含预付款行,认领金额不会计入预付款行——业务要求分性质拆分时需认领页增加性质字段。
5. **C103-9 覆盖口径与付款链一致**:认领金额累加覆盖 HCS 计划行款项金额(原计划金额被累计认领金额覆盖属预期行为),需与合规侧确认展示口径。
6. **金额口径**:C107-1/C108-1 金额为「分摊/累计认领金额」(2 位小数,随认领校验规则);同一流水多次认领后一次性推送金蝶,认领链按推送时点的全量有效分摊归集,不区分历史认领主单先后。
7. **合规流水定位依赖明细流水号一致**:C104-2 按 `fdDetailSerialNumber` 精确匹配(与 A301-2 detailid 同源),合规侧同步口径变化(如明细流水号为空)会导致 C107-1 全部跳过。
8. **并发安全**:金蝶推送侧已有行锁 + 终态闸门防双推,认领链单实例单流水触发一次;计划行累加为 SQL 原子操作,多流水并发认领不丢更新。