治理模块 govern.md 34 KB

治理模块 govern

本文引用的文件

  • GovernService.java
  • GovernTreeService.java
  • GovernConfService.java
  • GovernCache.java
  • GovernActivityProbe.java
  • GovernController.java
  • GovernTreeController.java
  • GovernTreeMapper.xml
  • GovernConfMapper.xml
  • GovernTree.java
  • GovernConf.java
  • TransResultHandler.java
  • CallResultHandler.java
  • governApi.ts
  • dto.ts
  • AiCleanService.java
  • GraphService.java
  • DmService.java
  • TimeSeriesService.java
  • GovernTableTool.java
  • AiGovernService.java

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与并发特性
  8. 使用示例
  9. 结果消费与扩展指南
  10. 故障排查
  11. 结论

引言

治理模块 govern 是调查场景中的数据治理中枢,负责三类核心职责:

  • 治理树:把通话、交易、住宿、交通、快递等数据源组织成“业务分类 + 人员 + 银行/运营商”的层级拓扑,并承载各节点的数据量统计。
  • 治理配置:控制是否启用开户信息、是否去重、导入时是否跳过治理等开关,并缓存案件级治理表名选择。
  • 治理任务与结果处理器:串联清洗、时序图构建、分类树统计、关系边计算和合并,最终产出图谱可用的关系边、外部表以及下游 agent 可消费的治理结果。

该模块对外暴露两类接口:治理任务接口 /govern 和治理树查询接口 /gt。前端通过 SSE 实时获取治理进度,并在治理树中查看按机构、银行、运营商、人员维度的关联数据。

项目结构

治理模块位于后端 module/govern,并与公共模型 common/model/govern、AI 清洗链路 module/aiclean、数据建模 module/dm、图谱 module/graph、时序图 module/otg 和 agent 工具链协作。

graph TB
    subgraph "前端"
        FE_API["治理前端 API<br/>governApi.ts"]
        FE_DTO["治理类型定义<br/>dto.ts"]
    end

    subgraph "治理模块 govern"
        CTRL_G["GovernController<br/>/govern"]
        CTRL_GT["GovernTreeController<br/>/gt"]
        SVC_GOVERN["GovernService<br/>治理流水线"]
        SVC_TREE["GovernTreeService<br/>治理树查询"]
        SVC_CONF["GovernConfService<br/>治理配置"]
        CACHE["GovernCache<br/>时序图 SQL 映射"]
        RS_TRANS["TransResultHandler<br/>交易结果处理器"]
        RS_CALL["CallResultHandler<br/>通话结果处理器"]
    end

    subgraph "共享模型"
        ENT_TREE["GovernTree<br/>治理树实体"]
        ENT_CONF["GovernConf<br/>治理配置实体"]
    end

    subgraph "外部模块"
        AICLEAN["AiCleanService / AiGovernService<br/>AI 清洗模板与治理树"]
        DM["DmService<br/>数据建模/外部表"]
        GRAPH["GraphService<br/>图谱关系"]
        OTG["TimeSeriesService<br/>时序图"]
        AGENT["GovernTableTool<br/>Agent 治理表工具"]
    end

    FE_API --> CTRL_G
    FE_API --> CTRL_GT
    CTRL_G --> SVC_GOVERN
    CTRL_GT --> SVC_TREE
    SVC_GOVERN --> SVC_CONF
    SVC_GOVERN --> RS_TRANS
    SVC_GOVERN --> RS_CALL
    SVC_GOVERN --> AICLEAN
    SVC_GOVERN --> CACHE
    SVC_TREE --> SVC_CONF
    SVC_GOVERN --> ENT_TREE
    SVC_CONF --> ENT_CONF
    SVC_GOVERN --> DM
    SVC_GOVERN --> GRAPH
    SVC_GOVERN --> OTG
    AGENT --> SVC_TREE

图表来源

  • GovernController.java:1-72
  • GovernTreeController.java:1-122
  • GovernService.java:1-200
  • GovernTreeService.java:1-120
  • GovernConfService.java:1-113
  • GovernCache.java:1-200
  • governApi.ts:1-200
  • dto.ts:1-121

章节来源

  • GovernController.java:1-72
  • GovernTreeController.java:1-122
  • governApi.ts:1-200
  • dto.ts:1-121

