图谱与图表接口.md 24 KB

图谱与图表接口

本文引用的文件

  • GraphController.java
  • GraphService.java
  • GraphQuery.java
  • GraphTransDetailQuery.java
  • GraphCallDetailQuery.java
  • GraphHis.java
  • analysis.ts
  • graph/index.vue

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 接口定义
  6. 业务实体关系
  7. 前端渲染方式
  8. 大数据量性能注意事项
  9. 调用示例
  10. 故障排查
  11. 结论

引言

本文面向后端接口使用者、前端开发者和数据分析人员,系统化说明 GraphController 暴露的图谱与图表相关 REST 接口。内容覆盖:

  • 关系图数据查询、生成、导出和快照保存等能力;
  • 图谱节点与边如何映射到人员、通话、交易等业务实体;
  • 前端 AntV G6/X6、Relation Graph、ECharts 的渲染协作方式;
  • 大数据量下的分页、过滤与导出策略;
  • curl 与前端调用示例;
  • 图谱为空、节点过多卡顿、导出失败等常见问题的排查方法。

项目结构

与图谱与图表接口直接相关的代码主要分布在以下位置:

  • 后端控制器:ai-server/src/main/java/com/zsjz/ai/module/graph/controller/GraphController.java
  • 后端服务实现:ai-server/src/main/java/com/zsjz/ai/module/graph/service/GraphService.java
  • 查询模型:GraphQuery、GraphTransDetailQuery、GraphCallDetailQuery
  • 历史记录实体:GraphHis
  • 前端 API 封装:ai-electron/frontend/src/graph/api/analysis.ts
  • 前端图谱页面:ai-electron/frontend/src/graph/views/graph/index.vue

    graph TB
    FE["前端页面<br/>graph/index.vue"] --> API_TS["前端 API 封装<br/>analysis.ts"]
    API_TS --> CTRL["后端控制器<br/>GraphController"]
    CTRL --> SVC["后端服务<br/>GraphService"]
    SVC --> MAPPER["数据库访问层"]
    SVC --> ENT_TRANS["交易记录<br/>TransRecord"]
    SVC --> ENT_CALL["通话记录<br/>CallRecord"]
    SVC --> ENT_HIS["图谱历史<br/>GraphHis"]
    

图示来源

  • GraphController.java:1-131
  • GraphService.java:1-200
  • analysis.ts:1239-1358
  • graph/index.vue:6125-6223

章节来源

  • GraphController.java:1-131
  • analysis.ts:1239-1358

