360 lines
10 KiB
Markdown
360 lines
10 KiB
Markdown
|
|
# 银行流水模型真实规则两阶段落地设计文档
|
|||
|
|
|
|||
|
|
**模块**: 银行流水打标
|
|||
|
|
**日期**: 2026-03-20
|
|||
|
|
|
|||
|
|
## 一、背景
|
|||
|
|
|
|||
|
|
当前项目已经具备银行流水打标基础链路:
|
|||
|
|
|
|||
|
|
- 规则元数据表 `ccdi_bank_tag_rule`
|
|||
|
|
- 结果表 `ccdi_bank_statement_tag_result`
|
|||
|
|
- 任务表 `ccdi_bank_tag_task`
|
|||
|
|
- 规则执行入口 `CcdiBankTagServiceImpl`
|
|||
|
|
- SQL 承载文件 `CcdiBankTagAnalysisMapper.xml`
|
|||
|
|
- 参数解析器 `BankTagRuleConfigResolver`
|
|||
|
|
|
|||
|
|
其中“大额交易”模型下的首批规则已经具备真实 SQL,其余不少规则虽然已经补齐了:
|
|||
|
|
|
|||
|
|
- `rule_code`
|
|||
|
|
- `model_code`
|
|||
|
|
- Service 分发入口
|
|||
|
|
- Mapper 方法签名
|
|||
|
|
- XML `select`
|
|||
|
|
|
|||
|
|
但当前 XML 仍是 `where 1 = 0` 的占位 SQL,尚未产生真实命中结果。
|
|||
|
|
|
|||
|
|
根据 [assets/模型信息.xlsx](/Users/wkc/Desktop/ccdi/ccdi/assets/模型信息.xlsx) 当前整理结果,现有未真实实现、且在本环境中已判定可直接执行 SQL 的银行流水模型共 19 条。本次需求是将这 19 条规则从“占位规则”替换为“真实规则”。
|
|||
|
|
|
|||
|
|
## 二、目标
|
|||
|
|
|
|||
|
|
本次设计目标如下:
|
|||
|
|
|
|||
|
|
1. 将 19 条未真实实现的银行流水模型接入现有真实打标链路。
|
|||
|
|
2. 保持现有规则式架构不变,不新增平行模块或兼容性补丁链路。
|
|||
|
|
3. 将真实命中逻辑统一收敛到 `CcdiBankTagAnalysisMapper.xml`。
|
|||
|
|
4. 补齐规则执行所需的参数映射、初始化 SQL 与验证测试。
|
|||
|
|
5. 为控制改动规模,将 19 条规则拆成两期实施,并分别产出前后端实施计划。
|
|||
|
|
|
|||
|
|
## 三、范围
|
|||
|
|
|
|||
|
|
### 3.1 本次范围
|
|||
|
|
|
|||
|
|
- `CcdiBankTagAnalysisMapper.xml` 中 19 条占位规则替换为真实 SQL
|
|||
|
|
- `CcdiBankTagServiceImpl` 中对应规则的真实执行分发校准
|
|||
|
|
- `BankTagRuleConfigResolver` 中新增规则参数映射补齐
|
|||
|
|
- `sql/` 下与本次规则相关的初始化脚本或增量脚本调整
|
|||
|
|
- 单元测试、结构测试与回归测试补齐
|
|||
|
|
- 新增 1 份设计文档、2 份后端实施计划、2 份前端实施计划
|
|||
|
|
|
|||
|
|
### 3.2 不在本次范围
|
|||
|
|
|
|||
|
|
- 不新增前端页面字段、交互或展示组件
|
|||
|
|
- 不引入动态规则引擎、脚本注册中心或 DSL
|
|||
|
|
- 不新增数据库表结构
|
|||
|
|
- 不处理 `xlsx` 中当前环境不可直接执行的规则
|
|||
|
|
- 不改造“大额交易”已真实落地的 8 条规则逻辑
|
|||
|
|
|
|||
|
|
## 四、现状分析
|
|||
|
|
|
|||
|
|
### 4.1 当前实现结构
|
|||
|
|
|
|||
|
|
当前银行流水打标流程为:
|
|||
|
|
|
|||
|
|
1. `CcdiBankTagServiceImpl.rebuildProject(...)` 加载启用规则。
|
|||
|
|
2. 按 `rule_code` 分发到 `executeStatementRule / executeObjectRule`。
|
|||
|
|
3. 通过 `CcdiBankTagAnalysisMapper` 调用 XML 中的具体 SQL。
|
|||
|
|
4. 将命中结果组装为 `CcdiBankTagResult` 后批量入库。
|
|||
|
|
5. 刷新项目风险人数,供结果总览等后续页面使用。
|
|||
|
|
|
|||
|
|
### 4.2 当前核心问题
|
|||
|
|
|
|||
|
|
19 条目标规则目前已具备“入口”,但不具备“真实命中能力”:
|
|||
|
|
|
|||
|
|
- `ccdi_bank_tag_rule` 中已有规则元数据
|
|||
|
|
- `CcdiBankTagServiceImpl` 中已有大部分分发分支
|
|||
|
|
- `CcdiBankTagAnalysisMapper.java` 中已有对应方法
|
|||
|
|
- `CcdiBankTagAnalysisMapper.xml` 中对应 `<select>` 仍为占位 SQL
|
|||
|
|
|
|||
|
|
因此当前的主要缺口不是“补骨架”,而是“把占位 SQL 换成真实规则 SQL,并补齐参数映射与测试”。
|
|||
|
|
|
|||
|
|
### 4.3 当前环境可直接落地的 19 条规则
|
|||
|
|
|
|||
|
|
#### 第一期
|
|||
|
|
|
|||
|
|
- `GAMBLING_SENSITIVE_KEYWORD`
|
|||
|
|
- `SPECIAL_AMOUNT_TRANSACTION`
|
|||
|
|
- `SUSPICIOUS_INCOME_KEYWORD`
|
|||
|
|
- `SINGLE_PURCHASE_AMOUNT`
|
|||
|
|
- `SINGLE_SETTLEMENT_AMOUNT`
|
|||
|
|
- `LARGE_PURCHASE_TRANSACTION`
|
|||
|
|
- `STOCK_TFR_LARGE`
|
|||
|
|
- `LARGE_STOCK_TRADING`
|
|||
|
|
- `WITHDRAW_CNT`
|
|||
|
|
|
|||
|
|
#### 第二期
|
|||
|
|
|
|||
|
|
- `LOW_INCOME_RELATIVE_LARGE_TRANSACTION`
|
|||
|
|
- `MULTI_PARTY_GAMBLING_TRANSFER`
|
|||
|
|
- `MONTHLY_FIXED_INCOME`
|
|||
|
|
- `FIXED_COUNTERPARTY_TRANSFER`
|
|||
|
|
- `HOUSE_REGISTRATION_MISMATCH`
|
|||
|
|
- `PROPERTY_FEE_REGISTRATION_MISMATCH`
|
|||
|
|
- `TAX_ASSET_REGISTRATION_MISMATCH`
|
|||
|
|
- `SUPPLIER_CONCENTRATION`
|
|||
|
|
- `SALARY_QUICK_TRANSFER`
|
|||
|
|
- `SALARY_UNUSED`
|
|||
|
|
|
|||
|
|
## 五、方案对比
|
|||
|
|
|
|||
|
|
### 5.1 方案一:一次性直接替换 19 条占位 SQL
|
|||
|
|
|
|||
|
|
优点:
|
|||
|
|
|
|||
|
|
- 最短路径
|
|||
|
|
- 架构最稳定
|
|||
|
|
- 规则口径统一落地后可立即进入现有结果链路
|
|||
|
|
|
|||
|
|
缺点:
|
|||
|
|
|
|||
|
|
- 单次改动面较大
|
|||
|
|
- SQL、参数、测试回归压力集中
|
|||
|
|
|
|||
|
|
### 5.2 方案二:按模型组拆成多轮交付
|
|||
|
|
|
|||
|
|
优点:
|
|||
|
|
|
|||
|
|
- 单次改动更小
|
|||
|
|
|
|||
|
|
缺点:
|
|||
|
|
|
|||
|
|
- 一部分规则真实、一部分规则仍占位,阶段内口径不完整
|
|||
|
|
- 和本次“一次性纳入两批规划”的目标不一致
|
|||
|
|
|
|||
|
|
### 5.3 方案三:改造成更通用的动态规则架构
|
|||
|
|
|
|||
|
|
优点:
|
|||
|
|
|
|||
|
|
- 长期可维护性表面上更统一
|
|||
|
|
|
|||
|
|
缺点:
|
|||
|
|
|
|||
|
|
- 明显超出本次需求
|
|||
|
|
- 会把风险扩大到 Service、Mapper、配置、测试结构整体重构
|
|||
|
|
|
|||
|
|
### 5.4 结论
|
|||
|
|
|
|||
|
|
采用方案一,但执行层面拆成两期实施:
|
|||
|
|
|
|||
|
|
- 总体架构保持不变
|
|||
|
|
- 设计一次性定稿
|
|||
|
|
- 实施按“先易后难”拆成两期
|
|||
|
|
|
|||
|
|
## 六、总体设计
|
|||
|
|
|
|||
|
|
### 6.1 架构原则
|
|||
|
|
|
|||
|
|
本次遵循以下原则:
|
|||
|
|
|
|||
|
|
1. 不引入新模块
|
|||
|
|
2. 不新增兼容性双轨逻辑
|
|||
|
|
3. 不在 Java Service 层补业务口径判断
|
|||
|
|
4. 所有真实命中逻辑统一落在 `CcdiBankTagAnalysisMapper.xml`
|
|||
|
|
5. 参数解析仍通过 `BankTagRuleConfigResolver`
|
|||
|
|
|
|||
|
|
### 6.2 数据流
|
|||
|
|
|
|||
|
|
真实规则执行链路保持为:
|
|||
|
|
|
|||
|
|
1. `CcdiBankTagServiceImpl.rebuildProject(...)` 发起重算。
|
|||
|
|
2. `ruleMapper.selectEnabledRules(modelCode)` 获取启用规则。
|
|||
|
|
3. `BankTagRuleConfigResolver.resolve(projectId, rule)` 解析项目有效参数。
|
|||
|
|
4. `executeStatementRule / executeObjectRule` 依据 `rule_code` 分发。
|
|||
|
|
5. `CcdiBankTagAnalysisMapper.xml` 执行真实 SQL,返回 `STATEMENT` 或 `OBJECT` 命中结果。
|
|||
|
|
6. Service 将命中结果组装为 `CcdiBankTagResult` 并批量入库。
|
|||
|
|
7. 调用 `projectOverviewService.refreshProjectRiskCounts(projectId, operator)` 刷新项目风险人数。
|
|||
|
|
|
|||
|
|
### 6.3 规则落地边界
|
|||
|
|
|
|||
|
|
#### 流水明细型规则
|
|||
|
|
|
|||
|
|
输出:
|
|||
|
|
|
|||
|
|
- `bankStatementId`
|
|||
|
|
- `groupId`
|
|||
|
|
- `logId`
|
|||
|
|
- `reasonDetail`
|
|||
|
|
|
|||
|
|
代表规则包括:
|
|||
|
|
|
|||
|
|
- `GAMBLING_SENSITIVE_KEYWORD`
|
|||
|
|
- `SPECIAL_AMOUNT_TRANSACTION`
|
|||
|
|
- `SUSPICIOUS_INCOME_KEYWORD`
|
|||
|
|
- `HOUSE_REGISTRATION_MISMATCH`
|
|||
|
|
- `PROPERTY_FEE_REGISTRATION_MISMATCH`
|
|||
|
|
- `TAX_ASSET_REGISTRATION_MISMATCH`
|
|||
|
|
- `LARGE_PURCHASE_TRANSACTION`
|
|||
|
|
- `STOCK_TFR_LARGE`
|
|||
|
|
- `LARGE_STOCK_TRADING`
|
|||
|
|
- 外汇购汇/结汇规则
|
|||
|
|
|
|||
|
|
#### 对象型规则
|
|||
|
|
|
|||
|
|
输出:
|
|||
|
|
|
|||
|
|
- `objectType`
|
|||
|
|
- `objectKey`
|
|||
|
|
- `reasonDetail`
|
|||
|
|
|
|||
|
|
对象维度统一使用员工主键口径:
|
|||
|
|
|
|||
|
|
- `objectType = STAFF_ID_CARD`
|
|||
|
|
- `objectKey = 员工身份证号`
|
|||
|
|
|
|||
|
|
代表规则包括:
|
|||
|
|
|
|||
|
|
- `LOW_INCOME_RELATIVE_LARGE_TRANSACTION`
|
|||
|
|
- `MULTI_PARTY_GAMBLING_TRANSFER`
|
|||
|
|
- `MONTHLY_FIXED_INCOME`
|
|||
|
|
- `FIXED_COUNTERPARTY_TRANSFER`
|
|||
|
|
- `SUPPLIER_CONCENTRATION`
|
|||
|
|
- `WITHDRAW_CNT`
|
|||
|
|
- `SALARY_QUICK_TRANSFER`
|
|||
|
|
- `SALARY_UNUSED`
|
|||
|
|
|
|||
|
|
### 6.4 参数策略
|
|||
|
|
|
|||
|
|
参数只通过现有 `ccdi_model_param` 获取,不新增第二参数源。
|
|||
|
|
|
|||
|
|
本次需要补齐的规则参数映射包括:
|
|||
|
|
|
|||
|
|
- `MULTI_PARTY_GAMBLING_TRANSFER` -> `MULTI_PARTY_AMT_MIN`、`MULTI_PARTY_AMT_MAX`
|
|||
|
|
- `FIXED_COUNTERPARTY_TRANSFER` -> `FIXED_COUNTERPARTY_TRANSFER_MIN`、`FIXED_COUNTERPARTY_TRANSFER_MAX`
|
|||
|
|
- `SINGLE_PURCHASE_AMOUNT` 对应购汇类单值阈值
|
|||
|
|
- `SINGLE_SETTLEMENT_AMOUNT` 对应结汇类单值阈值
|
|||
|
|
- `WITHDRAW_CNT` 对应提现频次阈值
|
|||
|
|
- `STOCK_TFR_LARGE`、`LARGE_STOCK_TRADING` 等单值阈值按现有参数脚本统一校准
|
|||
|
|
|
|||
|
|
对本身不依赖阈值的规则,不强行补充虚假参数。
|
|||
|
|
|
|||
|
|
### 6.5 错误处理策略
|
|||
|
|
|
|||
|
|
本次不增加补丁式兜底逻辑:
|
|||
|
|
|
|||
|
|
- 真实 SQL 报错:整次打标任务按现有逻辑失败
|
|||
|
|
- 规则无命中:任务正常成功,命中数为 0
|
|||
|
|
- 参数缺失:按现有解析结果暴露问题,并通过脚本与测试补齐
|
|||
|
|
|
|||
|
|
## 七、两期拆分设计
|
|||
|
|
|
|||
|
|
### 7.1 第一期设计目标
|
|||
|
|
|
|||
|
|
优先替换依赖简单、回归范围可控的规则,形成第一批真实命中能力。
|
|||
|
|
|
|||
|
|
第一期规则:
|
|||
|
|
|
|||
|
|
- `GAMBLING_SENSITIVE_KEYWORD`
|
|||
|
|
- `SPECIAL_AMOUNT_TRANSACTION`
|
|||
|
|
- `SUSPICIOUS_INCOME_KEYWORD`
|
|||
|
|
- `SINGLE_PURCHASE_AMOUNT`
|
|||
|
|
- `SINGLE_SETTLEMENT_AMOUNT`
|
|||
|
|
- `LARGE_PURCHASE_TRANSACTION`
|
|||
|
|
- `STOCK_TFR_LARGE`
|
|||
|
|
- `LARGE_STOCK_TRADING`
|
|||
|
|
- `WITHDRAW_CNT`
|
|||
|
|
|
|||
|
|
第一期特点:
|
|||
|
|
|
|||
|
|
- 单表筛选为主
|
|||
|
|
- 依赖关系较少
|
|||
|
|
- 参数映射简单
|
|||
|
|
- 适合先完成真实 SQL 替换和基础回归
|
|||
|
|
|
|||
|
|
### 7.2 第二期设计目标
|
|||
|
|
|
|||
|
|
完成跨表比对、对象聚合和窗口口径更复杂的规则。
|
|||
|
|
|
|||
|
|
第二期规则:
|
|||
|
|
|
|||
|
|
- `LOW_INCOME_RELATIVE_LARGE_TRANSACTION`
|
|||
|
|
- `MULTI_PARTY_GAMBLING_TRANSFER`
|
|||
|
|
- `MONTHLY_FIXED_INCOME`
|
|||
|
|
- `FIXED_COUNTERPARTY_TRANSFER`
|
|||
|
|
- `HOUSE_REGISTRATION_MISMATCH`
|
|||
|
|
- `PROPERTY_FEE_REGISTRATION_MISMATCH`
|
|||
|
|
- `TAX_ASSET_REGISTRATION_MISMATCH`
|
|||
|
|
- `SUPPLIER_CONCENTRATION`
|
|||
|
|
- `SALARY_QUICK_TRANSFER`
|
|||
|
|
- `SALARY_UNUSED`
|
|||
|
|
|
|||
|
|
第二期特点:
|
|||
|
|
|
|||
|
|
- 跨表比对较多
|
|||
|
|
- 聚合口径更复杂
|
|||
|
|
- 对交易时间、关系人口径、资产登记口径更敏感
|
|||
|
|
|
|||
|
|
## 八、测试设计
|
|||
|
|
|
|||
|
|
### 8.1 XML 结构测试
|
|||
|
|
|
|||
|
|
在 `CcdiBankTagAnalysisMapperXmlTest` 中补充:
|
|||
|
|
|
|||
|
|
- 目标规则不再使用 `where 1 = 0`
|
|||
|
|
- 新增真实 SQL 仍满足 XML 结构合法
|
|||
|
|
- `STATEMENT` 规则仍返回完整命中字段
|
|||
|
|
- `OBJECT` 规则仍返回完整命中字段
|
|||
|
|
|
|||
|
|
### 8.2 参数解析测试
|
|||
|
|
|
|||
|
|
在 `BankTagRuleConfigResolverTest` 中补充:
|
|||
|
|
|
|||
|
|
- 新增规则参数映射断言
|
|||
|
|
- 双阈值规则参数完整性断言
|
|||
|
|
- 无参数规则仍返回空参数集
|
|||
|
|
|
|||
|
|
### 8.3 Service 分发测试
|
|||
|
|
|
|||
|
|
在 `CcdiBankTagServiceImplTest` 中补充:
|
|||
|
|
|
|||
|
|
- 每条新增规则都能命中正确 Mapper 方法
|
|||
|
|
- 不再落入默认空分支
|
|||
|
|
- 真实规则空命中时任务仍可成功结束
|
|||
|
|
|
|||
|
|
### 8.4 受影响链路回归
|
|||
|
|
|
|||
|
|
至少覆盖:
|
|||
|
|
|
|||
|
|
- `CcdiBankTagAnalysisMapperXmlTest`
|
|||
|
|
- `BankTagRuleConfigResolverTest`
|
|||
|
|
- `CcdiBankTagServiceImplTest`
|
|||
|
|
- 受影响的项目风险人数回写与结果总览后端测试
|
|||
|
|
|
|||
|
|
## 九、文档产物
|
|||
|
|
|
|||
|
|
按仓库规范,本次输出以下文档:
|
|||
|
|
|
|||
|
|
1. 本设计文档:
|
|||
|
|
- `docs/design/2026-03-20-bank-tag-real-rule-two-phase-design.md`
|
|||
|
|
2. 第一期后端实施计划:
|
|||
|
|
- `docs/plans/backend/2026-03-20-bank-tag-real-rule-phase1-backend-implementation.md`
|
|||
|
|
3. 第一期前端实施计划:
|
|||
|
|
- `docs/plans/frontend/2026-03-20-bank-tag-real-rule-phase1-frontend-implementation.md`
|
|||
|
|
4. 第二期后端实施计划:
|
|||
|
|
- `docs/plans/backend/2026-03-20-bank-tag-real-rule-phase2-backend-implementation.md`
|
|||
|
|
5. 第二期前端实施计划:
|
|||
|
|
- `docs/plans/frontend/2026-03-20-bank-tag-real-rule-phase2-frontend-implementation.md`
|
|||
|
|
|
|||
|
|
其中前端实施计划用于明确边界:
|
|||
|
|
|
|||
|
|
- 本期无前端代码改造
|
|||
|
|
- 前端仅做依赖说明和联调预期记录
|
|||
|
|
|
|||
|
|
## 十、结论
|
|||
|
|
|
|||
|
|
本方案采用“现有架构内真实替换占位 SQL”的最短路径设计,并将 19 条目标规则拆成两期实施:
|
|||
|
|
|
|||
|
|
- 第一期先处理依赖少、风险低的 9 条规则
|
|||
|
|
- 第二期再处理聚合与跨表逻辑更重的 10 条规则
|
|||
|
|
|
|||
|
|
这样既满足“一次性完成完整设计”的要求,又能在实施阶段有效控制改动规模和回归风险,不会偏离当前项目既有技术路线。
|