docs: 客商黑名单与风险等级业务说明与运维手册

This commit is contained in:
刘泉佳
2026-10-30 11:42:22 +08:00
parent ed91793b64
commit 52d2f05524
2 changed files with 238 additions and 0 deletions
@@ -0,0 +1,101 @@
# 客商黑名单与风险等级业务说明(业务侧)
> 更新日期:2026-10-30 | 适用系统:运输 TMS | 读者:业务/运营人员
>
> 关联文档:《客商黑名单与风险等级运维手册(运维侧)》(同目录)
## 1. 这是什么
TMS 从**两个外部系统**获取客商风险数据,每日自动更新到客商档案,用于客商档案的展示、筛选,以及合同、付款环节的风险管控:
| 数据 | 来源系统 | 说明 |
|---|---|---|
| **客商风险等级** | 合同合规系统(HCS) | 低风险 / 中风险 / 高风险,另含"黑名单"标识 |
| **金蝶黑名单** | 金蝶(星瀚)· 国资委黑名单 | 命中后记录**失信类别**(禁止交易类 / 风险警示类)与**列入事由** |
## 2. 名词解释
| 名词 | 含义 |
|---|---|
| 黑名单 | 客商被列入外部(国资委)黑名单。金蝶分 **A 类(禁止交易类,不允许交易)** 和 **B 类(风险警示类,需关注)** |
| 失信类别 | 黑名单的分类名称(如"禁止交易类"),来自金蝶黑名单记录 |
| 列入事由 | 被列入黑名单的具体原因(如"涉贪污受贿裁判相关提及方(3年以上及其他)"),来自金蝶黑名单记录 |
| 风险等级 | 合同合规系统对客商的风险评级:0=低风险、1=中风险、2=高风险 |
| 内部组织客商 | 集团内我方签约主体(客商类型=内部组织),**不查询风险,默认无风险** |
## 3. 总体流程
```mermaid
flowchart TD
A[每日凌晨自动刷新<br/>02:30] --> B[取合同期限内生效合同的<br/>甲乙方客商]
B --> C{内部组织客商?}
C -->|是| D[默认无风险, 跳过]
C -->|否| E[查合同合规系统风险等级]
C -->|否| F[查金蝶黑名单]
E --> G[结果写入客商档案<br/>供列表展示与筛选]
F --> G
```
- 刷新范围:**合同期限内**(合同起止日期或临时期限覆盖当天)且**审核通过、未终止**的合同,其甲乙方关联客商。
- 数据**每日更新一次**;当天新增的客商在表单里有实时提示(见 4.1)。
## 4. 各业务环节说明
### 4.1 新增 / 编辑客商(表单实时提示)
- 录入**统一社会信用代码**满 18 位后,系统自动查金蝶客商档案,回填客商名称、法人等工商信息。
- **客商名称**回填或填写后失焦时,系统实时查询该客商的风险;若为高风险/黑名单客商,名称下方显示红色提示,悬浮可见明细,格式:
> 【客商名称】:被列入外部黑名单(失信类别:xx);列入事由 xx;风险等级:高风险
### 4.2 提交准入审批(金蝶黑名单硬校验)
提交客商准入审批时,系统按客商**发票信息中的纳税人识别号**实时查询金蝶黑名单:
| 命中情况 | 结果 |
|---|---|
| **A 类(禁止交易类)** | ❌ **禁止提交**,提示失信类别与列入事由 |
| **B 类(风险警示类)** | ⚠️ 默认放行并记录告警(是否拦截由系统配置决定) |
| 查询异常 | ❌ 暂缓提交(防止漏拦),稍后重试 |
> 因此:维护客商**发票信息(税号)是黑名单校验的前提**,未维护税号时提审不会做黑名单校验。
### 4.3 客商档案列表(展示 / 筛选 / 悬浮)
**客商风险列**显示规则:
| 客商情况 | 显示 | 颜色 |
|---|---|---|
| 高风险 且 黑名单 | 高风险、黑名单 | 红 |
| 仅高风险 | 高风险 | 红 |
| 仅黑名单 | 黑名单 | 红 |
| 中风险 | 中风险 | 黄 |
| 低风险 | 低风险 | 绿 |
| 内部组织客商 | 无风险(默认,不查询) | 绿 |
| 尚未查询到数据 | - | — |
- 红色标签(黑名单/高风险)**鼠标悬浮**可查看明细:失信类别、列入事由、风险等级。
- 搜索栏新增**客商风险**下拉筛选:黑名单 / 高风险 / 中风险 / 低风险。
- 数据为每日凌晨刷新结果,当天有变动的以次日刷新为准。
### 4.4 合同推送(合同合规系统)
合同推送到合规系统前,甲乙双方客商各做一次风险校验:**高风险/黑名单客商的合同不能直接签约**,系统自动发起合同特批流程,特批通过后方可继续。
### 4.5 付款申请
提交付款申请时,若收款方为外部客商且属**高风险/黑名单**:
- 系统弹出风险提示;
- **必须上传「特批附件」**类型附件,否则无法提交审批;
- 审批通过后自动发起付款特批,特批完成前禁止推送金蝶。
## 5. 常见问题
| 问题 | 说明 |
|---|---|
| 为什么客商风险列显示"-"? | 该客商不在任何合同期限内生效合同的关联范围内,尚未被每日刷新任务查询过;或系统刚上线数据尚未生成 |
| 为什么内部组织客商显示"无风险"? | 内部组织为我方主体,按集团规定不查询风险,默认无风险 |
| 新客商当天会出现在风险筛选里吗? | 表单实时提示即时生效;列表落库数据次日刷新后生效 |
| 提交审批被黑名单拦截怎么办? | 客商属 A 类禁止交易,不可线上提交,走线下处置流程 |
| 黑名单数据多久更新? | 每日凌晨 02:30 自动刷新(合同期限内关联客商) |
@@ -0,0 +1,137 @@
# 客商黑名单与风险等级运维手册(运维侧)
> 更新日期:2026-10-30 | 适用系统:运输 TMS(blade-transport) | 读者:运维/实施人员
>
> 关联文档:《客商黑名单与风险等级业务说明(业务侧)》(同目录)
## 1. 链路总览
```
┌──────────────┐ C101-1 客商风险等级 ┌────────────────┐
│ 合同合规系统 │ ◄────────────────────── │ │
│ (HCS) │ A801-5 金蝶黑名单 │ TMS │
└──────────────┘ ◄────────────────────── │ blade-transport│
└──────┬─────────┘
每日 02:30 CustomerRiskRefreshTask │
┌──────▼─────────┐
│ blade_customer_archive
│ hcs_risk_level / hcs_black_status
│ hcs_risk_time
│ kingdee_black_category / kingdee_black_reason
└────────────────┘
```
**两条数据线**:
| 线 | 接口 | 查询键 | 落库字段 |
|---|---|---|---|
| 合同合规风险(C101-1) | `getRelativeRisk` | 客商编号(fdNumber) | `hcs_risk_level`、`hcs_black_status`、`hcs_risk_time` |
| 金蝶黑名单(A801-5) | `queryBlacklist` | 税号/统一社会信用代码(number) | `kingdee_black_category`、`kingdee_black_reason` |
**调用场景**(C101-1):
| 场景 | 入口 | 行为 |
|---|---|---|
| 每日定时刷新 | `CustomerRiskRefreshTask` → `HcsCreditCheckSupport.refreshCustomerRiskForActiveContracts()` | 批量落库 |
| 表单实时提示 | `GET /hcs/sync/risk/by-name`(名称反查编号) | 实时查 C101-1 + A801-5 组装 riskTip |
| 列表单查/批量 | `GET /hcs/sync/risk`、`GET /hcs/sync/risk/batch` | 实时查(展示用) |
| 合同推送校验 | `HcsContractSyncSupport.checkRelativeRisk` | 甲乙双方各查一次,高风险转特批 |
| 付款提交校验 | `HcsCreditCheckSupport.checkRelativeRisk` | 高风险/黑名单须特批附件 |
**调用场景**(A801-5):
| 场景 | 入口 | 行为 |
|---|---|---|
| 每日定时刷新 | 同上(200 税号/批) | 落失信类别/列入事由 |
| 提审黑名单校验 | `CustomerArchiveServiceImpl.validateBlacklist` | 按客商发票信息税号查询;**A 类硬拦截,B 类默认放行告警,查询异常阻断提审** |
## 2. 定时任务
`CustomerRiskRefreshTask`(每天 02:30,错开金蝶客商同步 02:00):
1. 取合同期限内生效合同(`approval_status IN (approved, change_approved)`、`current_node != '已终止'`、正式或临时期限覆盖当天)的甲乙方名称——1 次 SQL;
2. 按名称 `IN` 反查客商档案——1 次 SQL;内部组织客商跳过(默认无风险);
3. 外部客商按 **200/批**:每批 A801-5 一次批量查询 + C101-1 逐个远程查询(接口仅支持单编号);
4. 批内成功结果立即 `Db.updateBatchById` 落库 + `Db.saveBatch` 留痕,**批间互不影响,单批失败不中断其余批次**。
## 3. 配置项(Nacos)
| 配置键 | 环境变量 | 默认 | 说明 |
|---|---|---|---|
| `third-party.hcs.risk.refresh-enabled` | `HCS_RISK_REFRESH_ENABLED` | false | 每日刷新总开关(**上线需置 true**) |
| `third-party.hcs.risk.refresh-cron` | `HCS_RISK_REFRESH_CRON` | `0 30 2 * * ?` | 刷新调度 |
| `third-party.hcs.risk.check-on-contract` | `HCS_RISK_CHECK_ON_CONTRACT` | true | 合同推送前风险校验 |
| `third-party.hcs.risk.check-on-payment` | `HCS_RISK_CHECK_ON_PAYMENT` | true | 付款提交前风险校验 |
| `thirdparty.bfi.blacklist.blockRiskWarning` | `BFI_BLACKLIST_BLOCK_RISK_WARNING` | false | 金蝶黑名单 **B 类(风险警示)提审是否拦截**(A 类恒拦截) |
配置模板:`doc/nacos/third-party-api.yaml`(hcs.risk 节点)。
## 4. 数据库
### 4.1 表结构(blade_customer_archive 新增列)
| 字段 | 类型 | 说明 |
|---|---|---|
| `hcs_risk_level` | varchar(8) | C101-1 风险等级:0=低/1=中/2=高风险 |
| `hcs_black_status` | varchar(8) | C101-1 黑名单状态:yes/no/handing |
| `hcs_risk_time` | datetime | 风险最近查询时间 |
| `kingdee_black_category` | varchar(200) | 金蝶黑名单失信类别(awrp_combofield_title 兜底 awrp_combofield) |
| `kingdee_black_reason` | varchar(1000) | 金蝶黑名单列入事由(awrp_textareafield) |
索引:`idx_hcs_risk_level`、`idx_hcs_black_status`。
### 4.2 脚本(幂等可重复执行)
`doc/sql/transport/lqj/temp/`:
| 脚本 | 内容 |
|---|---|
| `02_blade_customer_archive_hcs_risk_20261030.sql` | 加 5 列 + 2 索引(information_schema 判断,已存在跳过) |
| `03_blade_customer_risk_dict_20261030.sql` | 业务字典 `customer_risk`(列表筛选下拉)与 `risk_level`(等级翻译) |
> 若早期版本已执行过含 `hcs_black_category/reason` 的脚本,需手动删除残留列(现名已改 `kingdee_black_*`)。
### 4.3 字典
| code | dictKey → dictValue | 用途 |
|---|---|---|
| `customer_risk` | blacklist/high/middle/low → 黑名单/高风险/中风险/低风险 | 客商列表搜索栏筛选下拉 |
| `risk_level` | 0/1/2 → 低风险/中风险/高风险 | 风险等级名称翻译(明细文案) |
字典缺失时前端筛选走兜底选项、后端明细少拼等级段,不报错。
## 5. 明细组装口径(后台统一)
唯一出口:`HcsCreditCheckSupport.buildRiskDetail(customerName, blackStatusYes, riskLevel, blackCategory, blackReason)`,
格式:`【客商名称】:被列入外部黑名单(失信类别:xx);{列入事由};风险等级:xx`
- 黑名单段:合同系统黑名单 **或** 金蝶命中(类别/事由任一非空);
- 等级段:`risk_level` 字典翻译(`DictBizCache` 未命中兜底 `DictCache`);
- 列表(`hcs_risk_detail`,列表查询时组装不落库)与表单实时提示(`riskTip`)同口径。
列表显示规则(前端 `customerRowRiskName`):高风险+黑名单 → "高风险、黑名单"(红);高风险、黑名单单项各显示(红);中风险(黄);低风险(绿);内部组织 → "无风险"(绿);无数据 → "-"。
## 6. 日志与排查
| 排查点 | 位置/关键字 |
|---|---|
| 刷新汇总 | 应用日志:`定时刷新客商风险:生效合同 X 份,覆盖客商 Y 个,刷新 Z 个…` |
| 单客商刷新失败 | `定时刷新客商风险失败:customerCode=…`(error 级,含堆栈) |
| 黑名单批量查询失败 | `定时刷新客商风险批量查询金蝶黑名单失败:size=…`(该批黑名单段缺失,下轮重刷) |
| 留痕写入失败 | `定时刷新客商风险留痕批量写入失败:size=…` |
| 全量留痕 | 表 `blade_hcs_check_log`(`biz_type=contract`,`check_type=risk`,`result=pass/fail/skip`,含 `trace_id`、`msg`) |
| 提审黑名单拦截 | 提审报错文案含"国资委黑名单中(失信类别:…,列入事由:…)" |
## 7. 常见操作
| 操作 | 方法 |
|---|---|
| 开启/关闭每日刷新 | Nacos 改 `refresh-enabled`(`@RefreshScope`,改后自动生效,无需重启) |
| 立即手动刷新一次 | 临时把 `refresh-cron` 改为近时刻(如 `0 5 14 * * ?`),执行后改回;或本地调用 `refreshCustomerRiskForActiveContracts()` |
| 补字典 | 执行 `03_blade_customer_risk_dict_20261030.sql`(幂等) |
| 某客商风险不更新 | 核对:客商名称是否与合同甲乙方**完全一致**(按名称匹配);客商是否内部组织(跳过);合同是否期限内且审核通过 |
| C101-1 不可用 | 刷新任务该客商记失败跳过,不影响其他客商;列表显示上轮数据 |
| A801-5 不可用 | 该批黑名单字段缺失(等级仍更新);提审黑名单校验会阻断提交(防止漏拦),恢复后重试 |
---
**注意**:黑名单/风险数据仅作展示与流程管控,强制安全校验在提审(A801-5 硬拦)、合同推送、付款提交链路的服务端事务内,前端展示不作为安全边界。