核心组件

治理模块的核心由控制器、服务、实体、映射器和结果处理器组成:

组件 职责 关键行为
GovernController 治理任务入口 启动 SSE、防重入、异步执行 calcTask
GovernTreeController 治理树查询入口 提供树结构、各类分页查询
GovernService 治理流水线编排 阶段化执行清洗、时序图、分类树、关系边计算
GovernTreeService 治理树查询与聚合 组装树、按人员和对象维度查交易/通话
GovernConfService 治理配置访问 读取 useOpenInfo、duplicate、hasGovern 等开关
GovernCache 时序图 SQL 映射 维护多类数据源的列映射,生成 DuckDB SQL
TransResultHandler 交易结果处理 将交易记录转为人员关系边批量写入
CallResultHandler 通话结果处理 将通话记录转为人员关系边批量写入
GovernTree 治理树实体 描述节点 id、父节点、类型、表名和数据量
GovernConf 治理配置实体 存储 confStr 与 confType,支持 JSON 扩展

章节来源

  • GovernController.java:1-72
  • GovernTreeController.java:1-122
  • GovernService.java:1-200
  • GovernTreeService.java:1-120
  • GovernConfService.java:1-113
  • GovernCache.java:1-200
  • TransResultHandler.java:1-133
  • CallResultHandler.java:1-124
  • GovernTree.java:1-56
  • GovernConf.java:1-62

架构总览

治理任务是一个分阶段、带超时、带进度推送的流水线。它不直接面向用户交互,而是作为后台任务驱动多个子系统的状态变化。

sequenceDiagram
    participant FE as "前端"
    participant CTRL as "GovernController"
    participant GOV as "GovernService"
    participant CONF as "GovernConfService"
    participant TREE as "GovernTreeService"
    participant MAPPER as "GovernMapper / Mapper XML"
    participant SSE as "SSE 推送"
    participant DM as "DmService / FileInfo"
    participant GRAPH as "GraphService"
    participant OTG as "TimeSeriesService"
    participant AI as "AiCleanService / AiGovernService"

    FE->>CTRL: GET /govern/sse
    FE->>CTRL: GET /govern/calcTask
    CTRL->>GOV: tryStartGovern(caseId)
    CTRL->>GOV: calcTask(taskProcess, caseId, userId)
    GOV->>SSE: 日志:治理任务已启动
    GOV->>CONF: useOpenInfo() / getTransTableName()
    GOV->>MAPPER: 第一阶段:清洗、去重、关系清理
    alt 启用开户信息
        GOV->>MAPPER: 清理并复制通话到 use_open_info_call_record
    end
    GOV->>OTG: 创建时序图 SQL 并执行
    GOV->>TREE: 统计分类树、人员树、开户信息树
    GOV->>AI: 统计 AI 动态表治理节点
    GOV->>MAPPER: 第三阶段:通话/交易/其他关系边计算
    GOV->>MAPPER: 合并关系边阶段表
    GOV->>DM: 更新文件治理完成状态
    GOV->>SSE: 进度 100% 并关闭连接

图表来源

  • GovernController.java:25-72
  • GovernService.java:120-450
  • GovernService.java:451-760
  • GovernConfService.java:20-113
  • GovernTreeService.java:60-120

详细组件分析

治理树实体与查询

治理树以 govern_tree 表为持久化载体,继承通用树节点基类,并通过 type、pid、tableNameEn、tableNameCn、dataCount 表达业务分类、父子关系、目标表和记录数。

classDiagram
    class GovernTree {
        +Long id
        +Long pid
        +String type
        +String tableNameEn
        +String tableNameCn
        +Integer dataCount
        +String aiTemplateId
    }

    class GovernConf {
        +Long id
        +String confStr
        +String confType
        +getOtherConfStr(key, defaultValue) String
    }

    class GovernTreeService {
        +getTree() List~GovernTree~
        +getTreeTablePage(dto) Map
        +getTreeTransPersonPage(dto) Map
        +getTreeTransBankPage(dto) Map
        +getTreeCallPersonPage(dto) Map
        +getTreeCallOperPage(dto) Map
        +getTreeCallPersonUseOpenInfoPage(dto) Map
        +getTreeCallOperUseOpenInfoPage(dto) Map
    }

    class GovernTreeController {
        +getTree() Result
        +treeTablePage(dto) Result
        +getTreeTransPersonPage(dto) Result
        +getTreeTransBankPage(dto) Result
        +getTreeCallPersonPage(dto) Result
        +getTreeCallOperPage(dto) Result
        +getTreeCallPersonUseOpenInfoPage(dto) Result
        +getTreeCallOperUseOpenInfoPage(dto) Result
    }

    GovernTreeService --> GovernTree : "返回/构造"
    GovernTreeController --> GovernTreeService : "调用"
    GovernTreeService --> GovernConfService : "决定通话/交易表"