核心组件

  • GraphController:对外暴露 /graph/* REST 接口,负责接收请求参数并返回统一响应体。
  • GraphService:实现图谱生成、交易明细分页、通话明细分页、节点详情、图谱历史创建/删除/读取/写入等逻辑。
  • 查询对象:
    • GraphQuery:控制图谱类型(交易/通话)、金额范围、卡号、通话号码等条件。
    • GraphTransDetailQuery:交易明细分页查询条件。
    • GraphCallDetailQuery:通话明细分页查询条件。
  • GraphHis:图谱历史记录的轻量实体,包含 id、graphName、path。
  • 前端 analysis.ts:封装所有图谱相关 HTTP 调用,包括图谱分析、明细分页、历史管理、快照读写。
  • graph/index.vue:用户交互入口,触发图谱分析、打开明细面板、保存和恢复图谱快照。

章节来源

  • GraphController.java:1-131
  • GraphService.java:1-200
  • GraphQuery.java:1-22
  • GraphTransDetailQuery.java:1-37
  • GraphCallDetailQuery.java:1-32
  • GraphHis.java:1-14
  • analysis.ts:1239-1358

架构总览

GraphController 作为统一入口,不直接处理复杂业务,而是委托 GraphService。图谱生成过程会构造 SQL,通过临时表或子查询聚合交易、通话、其他关系,最终返回节点集合与边集合。前端 analysis.ts 将业务表单字段转换为后端期望的 GraphViewQuery 结构,并调用对应接口。图谱页面 index.vue 负责组合 UI 行为,例如打开分析条件弹窗、切换图谱画布、保存历史快照。

sequenceDiagram
    participant User as "用户"
    participant Page as "graph/index.vue"
    participant Api as "analysis.ts"
    participant Ctrl as "GraphController"
    participant Svc as "GraphService"
    participant DB as "数据库"

    User->>Page: "点击生成关系图谱"
    Page->>Api: "调用 fetchGraphAnalysis"
    Api->>Ctrl: "POST /graph/view"
    Ctrl->>Svc: "graph(query)"
    Svc->>DB: "执行图谱聚合 SQL"
    DB-->>Svc: "边列表 edgeList"
    Svc-->>Ctrl: "Map{nodeList, edgeList}"
    Ctrl-->>Api: "Result<Map>"
    Api-->>Page: "标准化后的 dx/gx"
    Page->>Page: "渲染 AntV G6/X6 图谱"

图示来源

  • graph/index.vue:8019-8025
  • analysis.ts:1239-1259
  • GraphController.java:23-38
  • GraphService.java:53-120

接口定义

通用约定

  • 基础路径:/graph
  • 统一响应体:由后端 Result 包裹,前端 normalizeGraphAnalysisResponse 会从 response.data 或外层 data 中解析图谱数据。
  • 成功时:HTTP 状态码通常为 200,code 表示业务成功;失败时可能抛出服务端异常或返回错误码。
  • 认证与上下文:部分查询依赖当前登录账号、案件数据源、治理树权限等,由服务层或上游网关/拦截器处理。

1. 生成关系图谱

  • URL:POST /graph/view
  • 请求头:Content-Type: application/json
  • 请求体:GraphQuery 扩展字段,典型关键字段如下:
    • type:关系类型数组,取值包括交易类 101、102、103,以及通话类 201、202、203。
    • cards:卡号列表。
    • startMoney、endMoney:交易金额起止值。
    • callNum:通话号码。
    • 其他由前端 GraphViewQuery 传递的条件字段,如人员姓名、身份证号、时间范围等。
  • 响应体:Result<Map<String, Object>>,前端标准化后为 { code, msg, data: { dx: 节点数组, gx: 边数组 } }。
  • 错误行为:

    • 当生成的边数量超过 10000 条时,服务层抛出“当前数据量过大,请根据条件缩数据范围”的异常。
    • 未传入 type 时,返回空图谱结果。

      flowchart TD
      Start(["进入 /graph/view"]) --> CheckType["校验 type 是否为空"]
      CheckType -->|为空| Empty["返回空图谱"]
      CheckType -->|非空| BuildSQL["构造图谱聚合 SQL"]
      BuildSQL --> QueryDB["执行数据库查询"]
      QueryDB --> CountEdge{"边数量是否超过 10000"}
      CountEdge -->|是| Error["抛出数据量过大异常"]
      CountEdge -->|否| Assemble["组装 nodeList 与 edgeList"]
      Assemble --> Return["返回 Result<Map>"]
      

图示来源

  • GraphService.java:53-120
  • GraphController.java:23-38

章节来源

  • GraphController.java:23-38
  • GraphService.java:53-120
  • GraphQuery.java:1-22
  • analysis.ts:1239-1259

2. 查询交易明细

  • URL:POST /graph/transDetail
  • 请求体:GraphTransDetailQuery,常用字段包括:
    • personCardNo:本方卡号。
    • otherCardNo:对方卡号。
    • lx:交易方向或类别。
    • jdlx:借贷类型,例如收入、支出。
    • otherName:交易对方名称。
    • ext1:交易摘要。
    • transAmountSymbol、transAmount:金额比较符号与金额值。
    • 分页字段:page、limit。
  • 响应体:Result<Page<TransRecord>>,即分页的交易记录。

章节来源

  • GraphController.java:40-52
  • GraphTransDetailQuery.java:1-37
  • analysis.ts:1262-1272

3. 查询通话明细

  • URL:POST /graph/callDetail
  • 请求体:GraphCallDetailQuery,常用字段包括:
    • personPhone:本方号码。
    • otherPhone:对方号码。
    • node、clazz:图谱节点标识与分类。
    • transAmountSymbol、transAmount:金额比较符号与金额值。
    • 分页字段:page、limit。
  • 响应体:Result<Page<CallRecord>>,即分页的通话记录。

章节来源

  • GraphController.java:54-66
  • GraphCallDetailQuery.java:1-32
  • analysis.ts:1275-1285

4. 查询节点详情

  • URL:POST /graph/nodeDetail
  • 请求体:使用 GraphCallDetailQuery 作为入参,但语义上用于定位某个图谱节点,并获取该节点关联的详细信息。
  • 响应体:Result<Map<String, Object>>,具体结构由服务层决定,通常包含节点维度可展开的明细或统计信息。

章节来源

  • GraphController.java:68-72
  • GraphCallDetailQuery.java:1-32
  • analysis.ts:1288-1297

5. 获取图谱历史记录列表

  • URL:GET /graph/graphHis
  • 请求参数:可选,用于筛选历史记录。
  • 响应体:Result<List<GraphHis>>,每个记录包含 id、graphName、path。

章节来源

  • GraphController.java:74-82
  • GraphHis.java:1-14
  • analysis.ts:1312-1318

6. 创建图谱历史记录

  • URL:GET /graph/createGraphHis
  • 请求参数:
    • graphHisName:图谱记录名称。
    • 其他前端附加字段如 caseId、title、content、graphData、nodeCount、edgeCount 等。
  • 响应体:Result<GraphHis>,返回创建的记录。

章节来源

  • GraphController.java:84-92
  • analysis.ts:1300-1308

7. 删除图谱历史记录

  • URL:GET /graph/deleteGraphHis
  • 请求参数:
    • id:图谱历史记录 ID。
  • 响应体:Result<Void>。

章节来源

  • GraphController.java:94-102
  • analysis.ts:1324-1330

8. 读取图谱历史快照内容

  • URL:GET /graph/history/{id}/content
  • 路径参数:
    • id:图谱历史记录 ID。
  • 响应体:Result<String>,返回图谱快照的 JSON 字符串。

章节来源

  • GraphController.java:104-112
  • analysis.ts:1339-1345

9. 保存图谱历史快照内容

  • URL:POST /graph/history/{id}/content
  • 路径参数:
    • id:图谱历史记录 ID。
  • 请求体:JSON 字符串形式的图谱快照内容。
  • 响应体:Result<Void>。

章节来源

  • GraphController.java:114-122
  • analysis.ts:1349-1357

业务实体关系

图谱的核心实体关系如下:

  • 节点:
    • 人员节点:通常以人员姓名、身份证号、卡号等作为唯一标识。
    • 交易节点:以卡号、账户、交易摘要等标识。
    • 通话节点:以电话号码、通话方向、通话类型等标识。
    • 其他业务节点:如设备、IP、地址等,由前端 GraphViewQuery 中的扩展字段驱动。
  • 边:

    • 交易关系边:两个账户之间的资金往来,可能包含金额、方向、摘要。
    • 通话关系边:两个电话号码之间的联系,可能包含通话次数、时间范围。
    • 其他关系边:由服务层动态拼接 SQL 生成。

      erDiagram
      PERSON {
      string name
      string card_no
      string identity_code
      }
      ACCOUNT {
      string card_no
      string owner_id
      }
      CALL_RECORD {
      string from_phone
      string to_phone
      datetime call_time
      }
      TRANS_RECORD {
      string from_card
      string to_card
      decimal amount
      datetime trans_time
      }
      GRAPH_NODE {
      string node
      string clazz
      string nodecn
      }
      GRAPH_EDGE {
      string node1
      string node2
      string clazz
      string mc
      number money
      }
      
      PERSON ||--o{ ACCOUNT : "拥有"
      ACCOUNT ||--o{ TRANS_RECORD : "发起或接收"
      CALL_RECORD }o--|| CALL_RECORD : "相互联系"
      GRAPH_NODE ||--o{ GRAPH_EDGE : "被引用"
      

图示来源

  • GraphService.java:53-120
  • GraphTransDetailQuery.java:1-37
  • GraphCallDetailQuery.java:1-32

前端渲染方式

前端在图谱与图表场景中通常采用三种渲染方案:

  • AntV G6/X6:用于交互式关系图,支持拖拽、缩放、高亮、布局算法、节点自定义形状。
  • Relation Graph:用于特定业务关系图的展示与编辑,常与 G6 配合,提供领域专用可视化能力。
  • ECharts:用于辅助分析图表,如资金流向、通话频次、时间趋势等,通常在图谱侧边栏或独立图表区域展示。

    graph TB
    View["graph/index.vue"] --> AnalysisApi["analysis.ts"]
    View --> G6X6["AntV G6/X6 渲染引擎"]
    View --> RelationGraph["Relation Graph 业务视图"]
    View --> ECharts["ECharts 辅助图表"]
    AnalysisApi --> Controller["/graph/* 接口"]
    

图示来源

  • graph/index.vue:1-200
  • analysis.ts:1239-1358

章节来源

  • graph/index.vue:1-200
  • analysis.ts:551-564

大数据量性能注意事项

  • 边数量上限:服务层对图谱生成的边数量设置了 10000 条限制,超出时会抛出异常。因此必须通过类型选择、卡号、金额区间、时间范围、人员姓名等条件缩小数据范围。
  • 分页策略:
    • 交易明细和通话明细使用分页接口,建议前端按需加载,避免一次性拉取大量明细。
    • 图谱主图应优先返回精简节点与边,明细数据通过节点点击或侧边面板异步加载。
  • 过滤条件优先级:
    • 先按主体对象(卡号、手机号、身份证号)过滤。
    • 再按关系类型(交易/通话)过滤。
    • 最后按金额、时间、摘要等次要条件过滤。
  • 导出格式:
    • 图谱快照通过 /graph/history/{id}/content 保存为 JSON 字符串,适合再次导入或离线分析。
    • 如需导出图片、PDF、CSV,应由前端在拿到完整节点与边数据后进行二次处理,避免让后端承担额外渲染或大体积序列化压力。
  • 布局计算:
    • 节点过多时,G6/X6 的布局算法会成为瓶颈。建议启用增量布局、延迟渲染、可视区域内懒加载、降低动画复杂度。

章节来源

  • GraphService.java:53-120
  • GraphController.java:40-72
  • analysis.ts:1262-1297

调用示例

curl 示例

  • 生成关系图谱:

    curl -X POST "http://your-host/admin/graph/view" \
    -H "Content-Type: application/json" \
    -d '{
      "type": [101, 201],
      "cards": ["卡号A", "卡号B"],
      "startMoney": "1000",
      "endMoney": "100000",
      "callNum": "13800000000"
    }'
    
  • 查询交易明细:

    curl -X POST "http://your-host/admin/graph/transDetail" \
    -H "Content-Type: application/json" \
    -d '{
      "personCardNo": "卡号A",
      "otherCardNo": "卡号B",
      "page": 1,
      "limit": 20
    }'
    
  • 查询通话明细:

    curl -X POST "http://your-host/admin/graph/callDetail" \
    -H "Content-Type: application/json" \
    -d '{
      "personPhone": "13800000000",
      "otherPhone": "13900000000",
      "page": 1,
      "limit": 20
    }'
    
  • 读取图谱历史快照:

    curl -X GET "http://your-host/admin/graph/history/1/content"
    
  • 保存图谱历史快照:

    curl -X POST "http://your-host/admin/graph/history/1/content" \
    -H "Content-Type: application/json" \
    -d '{"nodes":[],"edges":[]}'
    

前端调用示例

  • 生成图谱:

    import { fetchGraphAnalysis } from '@/graph/api/analysis';
    
    const result = await fetchGraphAnalysis({
    respondents: [{ id: '1', name: '张三' }],
    tradeMode: 'trade',
    communicationMode: 'contact',
    queryTime: ['2025-01-01', '2025-12-31'],
    });
    // result.data.dx 为节点,result.data.gx 为边
    
  • 查询交易明细:

    import { fetchGraphTransDetail } from '@/graph/api/analysis';
    
    const page = await fetchGraphTransDetail({
    personCardNo: '卡号A',
    page: 1,
    limit: 20,
    });
    
  • 查询通话明细:

    import { fetchGraphCallDetail } from '@/graph/api/analysis';
    
    const page = await fetchGraphCallDetail({
    personPhone: '13800000000',
    page: 1,
    limit: 20,
    });
    
  • 保存图谱历史:

    import { createGraphHistory, saveGraphHistoryContent } from '@/graph/api/analysis';
    
    const history = await createGraphHistory({ graphHisName: '张三关系图' });
    await saveGraphHistoryContent(history.id, snapshotJson);
    

章节来源

  • analysis.ts:1239-1358

故障排查

图谱数据为空

  • 检查是否传入了 type。如果 type 为空,服务层会直接返回空图谱。
  • 检查主体对象是否为空。前端 fetchGraphAnalysis 在未获取到对象名称时会抛错,要求先选择人员或实体。
  • 检查过滤条件是否过严:金额区间、时间范围、卡号、手机号可能导致无匹配数据。
  • 查看浏览器控制台和网络面板,确认后端是否返回空 dx/gx 或整体 data 为空。

章节来源

  • GraphService.java:53-60
  • analysis.ts:1239-1259

节点过多导致卡顿

  • 服务层会在边数量超过 10000 条时抛出异常,提示缩小数据范围。
  • 前端应避免一次性渲染全部节点和边,建议使用:
    • 分页加载明细;
    • 仅渲染可视区域或高相关度节点;
    • 关闭不必要的动画和高亮效果;
    • 将大图拆分为多个图谱标签页。
  • 若仍卡顿,检查 G6/X6 布局配置,避免使用过于复杂的力导向布局。

章节来源

  • GraphService.java:53-120
  • graph/index.vue:1-200

导出失败

  • 快照导出依赖 /graph/history/{id}/content 的读写。确认:
    • 历史 ID 是否存在;
    • 请求体是否为合法 JSON 字符串;
    • 后端文件写入权限是否正常。
  • 如果导出的是图片或报表,需在前端完成转换,避免后端承担额外格式化处理。
  • 网络层面注意跨域、鉴权、请求体大小限制。

章节来源

  • GraphController.java:104-122
  • analysis.ts:1339-1357

明细分页异常

  • 交易明细和通话明细返回 MyBatis-Plus 的 Page 对象。若前端解析失败,检查:
    • page、limit 是否为有效数字;
    • 后端是否返回标准分页结构;
    • 字段名是否与前端期望一致。

章节来源

  • GraphController.java:40-72
  • analysis.ts:1262-1297

结论

GraphController 提供了图谱生成、明细分页、节点详情和历史快照管理能力。其核心设计是:前端以业务条件驱动 GraphQuery,后端通过服务层构造 SQL 并返回节点与边;前端基于 AntV G6/X6 或 Relation Graph 渲染关系图,并使用 ECharts 补充统计分析。为避免大数据量问题,应严格限制图谱规模、使用分页与过滤、并在前端进行合理的渲染优化。导出功能以 JSON 快照为主,复杂格式应在前端处理。遇到问题时,优先从输入条件、边数量上限、分页结构和历史快照读写链路入手排查。