业务故事站
P4 Gotham

情报报告:从数据到可分发简报

分析做得再好,出不了报告就等于白做。情报报告模块用结构化 Block(heading / paragraph / table / kv)组织内容:既能从真实数据一键生成(聚合实体 / 事件 / 命中),也能手工编辑润色,还能嵌入图 / 地图 / 时间轴快照、按版本回滚,最后发布并导出 HTML / PDF / DOCX 分发给决策者。看完这 4 个故事,你就能把一次分析快速变成一份能签发的简报。

情报分析师 决策者 报告生成 结构化 Block 嵌入对象 / 版本 PDF / DOCX 导出 共 4 个故事

能 / 不能速览

✅ 这个主题能做
  • 报告 CRUD 与状态机 draft → published → archived(发布 / 归档走专用接口校验流转)
  • POST /reports/generate 从真实数据生成:按实体 / 事件 / 命中聚合自动组块
  • 内容为结构化 Block(heading / paragraph / table / list / kv),可手工增删改
  • 导出 HTML(可浏览器打印 PDF)、PDF(gofpdf,注册中文字体可渲染中文)、DOCX(OpenXML 手写)
  • 报告可关联图实体(entity_id),供回溯数据来源
⛔ 这个主题做不了
  • 嵌入对象仅 graph / map / timeline 三类,且导出 PDF / DOCX 时缩略图以说明文本替代(仅 HTML 内嵌图片)
  • PDF 依赖中文字体:无 TTF 字体时中文退化为 ASCII 并注明限制
  • DOCX 是手写最小 OpenXML,复杂排版(图片 / 分栏 / 页码)能力有限
  • 报告状态机严格:draft 不可直接归档,archived 不可再发布(无 reviewing 审核态)
  • AI 智能总结属 V2;模板已内置 3 套(案件调查 / 情报简报 / 态势总览),自定义模板管理属 V2

适用角色

本主题面向两个角色:

  • 情报分析师(核心):从数据生成报告、编辑 Block、发布与导出分发,是报告全流程的操作者。
  • 决策者:消费发布的简报(HTML / PDF / DOCX),不做编辑;通过报告状态了解分析进展。

平台管理员负责报告权限与归档管理;报告按状态(draft / published / archived)组织,方便审阅流程。

能力速览(能做什么)

报告 CRUD + 状态机

intelligence_reports 报告主表,状态 draft → published → archived,发布 / 归档走专用接口校验流转合法性。

从数据生成

POST /reports/generate:按 entity / incident / analysis / general 数据节,自动聚合实体信息、事件摘要与模式命中为结构化块。

结构化 Block

内容为 Block 序列:heading(标题)/ paragraph(段落)/ table(表格)/ list(列表)/ kv(键值对),JSON 存储,可编辑。

多格式导出

GET /reports/:id/html(浏览器预览可打印 PDF)、/pdf(gofpdf,中文字体渲染)、/docx(OpenXML 手写最小文档)。

报告回溯

报告可挂 entity_id 关联图实体,描述 / 概要 / 类型(incident / entity / analysis / general)完备,便于检索归档。

嵌入对象 + 版本

graph / map / timeline 三类"活"对象以查询参数 + 数据快照嵌入,可整体刷新;内容变更自动留版本快照,可回滚(回滚再 +1 版本)。

模板体系

预置 3 套模板(案件调查报告 / 情报分析简报 / 态势总览),POST /reports/from-template 一键从模板建报告。

调整指南(怎么调整)

  • 改生成范围:POST /reports/generate 的 sections 数组决定报告长什么样:entity 节出"实体信息 + 事件摘要 + 命中",incident 节出"事件明细 + 空间聚合 + 命中"。
  • 改报告内容:生成后的 content 是 Block 数组,可以删掉冗余段落、加 table / kv 块、改标题层级(level 1~3)。
  • 改导出效果:中文 PDF 要保证服务器能找到 TTF 中文字体(Windows 的 simhei / simkai / simfang);HTML 打印走 Ctrl+P 矢量输出。
  • 改流转节奏:草稿完善后发布(draft → published),归档(published → archived)保留历史;已归档不可再发布。
  • 改报告元信息:title / description / summary / report_type(incident / entity / analysis / general)均可更新,status 只能走发布 / 归档接口改。

做得好的场景

情报报告把"分析结论"变成"可分发成品",特别适合以下场景:
  • 一键生成简报:POST /reports/generate 从真实数据聚合实体、事件、命中,替代手工拼表格,几分钟出草稿。
  • 结构化可编辑:Block 式内容让"增删改查"都稳定可控,不用对着整篇富文本小心翼翼地改。
  • 多格式分发:HTML 给在线审阅、PDF 给正式签发、DOCX 给二次编辑,一份内容三种交付。
  • 状态可管可溯:draft → published → archived 全程留痕,发布过的报告归档后仍是决策依据。