图表来源

  • GovernTree.java:1-56
  • GovernConf.java:1-62
  • GovernTreeService.java:60-120
  • GovernTreeController.java:20-122

治理树查询的关键点包括:

  • 完整树构建:过滤 dataCount > 0 的节点后按 pid 组装树,并为负 id 的 AI 动态表节点补充字符串形式的模板 id。
  • 通用表格分页:根据 tableName 从全局表头缓存取列定义,并支持前端传入的动态条件 SQL。
  • 人员维度查询:按已知人员卡号或手机号过滤,也支持“未知对象”反向筛选。
  • 银行/运营商维度查询:对交易银行和通话运营商做分组统计,同时补齐余额、开户时间、账户状态等扩展信息。
  • 动态条件生成:对前端 Base64 编码的条件表达式解码,自动补全 LIKE 通配符和字符串引号。

章节来源

  • GovernTreeService.java:60-120
  • GovernTreeService.java:201-494
  • GovernTreeController.java:20-122
  • GovernTreeMapper.xml:1-200

治理配置

治理配置以 govern_conf 表存储,字段包含自增主键、JSON 或开关字符串 confStr,以及配置类型 confType。

配置类型 含义 默认行为
useOpenInfo 是否启用开户信息模式 未配置时不使用开户信息
duplicate 是否启用去重治理 未配置时不清理重复数据
hasGovern 导入数据时是否跳过治理 未配置时不跳过
other 其他 JSON 扩展配置 通过 getOtherConfStr 读取键值

GovernConfService 还负责根据配置选择实际使用的通话表和交易表:

  • 通话表:未启用开户信息时为 call_record;启用时为 use_open_info_call_record。
  • 交易表:启用去重时为 trans_record_all;未启用去重时为 trans_record。

这些选择会缓存到案件级配置缓存中,避免每次治理都重复查库。

章节来源

  • GovernConf.java:1-62
  • GovernConfService.java:20-113
  • GovernConfMapper.xml:1-5

治理任务流水线

GovernService.calcTask 是治理任务的主入口,负责上下文绑定、防重入、阶段编排和异常处理。

flowchart TD
    Start(["开始 calcTask"]) --> BindContext["绑定案件与用户上下文"]
    BindContext --> CleanConfig["清理案件治理配置缓存"]
    CleanConfig --> FirstStage["第一阶段:清洗、去重、关系清理"]
    FirstStage --> OpenInfo{"是否启用开户信息?"}
    OpenInfo -->|是| OpenInfoTasks["清理并复制通话到 use_open_info_call_record"]
    OpenInfo -->|否| SecondStage
    OpenInfoTasks --> SecondStage["第二阶段:时序图与分类树统计"]
    SecondStage --> ThirdStage["第三阶段:关系边计算"]
    ThirdStage --> MergeRelEdge["合并关系边阶段表"]
    MergeRelEdge --> Complete["完成治理任务"]
    Complete --> UpdateFileStatus["更新文件状态为治理完成"]
    Complete --> SendDone["推送 100% 进度并关闭 SSE"]

图表来源

  • GovernService.java:120-200
  • GovernService.java:201-450
  • GovernService.java:451-760

第一阶段:清洗、去重与关系清理

  • 并行执行交易去重、通话去重和关系清理。
  • 如果启用去重,会从临时表或清洗中间表拷贝最终通话数据到 call_record。
  • 失败会中断整个流水线,防止半成品继续落库。

第二阶段:时序图与分类树统计

  • 执行 GovernCache.getSql() 创建时序图相关数据。
  • 统计基础表节点、人员节点、银行/运营商节点。
  • 若启用开户信息,额外统计 use_open_info_call_record 的人员和运营商节点。
  • 调用 AiGovernService.calcAiTree() 补充 AI 动态表治理节点。

