From 4c32cb9046d7e588b4ec05c2d52636f1f810e2ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com> Date: Tue, 29 Sep 2026 01:51:07 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=96=B0=E5=A2=9E=E9=A2=84=E4=BB=98?= =?UTF-8?q?=E6=AC=BE=E7=94=B3=E8=AF=B7A103-3=E9=87=91=E8=9D=B6=E9=93=BE?= =?UTF-8?q?=E8=B7=AF=E8=A1=A5=E9=BD=90=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 覆盖三项改造:e_bebank_number 与 A103-1 统一取联行号、A103-2 消失解锁兜底(ADR-0005)、 回写任务开关默认策略;含状态机全景、时序图、配置汇总与联调验证要点 --- ...¡¥齐方案(e_bebank_number统一-消失解锁-回写默认开启).md | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 doc/docs/业务流程/2026-09-29-预付款申请A103-3金蝶链路补齐方案(e_bebank_number统一-消失解锁-回写默认开启).md diff --git a/doc/docs/业务流程/2026-09-29-预付款申请A103-3金蝶链路补齐方案(e_bebank_number统一-消失解锁-回写默认开启).md b/doc/docs/业务流程/2026-09-29-预付款申请A103-3金蝶链路补齐方案(e_bebank_number统一-消失解锁-回写默认开启).md new file mode 100644 index 00000000..130d952c --- /dev/null +++ b/doc/docs/业务流程/2026-09-29-预付款申请A103-3金蝶链路补齐方案(e_bebank_number统一-消失解锁-回写默认开启).md @@ -0,0 +1,169 @@ +# 预付款申请(A103-3)金蝶链路补齐方案:e_bebank_number 统一、A103-2 消失解锁、回写默认开启 + +> 日期:2026-09-29 +> 关联文档: +> - `doc/docs/TMS业财融合-集成流程图文字版与业务流程梳理.md`(图03 财务应付及付款,步骤4 推送金蝶 / 步骤13 异常回收) +> - `doc/adr/0005-B901事件驱动双表锁单模型.md`(UNLOCK 置失败态不自动重推;A103-2 连续两轮查询消失兜底复用 `unlockBill()`) +> - `doc/docs/业务流程/付款申请同步金蝶(星瀚)技术文档.md`(A103-3 接口定义) +> - `doc/docs/业务流程/2026-09-17-付款管理金蝶付款结果定时回写(A103-2付款申请单查询+A103-4付款处理查询)技术文档.md` +> - `doc/docs/业务流程/2026-09-18-付款管理金蝶同步全链路逻辑梳理(推送链路与回写链路连贯性).md` + +## 1. 背景与范围 + +对照方案文档图03 对 A103-3 预付款路径做金蝶侧缺口盘点,本方案补齐三项(合同合规系统相关事项另期处理): + +| # | 缺口 | 原状 | 本方案 | +|---|---|---|---| +| 1 | A103-3 分录 `e_bebank_number`(往来银行.编码)取 `bankName`(银行名称字段) | 与 A103-1 取客商收款账户联行号的口径不一致,疑似取错字段 | 统一取联行号,未维护即拦截 | +| 2 | 金蝶侧反审核删除付款申请单后,TMS 无感知、无恢复路径 | A103-2 查不到仅 `continue`,本地停留 synced/paying;状态门禁禁止重推 → 单据永久卡死 | 连续两轮查询消失 → `unlockBill()` 解锁置失败,交人工重推 | +| 3 | 定时回写任务默认关闭 | 代码 `@Value` 默认 false(注释却写"默认开启"),三套 Nacos 配置默认 false,上线必须手工开启 | 代码与 Nacos 默认均改为开启,注释纠正 | + +不改动范围:A103-3 推送报文其余字段、三层幂等门禁、A902 附件链路、A103-4 付款记录回写、履约数据联动(均已就绪)。 + +## 2. 改造一:A103-3 `e_bebank_number` 与 A103-1 统一口径 + +### 2.1 变更内容 + +`PaymentApplicationServiceImpl#pushBfiPayApply`: + +| 项 | 变更前 | 变更后 | +|---|---|---| +| 取值 | `entity.getBankName()`(付款申请"收款银行名称"文本) | `bfiBebankNumber(entity, context)` | +| 实际含义 | 银行名称(非编码,金蝶档案无法匹配) | 付款申请所选客商收款账户(`blade_customer_receipt_account`)**联行号 `cnapsCode`** | +| 缺失行为 | 不校验,直接传名称 | 收款账户不存在 / 未维护联行号 → `ServiceException` 拦截推送(与 A103-1 同口径) | + +```java +// 往来银行.编码:与 A103-1 统一口径,取付款申请所选客商收款账户联行号(未维护即拦截) +entry.setEBebankNumber(this.bfiBebankNumber(entity, context)); +``` + +### 2.2 取值链路(与 A103-1 完全一致) + +1. 付款申请选择了收款账户(`receiptAccountId`)→ 按账户 id 直查,批量同步经 `KingdeeSyncContext.receiptAccountCache()` 复用; +2. 未选账户 → 按合同乙方客商 + 收款账号兜底匹配(默认账户优先); +3. `cnapsCode` 为空 → 拦截:"收款账户未维护联行号,请先在客商档案维护收款信息联行号"。 + +### 2.3 影响 + +- **新增推送前置条件**:预付款推送前必须维护收款账户联行号。存量已 synced 单据不受影响(状态门禁不会重推);failed 待重推单据需先补联行号。 +- 解锁重推(改造二)产生的"新单"同样走该口径,与金蝶侧往来银行档案编码匹配。 + +## 3. 改造二:A103-2 消失解锁兜底(ADR-0005) + +### 3.1 业务问题 + +图03 异常回收分支:财务共享驳回后,金蝶侧对该付款申请单**反审核 + 删除**,TMS 需解锁并允许重新推送。此前 TMS 只有正向回写:A103-2 查不到该单仅跳过,本地停留 synced/paying,且 `doSyncKingdee` 状态门禁禁止 synced/paying 重推——单据卡死,只能改库解救。 + +B901 UNLOCK 事件通知属合同系统对接域,本期不建设;按 ADR-0005 约定,A103-2 轮询兜底与 B901 共用同一 `unlockBill()` 方法,B901 后续接入时零改动复用。 + +### 3.2 判定规则:"连续两轮查询消失" + +| 要素 | 规则 | +|---|---| +| 判定对象 | 本轮 A103-2 批量查询中未查得的、本地状态为 **synced / paying** 的单据 | +| 健康前提 | 同批次其余付款申请号正常返回(A103-2 服务整体故障时整轮抛异常,不做消失判定) | +| 排除对象 | failed(金蝶查不到属正常态,等待人工重推)、终态 paid/closed(不参与轮询)、paymentNo 为空(防御) | +| 计数存储 | Redis `transport:payment-application:kingdee-pay-miss:{付款申请id}`,每轮未查得 `INCR`,TTL 2100s(覆盖 3 个 10 分钟回写周期;任务中断超时后计数自然过期,需重新累计,方向保守) | +| 查得即清零 | A103-2 查得该单 → `DEL` 计数键 | +| 解锁阈值 | 连续计数 ≥ 2 轮 → 调用 `unlockBill(id, "A103-2 连续N轮查询消失")` | +| Redis 异常 | 放弃本轮判定(解锁会清空金蝶单号,属破坏性动作,宁可延迟不可误判) | + +### 3.3 `unlockBill()` 语义(ADR-0005,接口方法,B901 可直接复用) + +前置:仅 synced / paying 生效;failed 与终态单据自动跳过。 + +动作(单据级事务,条件更新防并发): + +1. 清除消失计数键; +2. `kingdee_status`:synced/paying → **failed(生成失败)**; +3. `kingdee_bill_id`、`kingdee_bill_no` **清空**(原值 warn 日志留档;金蝶侧单据已删除,原内码对 A902 附件、A103-4 勾稽均已失效); +4. **不自动重推**——金蝶反审核删除大概率伴随驳回意见,原样重推等于无视驳回(ADR-0005),置 failed 回人工。 + +### 3.4 重推闭环与误判安全网 + +解锁后单据进入 failed,与"推送异常"恢复路径完全合并: + +```mermaid +sequenceDiagram + participant T as TMS 定时回写(A103-2) + participant R as Redis 计数 + participant K as 金蝶(星瀚) + participant U as 人工 + + T->>K: A103-2 按 paymentNo 批量查询 + K-->>T: 某单未查得(同批其余正常) + T->>R: INCR 消失计数(第1轮,仅告警) + T->>K: 下一轮再查仍未见 + T->>R: INCR 计数 ≥ 2 + T->>T: unlockBill():status=failed、清单号/内码(日志留档) + U->>U: 核实金蝶确已删除(驳回原因) + U->>T: 「同步金蝶」重新推送 + T->>K: A103-2 勾稽预检(failed 恢复场景) + alt 金蝶侧单据实际存在(误判) + K-->>T: 命中 → 回填单据id/编号,跳过推送(不产生重复单据) + else 确已删除 + K-->>T: 未命中 → A103-3 重新保存,生成新单 + T->>K: A902 附件上传到新单 + end +``` + +要点:**即使误判解锁,重推链的 A103-2 勾稽预检也能兜底**——预付款路径 failed 恢复场景必经 `reconcileExistPayApply`,正式路径推送前统一预检,命中即回填跳过,不会产生重复单据。 + +### 3.5 涉及代码 + +| 位置 | 内容 | +|---|---| +| `IPaymentApplicationService#unlockBill(Long id, String source)` | 新增接口方法(B901 接入时复用) | +| `PaymentApplicationServiceImpl#unlockBill` | 解锁实现(事务 + 条件更新) | +| `PaymentApplicationServiceImpl#handlePayApplyMissed` | 消失轮次判定(回写主流程接入) | +| `executePaymentResultSync` ① 循环 | `payApply == null` → `handlePayApplyMissed`;查得 → `clearPayApplyMissKey` | + +## 4. 改造三:定时回写默认开启 + +| 位置 | 变更 | +|---|---| +| `PaymentKingdeeResultTask` | 注释纠正为"代码默认关闭(安全兜底),由 Nacos 按环境显式开启"(`@Value` 兜底默认保持 `false`) | +| `doc/nacos/blade-dev.yaml` / `blade-prod.yaml` / `third-party-api.yaml` | `syncEnabled: ${BFI_PAY_RESULT_SYNC_ENABLED:true}`——**环境配置默认开启**,未部署 Nacos 配置时代码兜底关闭 | + +- 调度频率不变:`0 */10 * * * ?`(每 10 分钟)。 +- 环境变量 `BFI_PAY_RESULT_SYNC_ENABLED=false` 仍可显式关闭(灰度/演练用)。 +- 消失解锁依赖该任务运行,开关关闭期间兜底判定同步停摆(预期行为)。 + +## 5. 状态机全景(变更后) + +``` +unsynced ─A103-1/A103-3─▶ synced ─Inpayment─▶ paying ─Alreadypay─▶ paid(终) + │ ▲ │ + │ └─ A103-2 勾稽纠偏 ──┘ + ├─ 连续两轮查询消失 / B901 UNLOCK ─▶ failed ─人工重推─▶ synced +推送异常 ─────────────────────────────────────────────────────▶ failed +billstatus=D ──────────────────────────────────────────────────▶ closed(终) +``` + +- 解锁后 `kingdee_bill_id/no` 清空 → A103-2/A103-4 后续轮询按 paymentNo 重新勾稷新单; +- failed 纳入轮询的既有纠偏逻辑与解锁路径互不冲突(failed 查不到不计数、查到回填 synced)。 + +## 6. 配置项汇总 + +| 配置 | 默认 | 说明 | +|---|---|---| +| `thirdParty.bfi.payResult.syncEnabled` | Nacos 配置 `true`;代码兜底 `false` | 回写任务总开关,关闭则状态回写与消失解锁同时停摆 | +| `thirdParty.bfi.payResult.cron` | `0 */10 * * * ?` | 回写周期,同时决定消失解锁的轮次间隔 | +| `thirdParty.bfi.payResult.lockLeaseSeconds` | `1800` | 回写 single-flight 锁租约 | +| Redis 键 `transport:payment-application:kingdee-pay-miss:{id}` | TTL 2100s | 消失轮次计数,无配置项(常量) | + +## 7. 验证要点 + +1. **联行号拦截**:收款账户未维护联行号的预付款点击"同步金蝶" → 报"收款账户未维护联行号"且不产生金蝶单据;维护后重推成功,A103-2 查回的 `e_bebank_number` 为联行号。 +2. **消失解锁**:推送成功(synced)→ 金蝶侧反审核并删除该付款申请单 → 等待 ≥2 个回写周期 → 日志出现"第1轮/连续2轮",单据变 failed、`kingdee_bill_id/no` 清空。 +3. **误判回填**:解锁后金蝶侧单据实际存在(构造 A103-2 两次查询异常)→ 人工重推 → 勾稽命中回填,金蝶侧不出现重复单据。 +4. **开关回归**:`BFI_PAY_RESULT_SYNC_ENABLED=false` 环境变量能覆盖默认值关闭任务。 + +## 8. 遗留事项(不在本方案范围) + +| # | 事项 | 状态 | +|---|---|---| +| 1 | B901 UNLOCK 回调接入(解锁延迟从 ≤2 个回写周期缩短为事件即时) | 待建设,复用 `unlockBill()` 零改动 | +| 2 | closed 终态(金蝶驳回/关闭)票据额度释放与待处理提醒 | 未实现 | +| 3 | A103-3 预付款不传 `awrpSrcConNo`(合同号)是否符合金蝶勾稽要求 | 待联调确认 | +| 4 | A103-2 查询未传 modifytime 时间窗(接口约束 ≤1 个月)是否放行 | 待联调确认 |