限制与不足

以下是明确的边界,使用前先知道:
  • 嵌入对象快照是时点数据:图 / 地图 / 时间轴对象以"查询参数 + 数据快照"嵌入,快照是添加 / 刷新时刻的数据,未刷新前与实时数据不一致;PDF / DOCX 导出时缩略图以说明文本替代,仅 HTML 内嵌图片。
  • PDF 字体依赖:gofpdf 导出需要 TTF 中文字体(simhei 等),找不到时中文内容会退化为 ASCII 并注明限制,正式交付前先验证。
  • DOCX 排版有限:OpenXML 手写最小文档,标题 / 段落 / 表格 / 键值对够用,图片 / 分栏 / 复杂样式不支持。
  • 状态机严格:draft 不可直接归档(需先发布再归档),archived 不可再发布,非法流转返回 GOTHAM_REPORT_INVALID_STATUS。
  • 无 AI 总结:analysis / general 节生成的是结构化占位段落,需人工替换为分析结论;AI 智能总结属 V2。

场景故事

故事 1 POST /reports/generate 从真实数据生成《玄武集团关联网络情报简报》
背景
2026 年 8 月 15 日,苏分析师完成了"玄武集团关联网络"的联动分析,要把结论沉淀成一份简报。她不想从零排版,直接让系统从真实数据生成:以玄武集团(graph:org:xuanwu)为实体节、以近一个月为事件节,聚合实体信息、事件摘要与模式命中。
传统做法对比
以前要把图上的节点、时间轴的 9 条事件、模式命中的 3 条手工抄进 Word,复制粘贴加对齐要 2~3 小时,还容易抄错金额。现在 POST 一次请求,系统按数据节自动组块,几分钟出草稿。
角色
情报分析师(苏分析师),执行报告生成并审阅草稿。
操作步骤
  1. 进入"情报报告"页面,点击"从数据生成"
  2. 填标题《玄武集团关联网络情报简报》、报告类型选 analysis(分析报告)
  3. 配置两个数据节:entity 节(entity_id=graph:org:xuanwu)+ incident 节(近一个月时间范围)
  4. 提交 POST /reports/generate,系统生成草稿报告并落库
系统响应
生成返回新报告 id:
{ "code": 0, "data": { "id": 2 } }
GET /reports/2 可看到报告为 draft 状态,content 是 Block 序列:标题块 + 报告类型 / 生成时间段落 + "第 1 节:实体情报"(实体信息 kv + 时间轴事件摘要 table + 模式命中 table)+ "第 2 节:事件态势"(事件明细 table + 空间聚合 kv)。
结果洞察
草稿里玄武集团实体信息自动带出类型 org / 密级 secret,事件摘要聚合了 2026-07~08 的 meeting / transaction / incident 事件,模式命中带出频率与金额两条规则的命中。苏分析师只需核对数字,不用从零排版。
调整建议
生成时 entity 节一定要填 entity_id,否则输出"缺少 EntityID"占位段落;incident 节默认取近 30 天,可显式给 start_time / end_time 改窗口;生成的是 draft,确认无误后再发布。
动手试一试
登录:admin / admin1。页面路径:情报报告 → 从数据生成。输入内容:title=《玄武集团关联网络情报简报》、report_type=analysis、sections=[{kind:entity,entity_id:"graph:org:xuanwu"},{kind:incident}]。预期结果:返回报告 id,content 含实体 / 事件 / 命中聚合块,状态 draft。
限制提示
GenerateFromData 至少需要一个数据节(sections 为空报错);analysis / general 节生成的是占位段落,需人工替换为结论;数据读取器缺失时对应块输出占位说明。
故事 2 看懂 Block 结构,手工补充"研判结论"
背景
生成的草稿内容偏"数据罗列",苏分析师要在报告里补充一段人工研判结论,并把关键数字整理成键值对(评估置信度、关注级别)。她要理解报告的 Block 结构,才能精准增删。
传统做法对比
以前在 Word 里插一段文字、加个表格,鼠标点半天还容易把整篇排版点乱;现在报告内容是一块块的 JSON,想加段落就加 paragraph 块、想加键值就加 kv 块,改动范围精确可控。
角色
情报分析师(苏分析师),编辑报告 content 并保存草稿。
操作步骤
  1. 打开草稿报告,查看 content 的 Block 序列(GET /reports/2)
  2. 识别各块类型:heading / paragraph / table / kv
  3. 追加一个 heading 块"研判结论"、一个 paragraph 块(人工结论文字)、一个 kv 块(评估置信度 / 关注级别)
  4. 提交更新 PUT /reports/2 保存草稿