第三阶段:关系边计算与合并

  • 分别计算通话关系边、交易关系边和其他规则关系边。
  • 最后统一合并到正式关系边表,供图谱、搜索和下游 agent 消费。

章节来源

  • GovernService.java:120-200
  • GovernService.java:201-450
  • GovernService.java:451-760

治理结果处理器

治理模块使用 MyBatis ResultHandler 把原始记录流式转换为关系边,达到阈值后批量插入,降低内存压力和数据库写入压力。

处理器 输入 输出 关键逻辑
TransResultHandler TransRecord PersonRelEdge 根据借贷标志调整方向,对方为空时降级为姓名或摘要节点
CallResultHandler CallRecord PersonRelEdge 根据主被叫方向交换节点,固定次数为 1,类别为通信

两者都维护一个缓存列表,达到 3000 条后批量插入 PersonRelEdgeMapper,并在结束时 flush 剩余数据。

flowchart TD
    Read["读取一条原始记录"] --> Validate{"记录是否为空?"}
    Validate -->|是| Next["跳过"]
    Validate -->|否| Build["转换为 PersonRelEdge"]
    Build --> Cache["加入批量缓存"]
    Cache --> Threshold{"缓存 >= 3000?"}
    Threshold -->|是| BatchInsert["批量插入关系边表"]
    BatchInsert --> Clear["清空缓存"]
    Threshold -->|否| End(["等待下一条"])
    Clear --> End

图表来源

  • TransResultHandler.java:1-133
  • CallResultHandler.java:1-124

章节来源

  • TransResultHandler.java:1-133
  • CallResultHandler.java:1-124

治理树节点结构与语义

治理树节点不是简单目录,而是业务分类与数据实体的混合拓扑:

字段 含义 说明
id 节点主键 正 id 用于既有表;负 id 表示 AI 动态表
pid 父节点 id 根节点通常为 1
type 节点类型 如 table、person、bank、yys、no_yys、call_person 等
tableNameEn 目标英文表名 指向治理后的实际表或视图
tableNameCn 展示中文名 可以是表中文名、人员姓名、银行名、运营商名
dataCount 数据量 用于过滤空节点和前端排序
aiTemplateId AI 模板 id 仅 AI 动态表节点填充,字符串形式避免 JS 精度丢失

治理树的状态主要由 dataCount 控制:统计完成后大于 0 的节点才进入前端树;AI 动态表节点通过负 id 与真实模板 id 的映射参与治理树。

章节来源

  • GovernTree.java:1-56
  • GovernTreeService.java:60-120
  • GovernService.java:250-350
  • GovernTreeMapper.xml:1-200

依赖关系分析

治理模块与多个子系统存在明确依赖:

graph LR
    GOVERN["GovernService"] --> AICLEAN["AiCleanService / AiGovernService"]
    GOVERN --> DM["DmService / FileInfoMapper"]
    GOVERN --> GRAPH["GraphService"]
    GOVERN --> OTG["TimeSeriesService"]
    GOVERN --> PERSON["PersonBasicInfo / PersonLibNo"]
    GOVERN --> CALL["CallRecord / CallRecordAll"]
    GOVERN --> TRANS["TransRecord / TransRecordAll"]
    GOVERN --> EDGE["EdgeConf"]
    GOVERN --> REL["PersonRelEdge"]
    GOVERN --> MAPPERS["GovernMapper / GovernTreeMapper"]

图表来源

  • GovernService.java:1-200
  • GovernService.java:451-760

治理模块的耦合特征如下:

  • 高内聚:治理任务编排、配置访问、树查询集中在 govern 模块。
  • 低侵入:治理结果以关系边、治理树和文件状态形式输出,不直接侵入下游业务内部实现。
  • 强依赖外部表:治理过程依赖 call、trans、person、dm 等模块提供的数据和表结构。
  • 可扩展:新增治理规则可通过 EdgeConf、GovernCache 映射、AiGovernService 和自定义结果处理器扩展。

章节来源

  • GovernService.java:1-200
  • GovernService.java:451-760

性能与并发特性

治理模块在性能和并发方面做了专门设计:

特性 实现方式 目的
单案件互斥 RUNNING_CASES 原子集合 防止同一案件双击或双标签页互相 truncate 数据
异步执行 ThreadUtil.execAsync + 虚拟线程执行器 大案件不阻塞其他用户的任务
阶段超时 CompletableFuture.orTimeout 防止某个阶段长期挂起
进度推送 SlowDownProgress + SSE 前端看到渐进式治理进度
批量写入 结果处理器每 3000 条批量插入 减少数据库写入压力
上下文绑定 CaseContextHolder.runWith 保证跨线程数据源路由和 SSE 接收者正确
活跃探针 GovernActivityProbe 告诉数据源回收器不要关闭正在治理的案件连接

治理任务的线程模型需要注意:

  • Controller 层捕获当前案件和用户 ID。
  • 异步线程没有 ThreadLocal 登录态,必须显式绑定。
  • 阶段异常必须上抛,不能吞掉,否则后续阶段会基于半成品数据继续运行。
  • 完成时必须关闭 SSE,避免前端一直等待。

章节来源

  • GovernService.java:20-120
  • GovernService.java:201-450
  • GovernActivityProbe.java:1-17
  • GovernController.java:40-72

使用示例

定义治理树

治理树的静态结构来自已有表信息和 AI 清洗模板:

  1. 系统通过表元数据生成基础治理树节点,例如通话记录、交易记录等。
  2. 治理任务执行时统计各表数据量,写入 govern_tree。
  3. 人员维度节点根据人员基本信息、卡号和手机号生成。
  4. 银行和运营商维度节点按交易和通话记录分组生成。
  5. 若启用开户信息,额外生成 use_open_info_call_record 下的人员和运营商节点。
  6. AI 动态表节点由 AiGovernService.calcAiTree() 补充,负 id 对应 ai_clean_template.id。

前端通过 /gt/tree 获取树结构,再通过 /gt/getTreeTransPersonPage、/gt/getTreeTransBankPage、/gt/getTreeCallPersonPage、/gt/getTreeCallOperPage 等接口查看具体数据。

绑定治理规则

治理规则主要通过以下机制绑定:

  • 既有规则:通过 EdgeConf 配置其他类型数据的节点和关系边。
  • 清洗规则:由 AI 清洗模板或既有模板决定字段归一方式和清洗函数链。
  • 治理开关:通过 govern_conf 控制是否启用开户信息、去重和导入时是否跳过治理。
  • 时序图规则:通过 GovernCache.TABLE_MAPPINGS 定义源表到标准列的映射。

执行治理任务

前端调用流程:

  1. 建立 SSE 连接:GET /govern/sse。
  2. 触发治理:GET /govern/calcTask?taskProcess=66。
  3. 后端校验案件上下文,尝试占位防止并发。
  4. 异步执行治理流水线,逐步推送进度。
  5. 完成后推送 100% 并关闭连接。

后端关键约束:

  • 必须先打开案件,否则抛出“请先打开案件后再执行数据治理”。
  • 同一案件只能同时跑一条治理流水线。
  • 失败时推送治理失败消息,而不是静默成功。

查看治理结果

治理结果体现在多个位置:

  • 治理树:节点数据量增加,人员、银行、运营商维度可见。
  • 关系边:通话、交易、其他规则生成的关系边进入关系边表。
  • 文件状态:治理完成后文件状态更新为治理完成。
  • 时序图:DuckDB 中生成时序图所需数据。
  • 下游模块:search、dm、otg、agent 可消费关系边、治理树和外部表。

章节来源

  • GovernController.java:25-72
  • GovernTreeController.java:20-122
  • governApi.ts:1-200
  • dto.ts:1-121
  • GovernService.java:120-450
  • GovernTreeService.java:60-120

结果消费与扩展指南

search、dm、otg 和其他模块如何消费治理结果

  • search:消费治理后的通话、交易、人员等表,以及治理树提供的分类维度。
  • dm:治理完成后更新 FileInfo.fileStatus,并可能结合外部表进行建模。
  • otg:通过 GovernCache 生成的 SQL 在 DuckDB 中创建时序图数据。
  • agent:通过 GovernTableTool 访问治理结果表,辅助智能体进行分析。
  • 图谱:关系边是图谱关系的重要输入,治理模块负责将原始记录转化为结构化关系边。

    graph TB
    RESULT["治理结果"] --> SEARCH["search 模块"]
    RESULT --> DM["dm 模块"]
    RESULT --> OTG["otg 模块"]
    RESULT --> AGENT["agent 工具"]
    RESULT --> GRAPH["图谱模块"]
    

