feat: add persistent document handling and protect note drafts

Add HTTP PaddleOCR-VL settings and shared document previews for chat and knowledge imports. Preserve attachment originals and parsed assets across drafts, messages and queues; support explicit image OCR, selecting document images into a conversation draft, and restoring queued input for editing.

Protect unsaved note bodies and titles during navigation and asynchronous updates. Match canvas analysis to source revisions, invalidate affected comments, preserve annotations during pagination, and provide a resizable record index with saved width preferences.

Existing OCR settings retain local behavior. Historical attachments without saved originals are not reconstructed. Advanced OCR options depend on the configured service; image sending depends on the effective model and Runtime.

Validation: full typecheck and lint passed; 477 focused tests passed across 12 files; staged whitespace checks passed. The full repository suite was not rerun for this commit.

Release note: Keep note drafts safe while switching workspaces, resize the record index, and revisit saved document attachments with OCR previews and selected images in chat.
This commit is contained in:
mesalogo
2026-09-19 16:51:10 +08:00
parent 17186b0c11
commit 935a8f56bf
95 changed files with 6232 additions and 553 deletions
+108 -29
View File
@@ -22,7 +22,7 @@ GoodBuddy 需要用同一条可信文档解析链路服务以下场景:
- XLSX 工作表 XML 与共享字符串;
- PPTX 幻灯片文字。
聊天附件、知识库和测试解析通过统一的 `DocumentParsingService` 使用已保存的工作流。
聊天文档附件、知识库和测试解析通过统一的 `DocumentParsingService` 使用已保存的工作流。
扫描 PDF 和 PPTX 幻灯片内嵌图片可使用已安装、已校验的本地 OCR 模型识别;
PPTX 的当前能力和边界见 [PPTX 图片流程](#75-pptx-图片流程)。
@@ -31,7 +31,11 @@ PPTX 的当前能力和边界见 [PPTX 图片流程](#75-pptx-图片流程)。
- DOC、XLS、PPT 等旧版二进制 Office 格式不支持;
- Office 解析主要提取文字,不能完整保留表格、公式、图表和版面;
- DOCX、XLSX 内嵌图片尚未接入 OCR;
- Office 格式转换和远程 OCR 服务尚未接入。
- Office 格式转换尚未接入;HTTP PaddleOCR-VL 已接入,部署高级模型能力需要使用文件测试。
聊天文档原件、解析正文和提取图片现保存为会话文件资产,数据库记录草稿、消息和队列引用。
已有历史附件若未保存原件,不会被升级自动补齐。第 13 节保持需求定义,当前实现与证据分别见
[生产实现](./implementation.md)和[进度](./progress.md#2026-09-19-实现与验证)。
## 3. 产品原则
@@ -48,7 +52,7 @@ PDF 不是所有文档唯一的中间格式。解析应同时保留:
| 场景 | 默认预设 | 行为 |
| --- | --- | --- |
| 聊天附件 | 自动解析 | 优先快速提取,文本不足时按需 OCR,完整解析文本加入当前请求 |
| 聊天文档附件(PDF、Office 等) | 自动解析 | 优先快速提取,文本不足时按需 OCR,完整解析文本加入当前请求 |
| 知识库导入 | 完整索引 | 完整解析、按页或工作表定位、按需 OCR、分块与索引 |
| 扫描文档 | OCR | 页面渲染、文字识别、置信度与定位保留 |
| 表格分析 | 语义优先 | 单元格和值优先,PDF 或图片补充图表与打印布局 |
@@ -82,6 +86,20 @@ PDF、DOCX、PPTX 和 XLSX 的解析结果保留章节定位及全文,不在
错误显示在输入区。剪贴板中的虚拟文档若没有本地路径,提示先保存到本地后添加;
无本地路径的截图继续使用图片粘贴入口。
#### 3.2.2 纯图片与文档的路由(规划)
普通聊天图片默认作为图片输入发送,跳过文档解析与 OCR;是否可发送取决于本次实际生效的
模型和 Runtime 图片输入能力。下表定义提示、显式 OCR 操作和原图持久化的验收要求,
各 Runtime 的真实验证范围见进度文档。
| ID | 产品要求与验收 |
| --- | --- |
| FR-I1 | 普通图片附件默认直接送入支持图片输入的模型,不自动 OCR。当前模型或 Runtime 不支持时明确提示,用户可选择“提取图片文字”或切换支持图片输入的模型;不得静默转成 OCR 文本并声称已发送原图。 |
| FR-I2 | 用户明确选择“提取图片文字”时,使用文档解析中已保存的 OCR 来源与选项,即使聊天模型支持图片输入也执行 OCR。成功后附件显示“原文件名 · 提取文字”和“仅发送提取文字,原图保留”,本次仅发送文字;可显式改回发送原图并重新校验能力。失败、取消或未提取到文字保持原发送方式及草稿,不隐式切换 Provider。 |
| FR-I3 | 纯图片附件长期保留原始图片及其会话、消息、附件归属,重启后可查看。请求可按实际格式或容量限制生成缩放、转码副本,但不得覆盖原图。纯图片不强制生成 parsed.md 或解析清单;显式 OCR 才产生关联的解析结果。持久化完成后才接受发送或保存队列引用,删除按有效引用清理,草稿引用的资源也须保留。 |
| FR-I4 | PDF、Office 的原生解析、按需 OCR 与纯图片直传分开。知识库中的图片文字提取和索引按知识库工作流决定,不随聊天模型视觉能力改变;这不代表当前已支持独立图片导入或图片向量检索。 |
| FR-I5 | 聊天与知识库解析预览提供图片多选,默认零选择;“添加所选图片”将图片复制为明确目标会话草稿的独立视觉附件,保留文档、页码及图片来源,不自动发送或附加全部图片。区分待添加勾选与已在草稿,重复添加同一来源图片幂等。父文档文本仅加入一次,父文档与已复制图片独立移除;知识库删除或重解析不影响会话副本。无有效会话时提供选择或新建会话流程。添加与发送共用既有附件数量、容量及有效模型/Runtime 校验,超限整批拒绝并保留选择,不静默丢图或抽样。 |
### 3.3 本地优先
- 文本层和本地 OCR 均在设备上处理;
@@ -113,18 +131,20 @@ OCR 模型区沿用语音模型管理模式:
- “打开模型仓库”直接显示在 OCR 模型卡片右上角,并使用当前下载源对应仓库;
- 模型操作即时生效,解析策略仍通过分类页头的“保存设置”提交。
### 4.1 第一阶段字段
### 4.1 设置字段
- 聊天附件预设:`auto`、`fast-text`、`high-fidelity`;
- 知识库预设:`complete-index`、`fast-index`、`high-fidelity`;
- PDF OCR 策略:`auto`、`always`、`disabled`;
- OCR 来源:第一阶段固定为 `local`,远程服务入口禁用;
- OCR 来源:`local` 或 HTTP PaddleOCR-VL,旧设置仍使用本地;
- 本地 OCR 模型:`pp-ocrv6-tiny`、`pp-ocrv6-small`、`pp-ocrv6-medium`;
- 单文档最大页数;
- OCR 并发数;
- 单页超时。
OCR 来源使用互斥选择。本地模型选中后才显示模型下拉列表、按需下载、导入和本地 OCR 参数;远程服务计划接入 MinerU、PaddleOCR-VL 等接口,第一阶段保持可读但禁用。来源选择本身就是用户的明确决策,不再显示额外的“隐私与云端处理”授权区。
OCR 来源使用互斥选择。本地模型选中后才显示模型下拉列表、按需下载、导入和本地 OCR 参数;
远程显示 PaddleOCR-VL 地址、认证及高级选项。两套配置分别保留,来源选择本身就是用户的
明确决策,不再显示额外的“隐私与云端处理”授权区。MinerU 不在本次范围。
## 5. 架构
@@ -139,7 +159,7 @@ OCR 来源使用互斥选择。本地模型选中后才显示模型下拉列表
└─ ParsedDocument merger
```
`DocumentParsingService` 是唯一场景入口:
`DocumentParsingService` 是文档解析的统一场景入口;普通聊天图片直传不经过此接口:
```ts
type DocumentParsingPurpose = 'chat-attachment' | 'knowledge-index'
@@ -158,7 +178,8 @@ type DocumentParsingService = {
## 6. 统一结果
第一阶段兼容现有 `ParsedDocument`,并逐步扩展:
现有 `ParsedDocument` 文本结构如下;第 13 节要求补齐图片、解析配置与持久化引用,具体
契约由 [HTTP 技术设计](./http-paddleocr-vl-technical-design.md#结果与资源)维护:
```ts
type ParsedDocument = {
@@ -363,29 +384,15 @@ DOC、XLS、PPT 通过 `DocumentConversionProvider` 转换:
`auto` 工作流可以从 OCR 回退到可靠的原生文本,但不能把空结果标记为成功。知识库导入失败时保留来源和可重试上下文。
## 11. 实施阶段
## 11. 实施范围与顺序
### 阶段一
本地 OCR 基线与已验证能力见第 2、7 节及聊天附件技术说明。第 8 节的旧 Office 转换和
扩展语义解析保留为独立规划,不因 HTTP 接入而承诺已经实现。
- 新增文档解析设置分类和持久化契约;
- 建立 `DocumentParsingService`,供聊天和知识库共用;
- 将无文本 PDF 识别为可触发 OCR 的明确状态;
- 接入 PP-OCRv6 Tiny、Small、Medium 的双来源下载、校验、ZIP 离线迁移、删除与
WASM Worker;
- 实现真实文件测试和六平台验证入口。
### 阶段二
- 增强 DOCX、XLSX、PPTX 语义结构;
- 实现按页混合文本层与 OCR;
- 增加版面、表格和阅读顺序。
### 阶段三
- 增加 LibreOffice 和 API 转换 Provider;
- 支持 DOC、XLS、PPT;
- 增加 MinerU、PaddleOCR-VL 等远程 OCR 服务连接配置;
- 增加高保真工作流和解析结果预览。
第 13 节及 FR-I1 至 FR-I5 是本次约定的完整功能范围:HTTP Provider、设置与高级选项、
三入口预览、文档和原图持久化、显式图片 OCR、文档选图加入会话及发送、失败恢复与清理。
实施依赖顺序见 [技术设计](./http-paddleocr-vl-technical-design.md#实施与验证顺序),不构成
分批产品交付或推迟选图发送的许可。产品完成须覆盖 [完整验收矩阵](./ui-design.md#8-完整验收矩阵)。
## 12. 验收
@@ -405,3 +412,75 @@ DOC、XLS、PPT 通过 `DocumentConversionProvider` 转换:
- 测试解析不会创建聊天消息或知识库文档;
- 选择本地模型时没有任何文档上传;
- 文档中的提示词不会改变系统、模式或工具权限。
## 13. HTTP PaddleOCR-VL 扩展(规划)
状态:已接入生产解析、设置、预览及资源流程。部署实测、验收层次与未覆盖项见
[进度](./progress.md#2026-09-19-实现与验证),行为规则见 [逻辑设计](./logic-design.md)。
用户需要使用已有内网 OCR 服务解析扫描件,并保留插图、表格和来源页码;文档中的页眉、
页脚有时包含合同编号或说明,不能只提供服务默认过滤结果。
| ID | 产品要求与验收 |
| --- | --- |
| FR-H1 | 在文档解析设置中明确选择本地 OCR 或 HTTP PaddleOCR-VL,保存服务地址和所需认证。HTTP 路径无需安装本地 OCR 模型;已有配置继续选本地来源。 |
| FR-H2 | 聊天文档附件、知识库导入和测试解析使用同一来源及解析设置。PDF 原生文本优先、快速模式禁用 OCR、高保真模式全页 OCR 的既有规则继续适用。PPTX 仍按直接内嵌图片识别并保留幻灯片定位。纯图片路由及显式 OCR 遵循 FR-I1、FR-I2。 |
| FR-H3 | 默认保存 HTTP 解析返回、被结果引用的插图字节及页码、Markdown 关联,重开后可查看;同名图片键仅在页内有效,跨页不得覆盖。支持 Markdown 图片及 HTML img、table 的预览。测试产物不进入聊天或知识库。图片缺失、超限或无法保存必须显示具体警告或失败,不能将带断图的结果表示为完整成功。 |
| FR-H4 | 高级设置允许保留或排除页眉、页脚、页码、脚注等标签,也允许恢复服务默认值。配置方向分类、去扭曲、版面检测、图表、印章、图片块 OCR 和 Markdown 格式选项时,应展示部署是否仅声明接口、是否经过真实样例验证。 |
| FR-H5 | 可选跨页表格合并与标题层级调整。启用后保留原始页面来源和图片引用;没有观察到合并效果时不得宣传为已支持跨页表格恢复。 |
| FR-H6 | HTTP 错误、超时、取消和图片持久化失败可诊断、可重试。取消后不再发起后续页或重组请求,不自动切换服务或本地模型。无文字且无有效图片时失败;仅有图片时明确标为仅图片结果,可预览和选择图片但不能发送空文本附件。部分解析不能标成完整成功。 |
| FR-H7 | 测试解析能核对文字、表格、图片数量、页码、过滤设置与耗时。服务没有置信度时显示“未提供”,不补成 1 或 0。 |
| FR-H8 | 已发送的聊天文档附件须长期保存原文件、解析文本和提取图片;应用重启后能从历史附件重新查看,成功持久化后移动或删除外部原文件不影响查看。资源属于会话,存放于应用 userData 管理的文件资源中,数据库保存归属和引用关系,不依赖 Runtime 项目工作目录。 |
| FR-H9 | 未发送文档附件使用应用管理的暂存资源;移除、导入失败或取消时仅清理本次无有效引用的暂存,保留其他附件和草稿。发送被接受及队列记录持久化之前完成会话归属和资源持久化,恢复队列不能依赖已丢失的内存 contexts 或外部原路径。删除会话清理其独占资源,仍被草稿或其他有效对象引用的资源须保留;不得按临时目录名在启动或退出时一律删除。 |
| FR-H10 | 知识库解析文本与 chunks 继续入库;图片归知识库文档所有,独立于聊天会话。managed 与 reference 来源的解析派生文件均由应用管理,不写入外部原文件目录。重解析或同步只有在新结果及必要资源成功保存后才替换旧结果;失败或取消保留旧结果,删除文档或来源时清理无引用的派生资源。 |
| FR-H11 | 每次解析使用启动时已保存的 Provider 和生效选项,并随结果记录供详情查看,不保存凭据副本。修改配置不改写已保存结果;草稿或知识库再次解析时才采用新配置,成功才替换。历史消息和已入队输入保持已接受内容,重新解析通过添加到草稿完成,不改写原消息或队列。失败不得损坏旧文本、图片或来源关联。 |
| FR-H12 | 设置中的来源切换保留本地与远程各自配置,高级选项默认折叠;测试前须保存设置。测试、聊天附件和知识库详情共用正文、图片、详情预览,支持页码互跳、打开原件、查看保存时配置、失败及部分结果。聊天卡显示解析进度、取消、重试及完整程度;界面支持窄容器、键盘和辅助技术。具体交互由 UI 设计维护。 |
### 13.1 范围与存储边界
本轮已实现配置、HTTP 适配器、数据库引用、共享预览和会话选图链路。
具体文件布局、schema 与已验证行为由[生产实现说明](./implementation.md)维护。
FR-H8 至 FR-H12 的资源与预览要求针对已解析文档及其产物,也适用于本地或原生解析结果,
不要求所有附件都生成解析文件。纯图片遵循 FR-I1 至 FR-I3;图片保存以解析器实际返回的
内容为准,不据此承诺本地解析新增插图提取能力。
聊天文档的原文件、解析文本和图片是应用持有的文件资产,数据库负责关联会话、消息、附件
和资源。目录与文件名规划由
[技术设计的结果与资源](./http-paddleocr-vl-technical-design.md#结果与资源)维护。历史数据若未保存
这些内容,不能显示为已有完整解析资源;本轮不要求恢复缺失历史内容或批量重解析。
不接入 MinerU、旧 Office 转换、
DOCX/XLSX 图片 OCR、图片向量检索、服务安装管理或 DOCX 导出。服务接受 PNG 的探测结果
也不改变聊天截图目前作为图片附件的行为。HTTP 上传路径不因 Ask/Execute 模式改变;
沿用第 3.3 节的来源选择与 Main 凭据边界,不增加逐文档授权。
不增加完整配置快照、结果版本历史或通用恢复系统;仅记录本次结果需要的来源、选项和资源关系。
### 13.2 配置与预览行为
界面的信息架构、控件、文案、状态、响应式和无障碍由 [UI 设计](./ui-design.md)唯一维护。
来源与保存规则见其第 2 节,共享正文/图片/详情预览见第 3 节,文档选图加入会话见第 4 节,
纯图片 OCR 与文档卡片见第 5 节,知识库交互见第 6 节。测试资产在结束预览后清理,不提供
加入聊天或知识库操作;正式文档中的图片使用 FR-I5 的显式选择路径。
### 13.3 用户验收
以下为产品验收条件;已执行范围与尚未执行项在进度中逐项注明:
| 场景 | 可观察结果 | 需求 |
| --- | --- | --- |
| 发送扫描文档后关闭应用,移动或删除外部原文件,再启动并打开历史附件 | 可打开应用保存的原文件,查看原解析正文、表格、图片和页码,无需重新 OCR | FR-H3、FR-H8 |
| 文档消息进入发送队列后重启,再恢复发送 | 附件与原解析内容仍可用,不要求重新选择外部文件;取消生成不删除已保存附件 | FR-H8、FR-H9 |
| 草稿移除附件、取消解析或批次导入失败 | 本次未提交资源被清理;先前附件、草稿和已发送内容仍可用 | FR-H9 |
| 删除一段含文档的会话,再查看其他会话或知识库中的关联文档 | 被删会话独占资源被清理,其他有效引用的原文件与图片仍能打开 | FR-H9、FR-H10 |
| 两页返回同名图片键,并使用 HTML img 和 table | 两页图片各自对应正确页码,表格可读,正文引用不串页、不出现未说明的断图 | FR-H3 |
| 切换本地与远程来源,修改页眉选项并测试 | 各来源配置保留;未保存时提示保存;保存后测试采用新值,三个结果视图可相互核对 | FR-H1、FR-H4、FR-H7、FR-H12 |
| 已保存结果后修改 Provider 或过滤项,再查看旧结果 | 旧正文与图片不变,详情仍显示原解析所用来源与选项;草稿或知识库再次解析成功后才替换,历史消息重解析进入新草稿 | FR-H11 |
| 对已有知识库文档重解析,发生服务错误、缺图或取消 | 旧正文、chunks、图片及页码仍可使用;重试成功后显示新结果并清理无引用旧资源 | FR-H6、FR-H10 |
| 分别导入 managed、reference 来源,随后删除来源 | 派生图片均在应用管理范围;删除后无引用派生资源清理,外部原文件不被派生资源清理误删 | FR-H10 |
| 从聊天文档选两张插图并重复点击添加,再移除父文档 | 草稿只增加两份独立图片附件;父文档在场时正文仅一次,移除后图片仍可发送 | FR-I5 |
| 从知识库选图,选择或新建会话后添加;随后重解析或删除源文档 | 仅明确选定会话的草稿变化,会话图片及已发送来源说明仍可用 | FR-I5、FR-H10 |
| 视觉模型配合不支持图片的 Runtime,或恢复队列时能力已变化 | 阻止该请求并保留附件,提供切换、提取文字或移除的恢复路径,不静默降级 | FR-I1、FR-I5 |
| 图片提取文字成功、失败、取消及再次改回原图 | 成功后明确仅发文字且原图可开;其余状态不丢原图,改回后重新校验图片能力 | FR-I2、FR-I3 |
完整验收覆盖见 [UI 验收矩阵](./ui-design.md#8-完整验收矩阵)。清理还需核对应用资源目录和
数据库引用;仅凭界面中看不到附件不能证明文件已删除。