系统响应
报告 content 的结构示例:
[
  { "type": "heading", "data": { "text": "玄武集团关联网络情报简报", "level": 1 } },
  { "type": "paragraph", "data": { "text": "本报告汇总近一个月玄武集团及其关联方的人员、组织、船舶与事件情报。" } },
  { "type": "table", "data": { "headers": ["类型", "名称", "区域", "密级"], "rows": [...] } },
  { "type": "kv", "data": { "pairs": [["评估置信度", "高"], ["关注级别", "S1"]] } }
]
更新成功后 PUT 返回 {code:0, data:{id:2}},content 已含新增的"研判结论"块。
结果洞察
报告从"纯数据块"变成了"数据 + 结论"完整成稿:关键实体表、重点事件表保持结构,新增研判结论点明"近一个月关联活动频繁,涉机密数据仅管理员与授权分析师可访问"。决策者拿到就能读。
调整建议
表格行的长度不要超过表头数,多余列会被截断;heading 的 level 填 1~3(对应 h1/h2/h3);段落文字避免手拼 HTML,导出时会统一转义防注入。
动手试一试
登录:admin / admin1。页面路径:情报报告 → 打开草稿 → 编辑。输入内容:追加 heading"研判结论"、paragraph 正文、kv(评估置信度=高 / 关注级别=S1)。预期结果:content 里出现对应块,保存后 GET /reports/:id 可见更新。
限制提示
status 只能走发布 / 归档接口修改,PUT 更新不带状态流转;content 为 nil 时保留原值,要清空需显式传空数组;保存时即校验块结构,未知块类型 / 缺必填字段直接 400(带块序号),编辑时别造新 type。
故事 3 发布并导出 HTML / PDF / DOCX,分发给决策者
背景
简报成稿后,苏分析师要在 8 月 15 日下午的专题会上交给玄武集团风控总监。她需要:一份在线预览(HTML)、一份正式签发件(PDF)、一份给法务二次编辑的版本(DOCX)。三种格式同一份内容,走发布再导出。
传统做法对比
以前要从 Word 另存 PDF、再导出文本给同事排版,格式经常错位,图片表格一导出就乱;现在一份结构化内容三种导出都是服务端渲染,格式稳定,耗时从半天压缩到几分钟。
角色
情报分析师(苏分析师)负责发布与导出;决策者(风控总监)消费 HTML / PDF / DOCX 三种形态。
操作步骤
  1. 对草稿报告点"发布",POST /reports/:id/publish 状态转 published
  2. 打开 HTML 预览 GET /reports/:id/html,在线核对排版
  3. 导出 PDF:GET /reports/:id/pdf(服务端 gofpdf 生成,中文字体渲染)
  4. 导出 DOCX:GET /reports/:id/docx,交给法务二次编辑
系统响应
发布返回:
{ "code": 0, "data": { "id": 2, "status": "published" } }
HTML 接口返回完整文档(含 @media print 打印样式),PDF 接口返回 application/pdf 字节(无中文字体时退化为 ASCII),DOCX 接口返回 OpenXML 文档(application/vnd...wordprocessingml.document)。
结果洞察
HTML 在专题会上投屏流畅,PDF 用于归档签发,DOCX 由法务补充合规意见后回传。风控总监根据简报中的"评估置信度=高 / 关注级别=S1"决定对玄武集团关联交易启动专项核查,报告直接支撑了行动决策。
调整建议
PDF 中文渲染依赖 TTF 字体,正式签发前先导一次验证中文是否完整;HTML 打印可走浏览器 Ctrl+P 出矢量 PDF(中文保真);报告归档(published → archived)后保留历史,便于年度回溯。
动手试一试
登录:admin / admin1。页面路径:情报报告 → 打开报告 → 发布 → 导出。输入内容:POST /reports/:id/publish,再分别 GET /reports/:id/html、/pdf、/docx。预期结果:状态变 published;HTML / PDF / DOCX 三种格式均可打开。
限制提示
draft 不可直接归档(需先发布);archived 不可再发布(返回 GOTHAM_REPORT_INVALID_STATUS);PDF 无中文字体时中文退化为 ASCII 且注明限制;DOCX 无图片 / 分栏等复杂排版能力。
故事 4 嵌入"关系子图 + 事件趋势"快照,改坏了还能从版本列表一键回滚
背景
8 月 20 日苏分析师要给简报加两个"活"视图:玄武集团的关联关系子图(graph 对象,entity_id=graph:org:xuanwu、depth=2)和近 30 天事件趋势(timeline 对象,bucket=day、window=3、horizon=5)。同时她记得 8 月 15 日发布的版本保存过,想把"改坏了的最新一版"回滚到之前的稳定版本。
传统做法对比
以前要把图截图、时间轴画图导图再贴进 Word,数据一变图就过期,重做一轮 2 小时;改坏版本只能在 Word 里 Ctrl+Z,关了文件就没了。现在嵌入对象带查询参数 + 数据快照,点一下刷新就重渲染;版本按次留快照,改坏一键回滚。
角色
情报分析师(苏分析师),添加嵌入对象、刷新快照并做版本回滚。
操作步骤
  1. 打开报告,POST /reports/:id/objects 添加 graph 对象(entity_id=graph:org:xuanwu、depth=2)
  2. 再添加 timeline 对象(bucket=day、window=3、horizon=5),并改一处正文触发版本 +1
  3. 一周后数据更新,POST /reports/:id/objects/refresh 整体刷新快照
  4. 发现最新版编辑出错,GET /reports/:id/versions 后 POST /reports/:id/versions/1/restore 回滚