[此图为概念性流程图,不直接映射具体代码结构]

扩展新治理规则

如果需要在治理流水线中加入新的业务规则,建议遵循以下路径:

  1. 新增治理树节点类型:在 GovernService 统计阶段新增节点插入逻辑,或在 GovernTreeMapper.xml 新增统计 SQL。
  2. 新增关系边规则:
    • 如果是既有表,参考 calcOtherRel,通过 EdgeConf 配置节点字段、关系名称和类别。
    • 如果是通话或交易,参考 calcCallRel、calcTransRel 和对应结果处理器。
  3. 新增结果处理器:
    • 新建实现 ResultHandler<T> 的处理器。
    • 在缓存达到阈值后批量插入 PersonRelEdge。
    • 在治理任务阶段调用该处理器。
  4. 新增治理配置:
    • 在 govern_conf 表中新增配置项。
    • 在 GovernConfService 中添加读取方法,并在治理任务中使用。
  5. 新增时序图映射:
    • 在 GovernCache.TABLE_MAPPINGS 中新增源表到标准列的映射。
  6. 新增 AI 动态表治理节点:
    • 通过 AiGovernService 把 AI 清洗模板纳入治理树。

扩展新结果处理器

新增结果处理器时应注意:

  • 使用 SpringUtil.getBean 获取 PersonRelEdgeMapper。
  • 维护本地缓存列表,达到 3000 条后批量插入。
  • 提供 end() 方法处理剩余数据。
  • 转换逻辑要处理空值、方向、类别、金额和时间等关键字段。
  • 日志要区分单条处理和批量插入,便于排障。

章节来源

  • GovernService.java:451-760
  • GovernTreeMapper.xml:1-200
  • TransResultHandler.java:1-133
  • CallResultHandler.java:1-124
  • GovernConfService.java:20-113
  • GovernCache.java:1-200
  • AiGovernService.java
  • GovernTableTool.java
  • AiCleanService.java
  • GraphService.java
  • DmService.java
  • TimeSeriesService.java

故障排查

常见问题和定位建议:

现象 可能原因 排查建议
治理任务提示“请先打开案件” Controller 未捕获案件上下文 检查请求是否携带有效案件
治理任务被拒绝 同案件已有治理任务在运行 等待前一个任务完成或检查并发触发
治理进度卡在某一阶段 某阶段超时或数据库执行异常 查看阶段日志和数据库慢查询
治理失败但前端仍显示正常 异常被吞掉 确认 awaitStage 和 exceptionally 是否正确上抛
SSE 进度推给错误用户 异步线程未绑定 userId 检查 CaseContextHolder.runWith 使用
治理树为空 所有节点 dataCount 为 0 检查基础表是否有数据、是否启用了正确表名
AI 动态表治理节点无法翻页 JS 数字精度丢失 使用前端下发的字符串 aiTemplateId
开户信息模式下通话数据异常 开户时间范围或电话号码匹配问题 检查人员库号码时间范围和 use_open_info_call_record
关系边数量异常 借贷方向、主被叫方向或对方为空逻辑处理不当 检查 TransResultHandler 和 CallResultHandler

章节来源

  • GovernController.java:40-72
  • GovernService.java:201-450
  • GovernService.java:451-760
  • GovernTreeService.java:201-494
  • TransResultHandler.java:1-133
  • CallResultHandler.java:1-124

结论

治理模块 govern 是调查场景中连接原始数据与下游分析的枢纽。它以治理树表达业务分类和关系拓扑,以治理配置控制治理策略,以阶段化治理任务驱动清洗、时序图、分类统计和关系边构建。治理结果不仅服务于前端可视化,还被 search、dm、otg、agent 和图谱模块消费。

扩展治理能力时,应优先复用现有模式:通过配置驱动表选择和规则分支,通过结果处理器批量写入关系边,通过治理树节点表达分类维度,通过治理任务阶段管理复杂流程。这样既能保持治理链路的稳定性,又能支撑调查场景不断演进的业务需求。