:docs: 更新HCS特批结果回传机制相关文档
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
| D12 | 开票登记时机 | 审批通过即推 C111-2(票据日期空);金蝶开票完成后 C111-3 回填 |
|
||||
| D13 | 收票合同关联 | 应付结算链路自动回溯;回溯不到收票表单加合同字段人工补录 |
|
||||
| D14 | 来源标识 | `fd_sources="WLTMS"`(Nacos `src-system` 可配);`fd_kingdee_id`=TMS 业务单据主键 |
|
||||
| D15 | 特批载体 | 付款申请表加 `hcs_credit_*`/`hcs_spec_*` 字段组;C106-1 提交时同步;超额转 C106-3;**特批结果回传方式未决**(过渡:页面人工确认);合同 `fdSepcailContract` 一期固定 false |
|
||||
| D15 | 特批载体 | 付款申请表加 `hcs_credit_*`/`hcs_spec_*` 字段组;C106-1 提交时同步;超额转 C106-3;~~特批结果回传方式未决~~ **已决(2026-10-12):合规经 contractLegal/paymentLegal result 接口推送 TMS**;合同 `fdSepcailContract` 一期固定 false |
|
||||
|
||||
---
|
||||
|
||||
@@ -306,7 +306,7 @@ flowchart LR
|
||||
|
||||
`mechanisms.attachment`:`attachmentsJson` 经 C103-2 转传,特批附件 `fdEntityKey=fd_spc_approval_attach` 且带 `fdBindType=ADD`。更新(C106-4):单据变更且特批流程存在时调用,顶层 `fdId=hcs_spec_fd_id`,附件不带 fdBindType。
|
||||
|
||||
**特批结果**:v4 无结果查询/回调接口 → `approved/rejected` 一期由页面人工确认(未决 §9-U1)。
|
||||
**特批结果**:v4 无结果查询/回调接口 → 一期由页面人工确认;**2026-10-12 已决**:合规审批完成后经 `POST /hcs/paymentLegal/result` 主动推送 TMS(`requestId`=付款申请ID,`status=APPROVED/REJECTED`),人工确认保留等效兜底(§9-U1 闭环)。
|
||||
|
||||
### 5.6 履约记录(C108-1/2 ← PaymentApplication,D11)
|
||||
|
||||
@@ -415,7 +415,7 @@ thirdParty:
|
||||
|
||||
| # | 事项 | 影响 |
|
||||
|---|---|---|
|
||||
| U1 | **特批流程结果回传方式**:v4 无查询/回调接口 | 特批 approved/rejected 一期人工确认 |
|
||||
| U1 | **特批流程结果回传方式**:v4 无查询/回调接口 → **已决(2026-10-12)**:合规经 `contractLegal/result`(合同)/`paymentLegal/result`(付款)主动推送 TMS | 推送接收端点已实现(PERMIT_ALL);人工确认保留等效兜底 |
|
||||
| U2 | 组织/人员引用体系:HCS `{fdId,fdName}` 的 fdId 与 TMS 部门ID 不同源;登录名是否同源(见原文登录名截图) | 立项/合同操作人字段解析方式 |
|
||||
| U3 | 字典值映射:fd_settlement_type、fd_invoice_type、付款用途/性质/类型、CONTRACT_STATUS 是否必传 | 各映射配置 |
|
||||
| U4 | C103-3/C102-3/C111-1 conditions 是否支持 fdNumber/fd_num/fdKingdeeId 精确查询;HCS 是否按 fd_kingdee_id 幂等 | 判重与防重方案 |
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
| `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/contractLegal/result` | 合同特批结果回传接收(合规推送,PERMIT_ALL,2026-10-12 替代 B103) |
|
||||
| `POST /hcs/paymentLegal/result` | 付款特批结果回传接收(合规推送,PERMIT_ALL) |
|
||||
| `POST /hcs/master-data/refresh` | 刷新主数据缓存并校验模板映射 |
|
||||
| `GET /hcs/recon/project?projectCode=` | 项目立项对账(C102-3) |
|
||||
| `GET /hcs/recon/contract?contractNo=` | 合同对账(C103-3) |
|
||||
@@ -126,7 +128,7 @@
|
||||
|
||||
| # | 事项 | 当前代码/配置占位 |
|
||||
|---|---|---|
|
||||
| U1 | 特批流程结果回传方式 | 人工确认端点 `POST /hcs/spec-pay/confirm`(过渡方案);若有回调/查询接口需改造 |
|
||||
| U1 | ~~特批流程结果回传方式~~ **已决(2026-10-12)**:合规经 `POST /hcs/contractLegal/result`、`POST /hcs/paymentLegal/result` 主动推送结果(报文 `{sourceSystem, requestId, status=APPROVED/REJECTED, reason}`) | 人工确认端点保留作等效兜底;原 B103 推测性回调端点 `/hcs/callback/spec-result` 已删除 |
|
||||
| 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(文档示例如此) |
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
| C103-3 合同列表查询 | `GET /hcs/recon/contract` 已有 | 已有 | 合同列表"合规对账"弹窗 |
|
||||
| C103-4 合同详情查询 | `GET /hcs/recon/contract/detail` 已有 | 已有 | 对账弹窗"查看合规详情" |
|
||||
| C103-5 合同附件下载 | 仅 Feign 端点 | **`GET /hcs/attachment/download`(新增)** | 对账弹窗/合同详情中下载 HCS 侧附件 |
|
||||
| C103-8 合同发起特批 | **本期正式接入**(业务闭环见集成流程梳理:高风险客商签约必走;B103 结果回传) | **`POST /hcs/contract/spec-apply`(新增)+ `POST /hcs/callback/spec-result`(B103 接收,新增)** | 合同详情"发起特批"、特批状态展示、回传后自动恢复推送 |
|
||||
| C103-8 合同发起特批 | **本期正式接入**(业务闭环见集成流程梳理:高风险客商签约必走;结果经 contractLegal/result 推送,2026-10-12 替代 B103) | **`POST /hcs/contract/spec-apply`(新增)+ `POST /hcs/contractLegal/result`(结果推送接收,新增)** | 合同详情"发起特批"、特批状态展示、结果推送后自动恢复展示 |
|
||||
|
||||
---
|
||||
|
||||
@@ -77,7 +77,7 @@ GET /hcs/risk?customerCode=...
|
||||
|
||||
> 前端仅用于**展示与提示**,不作为安全边界:强制校验仍在合同推送链路(`risk.block-blacklist`)与付款提交事务内。
|
||||
|
||||
### 3.4 合同发起特批(C103-8)+ 结果回传(B103)——本期正式接入
|
||||
### 3.4 合同发起特批(C103-8)+ 结果推送接收(contractLegal/result)——本期正式接入
|
||||
|
||||
**业务闭环**(依据《TMS业财融合-集成流程图文字版与业务流程梳理.md》§3.3/§8):
|
||||
|
||||
@@ -88,8 +88,8 @@ GET /hcs/risk?customerCode=...
|
||||
→ TMS 内部特批审批(按原审批流)
|
||||
→ 前端补特批申请材料 + 内部审批流程附件 → C103-8 发起特批(hcs_spec_status=processing)
|
||||
→ 合同系统集团审批(流程在合同系统预配置)
|
||||
→ B103 特批结果回传 TMS(hcs_spec_status=approved/rejected)
|
||||
→ approved → 自动恢复 C103-1 推送 → 完成签订;rejected → 前端提示,重新发起
|
||||
→ 合规推送特批结果 TMS:POST /hcs/contractLegal/result(hcs_spec_status=approved/rejected)
|
||||
→ approved → 恢复"审批通过"展示(C103-1 已起草,无需再推送)→ 完成签订;rejected → 前端提示,重新发起
|
||||
```
|
||||
|
||||
**数据模型**:`blade_contract_manage` 追加特批字段组(照付款申请 `hcs_spec_*` 惯例),SQL 落 `doc/sql/transport/`:
|
||||
@@ -112,12 +112,12 @@ POST /hcs/contract/spec-apply (body:{ contractId, attachments: [{fdId,
|
||||
→ 返回 data.fdId → hcs_spec_fd_id,状态置 processing;失败置 need 并记 hcs_spec_msg
|
||||
→ C103-8 v4 未含报文,联调前按上述预估实现并加 TODO 标注(§7-U1)
|
||||
|
||||
POST /hcs/callback/spec-result (B103 合规→TMS 回调接收端点)
|
||||
公开端点(@PreAuth(AuthConstant.PERMIT_ALL) + 报文验签字段待合规方口径,先记录原文留痕)
|
||||
body:{ 合同标识/特批流程fdId, 审批结果, 审批意见 } ← 字段名待 B103 报文(§7-U1)
|
||||
处理:定位合同 → 回写 hcs_spec_status=approved/rejected + hcs_spec_msg
|
||||
→ approved 时把合同 hcs_sync_status 重置 unsynced,由既有扫描任务自动走 C103-1(零新增链路)
|
||||
→ B103 报文未到位前端点先落库留痕不置状态,联调时接线
|
||||
POST /hcs/contractLegal/result (合规系统推送特批结果,2026-10-12 替代未建设的 B103)
|
||||
公开端点(@PreAuth(AuthConstant.PERMIT_ALL)),iPaaS 网关注册映射 /gwzh/HTHG/contractLegal/result → 本端点
|
||||
body(HcsLegalResultDTO):{ sourceSystem="WLTMS", requestId=TMS合同ID, status=APPROVED|REJECTED, reason }
|
||||
处理:按 requestId 定位合同 → status 大小写不敏感识别 → 回写 hcs_spec_status + 原文(含 reason)留痕 blade_hcs_check_log
|
||||
→ approved 恢复 currentNode="审批通过"(C103-1 已起草,无需再推送);rejected 联动审批驳回,reason 随原文见 hcs_spec_msg
|
||||
→ 未定位到合同/状态未识别仅留痕返回,不报错
|
||||
```
|
||||
|
||||
**状态展示与操作权限**:
|
||||
@@ -230,7 +230,7 @@ export const applyContractSpec = data =>
|
||||
- **入口**:合同详情页【发起特批】按钮,仅 `hcsSpecStatus ∈ {need, rejected}` 时可用;权限码 `hcs_spec_apply`。
|
||||
- **交互**:弹窗选择/确认特批申请材料(先经 §4.5 `uploadAttachment` 取 fdId,弹窗内表格展示已传材料,含内部审批流程附件)→ 确认调 `applyContractSpec({ contractId, attachments })` → 成功后详情刷新为"特批中"。
|
||||
- **状态展示**:合同列表与详情按 §3.4 状态表展示特批标签(need/processing/approved/rejected);`need` 时列表"推送合规"按钮禁用并 tooltip 提示。
|
||||
- **结果回传**:B103 回调由后端接收并自动恢复推送,前端无需轮询;详情页打开时实时拉取最新状态即可,`rejected` 时展示 `hcsSpecMsg` 驳回原因。
|
||||
- **结果推送**:合规推送(`/hcs/contractLegal/result`)由后端接收并自动联动状态,前端无需轮询;详情页打开时实时拉取最新状态即可,`rejected` 时展示 `hcsSpecMsg` 驳回原因。
|
||||
|
||||
---
|
||||
|
||||
@@ -241,7 +241,7 @@ export const applyContractSpec = data =>
|
||||
| F1 基础 | `GET /hcs/master-data/template` + `@PreAuth`/菜单 SQL | `api/business/hcs.js`;管理端主数据页 | 无 |
|
||||
| F2 状态与推送 | 无(端点已有) | 两列表页:状态列/筛选 + 推送合规按钮 | F1(hcs.js) |
|
||||
| F3 对账与附件 | `/hcs/risk`、`/hcs/attachment/upload`、`/hcs/attachment/download` | 对账弹窗 + 合规附件下载 + 手动转传 + 附件行 `hcsFdId` | F2 |
|
||||
| F4 特批 | 合同特批字段组 SQL;`POST /hcs/contract/spec-apply` + `POST /hcs/callback/spec-result`(B103);合同推送链路加 need 挂起判断 | 发起特批弹窗 + 特批状态标签 + 按钮联动 | C103-8/B103 报文(§7-U1,可先按预估模式实现联调替换) |
|
||||
| F4 特批 | 合同特批字段组 SQL;`POST /hcs/contract/spec-apply` + `POST /hcs/contractLegal/result`(合规结果推送接收,2026-10-12 替代 B103);合同推送链路加 need 挂起判断 | 发起特批弹窗 + 特批状态标签 + 按钮联动 | C103-8 报文(§7-U1,可先按预估模式实现联调替换);结果推送报文已定(requestId/status/reason) |
|
||||
| F5 即时推送(2026-10-10 增补,纯后端) | `HcsImmediatePushSupport` + 4 处审批入口触发(§6.3)+ 开关配置 | 无 | 无(复用既有 Support,扫描兜底保留) |
|
||||
|
||||
---
|
||||
@@ -305,6 +305,6 @@ public void pushContractAfterCommit(Long id) // 合同 C103
|
||||
|
||||
| # | 事项 | 影响 | 当前处理 |
|
||||
|---|---|---|---|
|
||||
| U1 | **C103-8 / B103 报文 v4 未提供**(业务闭环已在集成流程梳理中明确) | 特批发起与结果回传的报文字段 | 按 C106-3 模式预估实现 + 回调端点先落库留痕;联调拿到报文后替换(代码已留 TODO) |
|
||||
| U1 | ~~C103-8 / B103 报文 v4 未提供~~ → **C103-8 报文仍待联调;结果回传已决(2026-10-12)**:B103 不建设,合规经 `contractLegal/result`/`paymentLegal/result` 推送结果(报文已定) | C103-8 发起报文字段 | 发起仍按 C106-3 模式预估(代码留 TODO);结果接收已按定稿报文实现(`HcsLegalResultDTO`) |
|
||||
| U2 | **C103-5 返回流是否带文件名**(v4 仅写"文件流") | 下载文件命名 | 后端以附件元数据/`fdId` 兜底命名,联调校准 |
|
||||
| U3 | 合规状态列/菜单权限是否需要按租户差异化 | 菜单 SQL | 先按统一菜单落地 |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 新建合同推送 HCS(合同合规系统)流程梳理
|
||||
|
||||
> 依据代码现状整理,核心类:`HcsContractSyncSupport`(blade-service/blade-transport/.../support/hcs)。
|
||||
> 对接接口:C101-1 风险校验、C103-2 附件上传、C103-3 合同判重、C103-1 合同发起、C103-11 合同更新、C103-8 特批、C103-9 履约规则。
|
||||
> 对接接口:C101-1 风险校验、C103-2 附件上传、C103-3 合同判重、C103-1 合同发起、C103-11 合同更新、C103-8 特批、C103-9 履约规则;特批结果接收 `/hcs/contractLegal/result`(合规推送,替代未建设的 B103,见 §9.4)。
|
||||
> "必填" 标注来源:代码注释中标注的 v4 接口文档要求(HCS 侧),以及 TMS 推送前强校验(缺失直接失败)。
|
||||
|
||||
---
|
||||
@@ -155,7 +155,7 @@
|
||||
| `hcs_spec_status` / `hcs_spec_time` / `hcs_spec_msg` | 特批状态(none/need/processing/approved/rejected)及留痕 |
|
||||
| `hcs_spec_fd_id` | 特批流程ID(C103-8 返回) |
|
||||
| `hcs_spec_files_json` | 特批申请材料JSON(含 C103-2 合规附件ID) |
|
||||
| `current_node` | 挂起展示节点:自动特批后置"特批审核",B103 通过恢复"审批通过",驳回置"已驳回" |
|
||||
| `current_node` | 挂起展示节点:自动特批后置"特批审核",合规推送特批通过恢复"审批通过",驳回置"已驳回" |
|
||||
|
||||
风险校验明细另写 `blade_hcs_check_log`(甲方/乙方各一条,含 traceId)。
|
||||
|
||||
@@ -201,11 +201,20 @@ TMS 审批通过(approved / change_approved)
|
||||
- 特批已通过(approved,单次有效)的合同推送/变更不重复发起特批;
|
||||
- C103-8 发起失败保持 need 仅留痕,人工经 `/hcs/contract/spec-apply`(详情页"发起特批"按钮)重发。
|
||||
|
||||
### 9.4 特批结果联动(B103 回传 / 人工确认等效)
|
||||
### 9.4 特批结果联动(合规推送 contractLegal/result / 人工确认等效)
|
||||
|
||||
**结果接收机制(2026-10-12 变更)**:原计划的 B103 推送合规方未建设,改为合规系统审批完成后经 iPaaS 网关调用 TMS 接收回传结果:
|
||||
|
||||
| 接口 | 定位方式 | 处理 |
|
||||
| --- | --- | --- |
|
||||
| `POST /hcs/contractLegal/result`(公开端点,网关注册映射 `/gwzh/HTHG/contractLegal/result`) | `requestId` = TMS 合同ID | 合同特批结果联动 |
|
||||
| `POST /hcs/paymentLegal/result`(公开端点,网关注册映射 `/gwzh/HTHG/paymentLegal/result`) | `requestId` = TMS 付款申请ID | 付款特批回写 `hcs_spec_status`(不联动付款审批状态) |
|
||||
|
||||
报文两接口共用(`HcsLegalResultDTO`):`{sourceSystem, requestId, status, reason}`;`status=APPROVED`(通过)/ `REJECTED`(驳回,reason 为驳回原因如"特批说明材料不完整,请补充"),大小写不敏感识别,其他值仅留痕不落状态。报文原文(含 reason)全量留痕 `blade_hcs_check_log`;未定位到单据或状态未识别时仅留痕返回,不报错。
|
||||
|
||||
| 特批结果 | 合同联动 |
|
||||
| --- | --- |
|
||||
| approved | `currentNode` 恢复"审批通过"(C103-1 已起草,hcs_sync_status 保持 synced,无需再推送) |
|
||||
| rejected | `approvalStatus=rejected` + `currentNode="已驳回"`,走重新编辑 → 提交 → 审批 → 重新特批闭环(重新推送时 C103-11 更新后再次自动特批) |
|
||||
| rejected | `approvalStatus=rejected` + `currentNode="已驳回"`,走重新编辑 → 提交 → 审批 → 重新特批闭环(重新推送时 C103-11 更新后再次自动特批),reason 随原文见 `hcs_spec_msg` |
|
||||
|
||||
> 缺口:v4 无特批结果主动查询接口(§9-U1),结果依赖 B103 回调(`POST /hcs/callback/spec-result`)或页面人工确认(`POST /hcs/contract/spec/confirm`),合规方提供查询能力后可增轮询兜底。
|
||||
> 等效兜底:页面人工确认(`POST /hcs/contract/spec/confirm`,合同)与(`POST /hcs/spec-pay/confirm`,付款)与合规推送等效,二者均以先到为准。原推测性接收端点 `POST /hcs/callback/spec-result`(B103 候选键解析)已删除。
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
# 合同特批与付款(结算付款)特批流程梳理
|
||||
|
||||
> 梳理日期:2026-10-12
|
||||
> 涉及模块:`blade-service/blade-transport`(业务编排/状态留痕)、`blade-third-party-api/blade-hcs-api`(Feign 客户端 + DTO + 配置)
|
||||
> 关联设计文档:`doc/docs/hcs合同/2026-10-11-hcs合同推送流程梳理.md`(§九)、`2026-09-27-桂物合同合规系统HCS接入技术设计.md`(§5.4/§5.5)
|
||||
> 关联提交:`8e6e263`(外部客商高风险黑名单管控与合同自动特批)
|
||||
>
|
||||
> **2026-10-12 变更**:原计划的 B103 推送合规方未建设,特批结果改为合规审批完成后经 iPaaS 主动推送 TMS:合同 `POST /hcs/contractLegal/result`、付款 `POST /hcs/paymentLegal/result`(报文 `{sourceSystem, requestId, status=APPROVED/REJECTED, reason}`);原推测性回调端点 `/hcs/callback/spec-result` 及 `HcsFieldConstant.SPEC_CB_*` 候选键解析已删除。见 §2.5/§4.4/§五。
|
||||
|
||||
---
|
||||
|
||||
## 一、总览:特批的业务含义
|
||||
|
||||
本文所述"特批"**不是 TMS 本地审批流**(本地审批走 `approvalStatus`/`currentNode`),而是**向集团合规系统 HCS 发起的特殊审批流程**:TMS 侧仅负责发起、留痕、挂起展示并接收结果,审批动作本身在 HCS 内完成。
|
||||
|
||||
### 1.1 触发条件(仅两类,与金额阈值、超权限无关)
|
||||
|
||||
| 触发线 | HCS 接口 | 判定条件 | 触发的特批 | 作用对象 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 外部客商高风险/黑名单 | C101-1 风险查询 | `fdRiskLevel=2`(高风险)或 `fdBlackStatus=yes`(黑名单) | 合同特批(C103-8 发起 / contractLegal/result 结果推送) | `ContractManage`(合同) |
|
||||
| 合同额度超额 | C106-1 额度校验 | `fdIsCredit=false`(超额) | 结算付款特批(C106-3 发起 / C106-4 更新) | `PaymentApplication`(付款申请) |
|
||||
|
||||
补充规则:
|
||||
|
||||
- **内部组织客商不查**:`CustomerArchive.customerKind=internal` 默认无风险(`HcsSyncConstant.CUSTOMER_KIND_INTERNAL`)。
|
||||
- **甲/乙任一方命中即整单管控**(`HcsSyncConstant.java:151-176`)。
|
||||
- **付款链路中黑名单不是特批而是直接阻断**:`risk.block-blacklist=true`(默认)时提交付款申请直接抛异常,不走特批。
|
||||
|
||||
### 1.2 与普通审批的关系
|
||||
|
||||
特批挂在 TMS 审批**之后**(合同须先审批通过并成功推送 HCS 起草,拿到 `hcs_fd_id` 后才能发起特批)。特批期间 TMS 用 `hcs_spec_status ∈ {need, processing}` + `currentNode="特批审核"` 挂起展示,推送门禁跳过;特批通过即放行,驳回则联动本地审批驳回(仅合同链路)。
|
||||
|
||||
### 1.3 特批状态机(两条链路共用 `HcsSyncConstant.SPEC_STATUS_*`)
|
||||
|
||||
```
|
||||
none(默认) ──触发──▶ need(挂起"特批审核")──发起成功──▶ processing(HCS 流程进行中)──结果──▶ approved / rejected
|
||||
└─发起失败──▶ 回落 need(仅留痕,可人工重发)
|
||||
```
|
||||
|
||||
- 合同特批 `approved` **单次有效**:再次推送时若已 approved 不重复发起。
|
||||
- 付款特批 `approved/rejected` **不联动付款审批状态**(无驳回联动),仅人工确认。
|
||||
|
||||
---
|
||||
|
||||
## 二、合同特批(C103-8 发起 / contractLegal/result 结果推送)
|
||||
|
||||
### 2.1 触发条件
|
||||
|
||||
外部客商高风险(风险等级=2)或黑名单,甲方或乙方任一方命中。风险判定:`HcsContractSyncSupport#checkRelativeRisk`(`HcsContractSyncSupport.java:167-183`,`risky` 判定在 :178)。
|
||||
|
||||
### 2.2 阶段 A:提交校验(特批说明附件必传)
|
||||
|
||||
入口 `ContractManageController`(`@RequestMapping("/contract-manage")`):
|
||||
|
||||
| 接口 | Service 方法 | 校验调用 |
|
||||
| --- | --- | --- |
|
||||
| `POST /contract-manage/submit` | `ContractManageServiceImpl#submit`(:146) | :161 |
|
||||
| `POST /contract-manage/to-temporary` | `#toTemporary`(:178) | :185 |
|
||||
| `POST /contract-manage/submit-formal` | `#submitFormal`(:198) | :205 |
|
||||
|
||||
三处均调用 `validateSpecExplanationOnSubmit`(:1048-1061):
|
||||
|
||||
1. `isRiskyCustomer`(:1066-1071)→ `HcsCreditCheckSupport#queryCustomerRiskByName`(:240)→ `queryCustomerRisk`(:182-231)**实时调 C101-1**(`hcsClient.getRelativeRisk`);内部组织客商直接返回不命中;名称反查不到客商编号不阻断(:242-248)。
|
||||
2. 命中且 `attachmentsJson` 中无 `fileType=特批说明`(`attachmentType=spec_explanation`)附件 → 抛出:"合同相对方存在高风险/黑名单客商,必须上传「特批说明」类型附件后再提交审批"。
|
||||
|
||||
> 已知缺口:`submitChange`(:303)未调用该校验;`submit()` 中"变更驳回重提交"分支(:150-155)转入 `submitChange`,会绕过附件强校验——推送后自动特批链路仍会兜底挂起,但附件缺失会导致特批发起失败。
|
||||
|
||||
### 2.3 阶段 B:审批通过 → 推送 → 自动特批
|
||||
|
||||
审批通过:`POST /contract-manage/approve` → `ContractManageServiceImpl#approve`(:217-245):置 `hcsSyncStatus=unsynced`(:237,推送零埋点 ADR-0001)→ `hcsImmediatePushSupport.pushContractAfterCommit(id)`(:243)。
|
||||
|
||||
合同推送共 3 个入口,收敛到 `HcsContractSyncSupport#pushContract`(:113-158):
|
||||
|
||||
| 入口 | 位置 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 即时推送 | `HcsImmediatePushSupport#pushContractAfterCommit`(:114) | afterCommit 异步(2 线程 daemon 池),开关 `push.immediate-enabled` 默认 false;`pushContractNow`(:178)对特批挂起中(need/processing)短路跳过(:185-188) |
|
||||
| 定时扫描 | `HcsPushTask#pushHcsContract`(:155,cron 默认 `0 1/5 * * * ?`) | `pushUnsyncedContracts`(:254-278):`approvalStatus ∈ {approved, change_approved}` 且 `hcs_sync_status ∈ {unsynced, failed}` 且重试未超限 |
|
||||
| 手动重推 | `HcsSyncController POST /hcs/sync/contract/{id}`(:110)→ `repushContract`(:509-530) | 特批挂起中不可推(:517-519) |
|
||||
|
||||
`pushContract` 内部步骤(与本文相关的 ⑤):
|
||||
|
||||
```
|
||||
⓪ 特批挂起门禁(need/processing 直接返回,:118-121)
|
||||
① 风险校验仅留痕(:124-126,回写 hcs_risk_level / hcs_black_status / hcs_risk_time)
|
||||
②③④ 附件转传 C103-2 / 判重 / C103-1 起草或 C103-11 更新,markSynced 回填 hcs_fd_id(:535)
|
||||
⑤ risky 时 autoApplySpecIfNeeded(:190-212)——自动特批链路
|
||||
```
|
||||
|
||||
`autoApplySpecIfNeeded`(:190-212):
|
||||
|
||||
1. 特批已通过(`hcs_spec_status=approved`,单次有效)→ 跳过(:191-195);
|
||||
2. 置 `hcsSpecStatus=need` + `currentNode="特批审核"`(`SPEC_REVIEW_NODE`,:196-201)——**先挂起后特批**;
|
||||
3. `transferSpecExplanationAttachments`(:218-242)筛选「特批说明」附件转传 C103-2(合规附件 ID 存入 `hcs_spec_files_json`);
|
||||
4. 调 `hcsContractSpecSyncSupport.applySpec(...)`(:207)发起 C103-8;失败保持 `need` 仅留痕(:208-211),可人工经 `POST /hcs/contract/spec-apply` 重发。
|
||||
|
||||
> 设计要点(`HcsContractSyncSupport.java:56-58` 注释):C103-8 必须携带已起草合同的 `hcs_fd_id`,因此顺序是 **先 C103-1 起草、后 C103-8 特批**(8e6e263 调整)。
|
||||
|
||||
### 2.4 阶段 C:发起特批 C103-8
|
||||
|
||||
`HcsContractSpecSyncSupport#applySpec`(`HcsContractSpecSyncSupport.java:92-130`):
|
||||
|
||||
- 前置:`requireAppliableContract`(:196-208,须审批通过 + 特批状态 need/rejected)、附件非空(:94-96)、`requireContractFdId`(:213-218,须已有 `hcs_fd_id`);
|
||||
- 组装 `HcsSpecContractSaveDTO`:`fdDocSubject="合同特批-{合同编号}"`、`fdReason=合同名称`、附件 `fdEntityKey=fd_spc_approval_attach`(:97-111);
|
||||
- `hcsClient.addSpecContract`(`IHcsClient.java:281`,`SPEC_CONTRACT_ADD_URL`)响应双层嵌套 `data.data.fdId` → 回填 `hcs_spec_fd_id`(:117),`markSpec` 置 `processing`(:118);
|
||||
- 留痕 `blade_hcs_check_log`(biz_type=`contract`,check_type=`spec`,:335-350);失败回 `need`(:125)。
|
||||
|
||||
### 2.5 阶段 D:结果联动(两条等效路径)
|
||||
|
||||
| 路径 | 接口 | 实现 |
|
||||
| --- | --- | --- |
|
||||
| 合规推送 | `POST /hcs/contractLegal/result`(`HcsSyncController`,`@PreAuth(PERMIT_ALL)`,网关注册 `/gwzh/HTHG/contractLegal/result`) | `handleLegalResult`:`requestId`=合同ID(selectById)定位 → `status=APPROVED/REJECTED` 大小写不敏感识别(其他值仅留痕)→ 原文(含 reason)留痕,报文模型 `HcsLegalResultDTO` |
|
||||
| 人工确认 | `POST /hcs/contract/spec/confirm`(:251-257) | `confirmSpecResult`(:139-157,仅 processing 可确认) |
|
||||
|
||||
联动 `syncContractOnSpecResult`(:312-320):
|
||||
|
||||
- `approved` → `currentNode="审批通过"`(C103-1 已起草,无需再推送,流程放行);
|
||||
- `rejected` → `approvalStatus=rejected` + `currentNode="已驳回"`,走"重新编辑 → 提交 → 审批 → 重新特批"闭环。
|
||||
|
||||
`markSpec`(:325-330)回写 `hcs_spec_status`/`hcs_spec_time`/`hcs_spec_msg`,回调原文留痕。
|
||||
|
||||
### 2.6 TMS 侧留痕字段(`blade_contract_manage`,`ContractManage.java:45`)
|
||||
|
||||
| 字段 | 位置 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `hcs_fd_id` | :213 | HCS 合同 ID(C103-1 起草回填) |
|
||||
| `hcs_risk_level` / `hcs_black_status` / `hcs_risk_time` | :233/:236/:239 | C101-1 风险留痕 |
|
||||
| `hcs_spec_fd_id` | :242 | HCS 特批流程 ID(C103-8 回填) |
|
||||
| `hcs_spec_status` | :246 | `none/need/processing/approved/rejected` |
|
||||
| `hcs_spec_time` / `hcs_spec_msg` | :249/:253 | 特批时间/信息 |
|
||||
| `hcs_spec_files_json` | :256 | 特批材料(含 C103-2 合规附件 ID) |
|
||||
| `current_node` | — | 挂起展示:`特批审核` / `审批通过` / `已驳回` |
|
||||
|
||||
---
|
||||
|
||||
## 三、付款特批(付款申请提交触发侧)
|
||||
|
||||
### 3.1 入口与触发
|
||||
|
||||
`PaymentApplicationController`(`/payment-application`)`POST /submit` → `PaymentApplicationServiceImpl#submit`(`PaymentApplicationServiceImpl.java:316-335`),事务内 :329 调 `HcsCreditCheckSupport#checkOnSubmit(entity)`(`HcsCreditCheckSupport.java:89-99`),依次执行两项校验:
|
||||
|
||||
**① C101-1 收款方风险校验**(开关 `risk.check-on-payment` 默认 true,:91)
|
||||
|
||||
- `checkRelativeRisk`(:104-131):按收款方 `payeeName` 反查 `CustomerArchive` 客商编号 → C101-1 实时查询;
|
||||
- **黑名单且 `risk.block-blacklist=true`(默认 true)→ 直接阻断**:抛"收款方客商黑名单,禁止提交付款申请"(:127-129)——付款链路黑名单不走特批;
|
||||
- 反查不到客商编号记 skip 留痕、不阻断(:106-110)。
|
||||
|
||||
**② C106-1 合同额度校验**(开关 `credit.check-enabled` 默认 false,**一期未对接**,:95-97)
|
||||
|
||||
- `checkCredit`(:136-172):要求合同已推送(有 `hcs_fd_id`,:138-145)→ `hcsClient.contractCreditCheck`(:151);
|
||||
- `fdIsCredit=true`(额度内)→ `hcs_credit_status=pass`(:160);
|
||||
- **超额不拦截提交** → `hcs_credit_status=over` + `hcs_credit_msg` + **`hcs_spec_status=need`**(:167-169)——这是付款特批的唯一自动触发点。
|
||||
|
||||
### 3.2 后续流转
|
||||
|
||||
- 审批通过:`#approve`(:353-362)置 `hcs_sync_status=unsynced`(:359,零埋点 ADR-0001);
|
||||
- **付款链没有即时推送**(`HcsImmediatePushSupport` 仅覆盖 project/contract),完全依赖定时扫描/手动端点(见 §四)。
|
||||
|
||||
### 3.3 TMS 侧留痕字段(`blade_payment_application`,`PaymentApplication.java:41`)
|
||||
|
||||
| 字段 | 位置 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `hcs_fd_id` / `hcs_sync_status` / `hcs_retry_count` | :125/:127/:129 | HCS 同步主状态 |
|
||||
| `hcs_credit_status` | :135 | `pass`(额度内)/ `over`(超额) |
|
||||
| `hcs_credit_msg` / `hcs_credit_time` | :137/:139 | 额度校验信息 |
|
||||
| `hcs_spec_fd_id` / `hcs_spec_status` | :141/:142 | 特批流程 ID / `none/need/pushing/processing/approved/rejected` |
|
||||
| `hcs_perf_fd_id` | :145 | 履约记录(C108,默认关,不在本文范围) |
|
||||
|
||||
### 3.4 与合同特批的关联
|
||||
|
||||
- 付款特批报文中的合同取 `ContractManage.hcs_fd_id` 传值(`requireContractFdId`,`HcsSpecPaySyncSupport.java:210-215`),额度校验也是按合同维度(C106-1 `fdContractId`);
|
||||
- 二者共用 `HcsSyncConstant.SPEC_STATUS_*` 状态机与 `blade_hcs_check_log` 留痕表(biz_type=`payment`,check_type=`risk`/`credit`/`spec`)。
|
||||
|
||||
---
|
||||
|
||||
## 四、结算付款特批(C106-3 发起 / C106-4 更新)
|
||||
|
||||
### 4.1 概念澄清
|
||||
|
||||
代码库中**不存在独立的"结算单付款"特批实体**。"结算付款特批"是**付款申请(PaymentApplication)的 HCS 特批流程在 HCS 侧的表单名称**——单据主题固定 `结算付款特批-{paymentNo}`(`HcsSpecPaySyncSupport.java:129/158`)。即:
|
||||
|
||||
- §三(付款特批)= **触发侧**:提交时 C106-1 超额置 `need`;
|
||||
- 本节(结算付款特批)= **推送侧**:审批通过后发起 C106-3 / 更新 C106-4。
|
||||
|
||||
佐证:`PaymentApplication.paymentType` 含 `settlement_payment`(`TransportBusiConstant.PAYMENT_TYPE_SETTLEMENT`,:35),BFI 申请事由即称"结算付款申请"(`PaymentApplicationServiceImpl.java:1207-1213`);`FormalSettlementPayment`(正式结算付款记录,`blade_formal_settlement_payment`)**没有任何 hcs/特批字段**,仅在付款完成后联动生成,不参与特批。
|
||||
|
||||
### 4.2 推送链路
|
||||
|
||||
| 入口 | 位置 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 定时扫描 | `HcsPushTask#pushHcsPayment`(:163,cron 默认 `0 2/5 * * * ?`,开关 `push.payment.sync-enabled` 默认 false) | `pushUnsyncedPayments`(:285-309):`approvalStatus=approved` 且 `hcs_sync_status ∈ {unsynced, failed}` 且重试未超限 → `HcsPaymentSyncSupport#pushPayment` |
|
||||
| 手动重推 | `POST /hcs/sync/payment/{id}`(`HcsSyncController.java:111`)→ `repushPayment`(:95-113);批量 `POST /hcs/sync/payment`(:129) | — |
|
||||
|
||||
`HcsPaymentSyncSupport#pushPayment`(`HcsPaymentSyncSupport.java:70-87`):
|
||||
|
||||
1. **① 结算付款特批**:`hcs_spec_status=need` 且未发起时(:72-74)调 `HcsSpecPaySyncSupport#pushSpecPay`;
|
||||
2. ② 履约记录 C108(默认关);
|
||||
3. 最后统一 `markSynced`(:142)/ `markFailed`(:154)回写整体同步状态。
|
||||
|
||||
> 当前 `credit.check-enabled=false`(C106-1 未对接),`need` 无自动触发源,"仅历史数据/人工场景可达"(`HcsPaymentSyncSupport.java:72` 注释)。
|
||||
|
||||
### 4.3 C106-3/4 实现(`HcsSpecPaySyncSupport`)
|
||||
|
||||
`pushSpecPay`(:86-108):
|
||||
|
||||
- `hcs_spec_fd_id` 为空 → **C106-3 发起**:`hcsClient.addSpecApplyPay`(:92,`IHcsClient.java:259`)双层嵌套 `data.data.fdId` → 回填 `hcs_spec_fd_id` + 状态 `processing`(:94-96);
|
||||
- 非空 → **C106-4 更新**:`updateSpecApplyPay`(:102,`IHcsClient.java:268`,顶层 `fdId` 定位,内层 `success` 判断)。
|
||||
|
||||
报文组装 `buildSpecPayParam`(:113-166):`HcsSpecPaySaveDTO` → `HcsSpecPayFormDataDTO` → `HcsSpecPayPropsDTO`,关键字段:
|
||||
|
||||
| HCS 字段 | 取值 |
|
||||
| --- | --- |
|
||||
| `fdDocSubject` | `结算付款特批-{paymentNo}`(:129/:158) |
|
||||
| `fdContractName` | 合同 `hcs_fd_id`(:123) |
|
||||
| `fdDocNo` / `fdId` | `paymentNo`(:127/:131) |
|
||||
| `fdPayAmount` | `appliedAmount` 申请金额(:133) |
|
||||
| `fdTotalAmount` | `settlementAmount` 结算金额(:135) |
|
||||
| `fdPayer` / `fdPayee` | 付款方/收款方(:137-138) |
|
||||
| 收款账户/账号/开户行 | :140-142 |
|
||||
| `fdSettleCurrency` | 默认"人民币"(:144) |
|
||||
| `fdPaymentPurpose`/`fdPaymentNature`/`fdPaymentType` | 来自 `thirdParty.hcs.spec-pay.*` 配置(:146-148) |
|
||||
| `fdReason` / `fdSupplementNote` | `remark`(:150-151) |
|
||||
| `fdSpcApprovalAttach` | `fd_spc_approval_attach`(:155) |
|
||||
|
||||
操作人 = 付款申请创建人登录名(`resolveLoginName`,:220-229)。
|
||||
|
||||
附件 `buildMechanisms`(:171-193):`attachmentsJson` 经 `HcsAttachmentSupport#transferAttachments`(C103-2)转传;**发起时带 `fdBindType=ADD`、更新时不带**(:181-189)。
|
||||
|
||||
### 4.4 结果确认
|
||||
|
||||
特批结果由合规系统审批完成后主动推送(2026-10-12 起,替代原计划的 B103,§9-U1 已闭环):
|
||||
|
||||
- `POST /hcs/paymentLegal/result`(`HcsSyncController`,`@PreAuth(PERMIT_ALL)`,网关注册 `/gwzh/HTHG/paymentLegal/result`)→ `HcsPaymentSyncSupport#handleLegalResult`:`requestId`=付款申请ID 定位,`status=APPROVED/REJECTED` 回写 `hcs_spec_status`,不联动付款审批状态;
|
||||
- 等效兜底:页面人工确认 `POST /hcs/spec-pay/confirm`(仅 `processing` 可确认,置 `approved/rejected`);
|
||||
- **付款特批结果不联动付款审批状态**(与合同特批的 `syncContractOnSpecResult` 不同,无驳回联动)。
|
||||
|
||||
---
|
||||
|
||||
## 五、推送时机与结果接收机制汇总
|
||||
|
||||
| 机制 | 合同特批(C103-8/contractLegal/result) | 付款/结算付款特批(C106-3/4/paymentLegal/result) |
|
||||
| --- | --- | --- |
|
||||
| 定时扫描 | `HcsPushTask#pushHcsContract`(默认 `0 1/5 * * * ?`) | `HcsPushTask#pushHcsPayment`(默认 `0 2/5 * * * ?`);Redis 任务锁 TTL 240s(:92)、分钟位错峰(:75-77) |
|
||||
| 即时推送 | `HcsImmediatePushSupport#pushContractAfterCommit`(afterCommit 异步,开关默认 false,单条锁 TTL 120s) | 无 |
|
||||
| 结果推送接收 | `POST /hcs/contractLegal/result`(PERMIT_ALL,requestId=合同ID,原文留痕+联动审批状态) | `POST /hcs/paymentLegal/result`(PERMIT_ALL,requestId=付款申请ID,回写特批状态) |
|
||||
| 人工确认 | `POST /hcs/contract/spec/confirm` | `POST /hcs/spec-pay/confirm` |
|
||||
| 手动发起/重推 | `POST /hcs/contract/spec-apply`(:226)、`POST /hcs/sync/contract/{id}`(:110) | `POST /hcs/sync/payment/{id}`(:111)、`POST /hcs/sync/payment`(:129) |
|
||||
|
||||
---
|
||||
|
||||
## 六、依赖配置项(`thirdParty.hcs.*`,`HcsProperties.java`)
|
||||
|
||||
| 配置 | 默认 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `contract.require-risk-check` | true | 提交时特批说明附件强校验 |
|
||||
| `risk.check-on-contract` | — | 合同链路 C101-1 查询开关 |
|
||||
| `risk.check-on-payment` | true | 付款提交 C101-1 校验开关 |
|
||||
| `risk.block-blacklist` | true | 付款链路黑名单阻断(合同链路已不用于阻断) |
|
||||
| `credit.check-enabled` | **false** | C106-1 额度校验,一期未对接(付款特批自动触发源关闭) |
|
||||
| `contract.special-contract-enabled` | false | C103-1 报文特批流程字段 `fdSepcailContract`(固定 false,D15) |
|
||||
| `push.immediate-enabled` | false | 审批通过后即时推送 |
|
||||
| `push.contract.sync-enabled` / `push.contract.cron` | — / `0 1/5 * * * ?` | 合同定时扫描 |
|
||||
| `push.payment.sync-enabled` / `push.payment.cron` | — / `0 2/5 * * * ?` | 付款定时扫描 |
|
||||
| `spec-pay.payment-purpose/nature/type` | — | C106 报文付款用途/性质/类型 |
|
||||
|
||||
---
|
||||
|
||||
## 七、留痕与常量速查
|
||||
|
||||
- **留痕表**:`blade_hcs_check_log`(`HcsContractCheckLog.java:44`):`biz_type=contract/payment`、`check_type=risk/credit/spec`、`result`、`msg`(≤500)、`trace_id`。
|
||||
- **关键常量**(`HcsSyncConstant`):`SPEC_STATUS_NONE/NEED/PROCESSING/APPROVED/REJECTED`(:119-149)、`RISK_LEVEL_HIGH="2"`(:156)、`ATTACHMENT_TYPE_SPEC_EXPLANATION="特批说明"`(:171)、`SPEC_REVIEW_NODE="特批审核"`(:176)。
|
||||
- **合规推送结果状态**(`HcsSyncConstant`):`LEGAL_RESULT_APPROVED="APPROVED"` / `LEGAL_RESULT_REJECTED="REJECTED"`(原 B103 回调候选键常量 `HcsFieldConstant.SPEC_CB_*` 已随旧回调端点删除)。
|
||||
- **特批附件挂载键**:`fd_spc_approval_attach`(合同 C103-8 与付款 C106-3/4 共用)。
|
||||
Reference in New Issue
Block a user