系统响应
添加对象返回:
{ "code": 0, "data": { "id": 5 } }
timeline 对象快照含聚合 + 预测 + 近期事件:
{
  "type": "timeline", "bucket": "day",
  "aggregate": [ { "bucket": "2026-08-01", "count": 1 } ],
  "forecast": [ { "time": "2026-08-16", "actual": null, "ma": 1.0, "ses": 1.0 } ],
  "events": [ { "id": 9, "title": "华南航线异常", "event_type": "incident", "location": "广州" } ]
}
回滚后版本列表新增一条 CreatedBy="restore:1" 的快照,报告内容恢复为该版本。
结果洞察
报告从"纯文本块"变成"数据 + 活视图":关系子图把玄武集团的 1 跳成员与资金链路带进文档,事件趋势让决策者直接看聚合折线;快照刷新一次就把过期图更新掉。回滚后报告内容与"8 月 15 日发布版"一致,且"回滚前"的版本也保留着,历史完整可追溯。
调整建议
嵌入对象 QueryParams 决定快照内容(图:entity_id/depth;地图:bbox/heatmap;时间轴:start/end/bucket/window/horizon);导出前先 refresh 快照保证离线文档最新;版本按"内容变更"自动留痕,每次发布前看一眼 versions 确认快照齐全。
动手试一试
登录:admin / admin1。页面路径:情报报告 → 打开报告 → 添加嵌入对象 / 版本管理。输入内容:object_type=graph、query_params={"entity_id":"graph:org:xuanwu","depth":2};再 POST /reports/:id/objects/refresh 与 /versions/1/restore。预期结果:对象列表出现 2 条快照;刷新后快照时间更新;回滚后版本再 +1 且 CreatedBy 含 restore。
限制提示
嵌入对象类型仅 graph / map / timeline 三类,未知类型报错;快照是添加 / 刷新时刻的数据,未刷新前与实时数据可能不一致;docx / PDF 导出时缩略图以说明文本替代(仅 HTML 内嵌图片);版本回滚后要重新发布才能让归档读者看到新状态。

常见问题

报告内容是 HTML 吗?

不是。报告 content 是结构化 JSON 的 Block 序列(heading / paragraph / table / list / kv),导出时再由服务端渲染成 HTML / PDF / DOCX。这样一份内容多格式输出,也方便程序化编辑与检索。

生成报告和手写报告有什么区别?

POST /reports/generate 从真实数据自动组块:实体信息、事件摘要、模式命中都从图 / 时间轴 / 命中服务实时读取聚合,适合"把分析过程沉淀成稿";手写报告则是完全由你定义 Block,适合有固定版式的场景。两者都是同一套 Block 结构,可混用。

PDF 导出为什么可能没有中文?

PDF 用 gofpdf 生成,中文字符需要 TTF 字体(Windows 的 simhei / simkai / simfang 等)。服务器找不到 TTF 字体时,中文会退化为 ASCII 并在内容中注明限制。正式签发前先验证一次;HTML 打印(Ctrl+P)不受此限制。

已发布的报告还能改吗?

可以更新内容(title / content 等),但 status 只能通过发布 / 归档接口流转:draft → published → archived 单向推进,archived 不可再发布。要改已归档报告,通常的做法是复制一份新报告来改。

报告里的图 / 地图能带进文档吗?

能。报告支持嵌入对象(graph / map / timeline 三类),以"查询参数 + 数据快照"方式嵌入:添加时服务端实时渲染快照(图子图 / 地图 bbox 与热力 / 时间轴聚合与预测),导出 HTML / PDF / DOCX 时直接渲染快照离线可读;数据变化后可整体刷新快照。注意快照是添加时刻的数据,刷新前与实时数据可能不一致。

主题小结

一句话:情报报告的玩法是"从数据生成 → 编辑 Block → 嵌入对象 → 版本管理 → 发布 → 导出分发"。记住三个边界:内容是结构化 Block 而非 HTML、PDF 中文依赖 TTF 字体、状态机三态无审核态。会生成、会编辑、会发布,你就能把一次分析变成一份能签发的简报。