fix: preserve exports on close and support themed PDF without export quotas
This commit is contained in:
@@ -1629,8 +1629,12 @@ CUDA 组件:`GET /api/local-models/runtime-components/cuda` 返回 status、st
|
||||
|
||||
`POST /api/plots/function`:请求`{source, theme_id}`,source最多20000字符;响应`{result: {content,mime_type,width,height,warnings} | null, diagnostics: [{severity,code,message,line}], node_count}`。语法错误为200诊断、请求字段违规422。共享plot白名单解释器,不执行eval;每块16表达式、8000累计节点、并发2。主题映射当前六个Theme ID并提供CSS图表Token;未知主题回退light。
|
||||
|
||||
`ExportRequest`新增可选title(最多200字符)、assets(最多64);`source.file_path`为未保存快照中相对图片的基准位置,不能用于任意文件读。每个asset为`{kind: mermaid|math_block|math_inline|image, source_hash: 64位sha256十六进制, png_base64}`;摘要为strip后UTF-8源码(image为src)的SHA256。只接受有效PNG并重编码,每图4百万像素、总16百万像素/8MiB;重复kind/hash或超限返回422 EXPORT_ASSET_INVALID。摘要失配不替换当前节点,不接受客户端SVG/XML/URL执行。
|
||||
`ExportRequest`新增可选title(最多200字符)、assets(HTML/DOCX 最多64,PDF 不设数量上限);`source.file_path`为未保存快照中相对图片的基准位置,不能用于任意文件读。每个asset为`{kind: mermaid|math_block|math_inline|image, source_hash: 64位sha256十六进制, png_base64}`;摘要为strip后UTF-8源码(image为src)的SHA256。只接受有效PNG并重编码;HTML/DOCX 每图4百万像素、总16百万像素/8MiB,PDF 不使用这些预算。重复kind/hash或无效PNG返回422 EXPORT_ASSET_INVALID。摘要失配不替换当前节点,不接受客户端SVG/XML/URL执行。
|
||||
|
||||
未带资源的公式由受限MathText转换(512字符/20层/64资源),仅解析Vault范围内PNG/JPEG/WebP(单文件2MB),拒绝远端与越界路径。资源失败保留源码/替代文字和warning。PDF/DOCX采用浅色打印样式;HTML保留有限主题调色板,不复刻任意主题CSS。DOCX图片为静态内容,不提供可编辑公式对象。
|
||||
未带资源的公式由 MathText 转换,仅解析 Vault 范围内 PNG/JPEG/WebP,拒绝远端与越界路径。HTML/DOCX 保留 512 字符/20 层/64 资源、单文件 2MB 的预算;PDF 不使用这些预算,也不限制导出源长度、产物字节数、函数图数量、表达式数量及累计复杂度。表达式白名单、有效图片校验、数值采样的收敛控制和队列并发调度仍保留。资源无法表示时保留源码/替代文字和 warning。
|
||||
|
||||
PDF 使用当前主题配色。`ExportOptions.palette` 可选,包含 page/surface/text/muted/code/border/accent 七个必填 `#RRGGBB` 值,由客户端在点击导出时冻结,用于自定义主题。未传 palette 时按 theme_id 解析六套内置配色,未知 ID 回退 light 并警告。PDF 页背景、正文、代码、表格、引用、链接、公式、Mermaid 和函数图均主题化;不会执行主题 CSS。DOCX 仍采用浅色打印样式;HTML 保留有限主题调色板。DOCX 图片为静态内容,不提供可编辑公式对象。
|
||||
|
||||
关闭导出窗口仅停止 UI 轮询,已发起的导出继续。主动取消在准备阶段停止提交;创建请求期间取消会等待任务 ID,调用后台取消接口并读取实际状态。
|
||||
|
||||
RAG `retrieval.fusion`接受rrf(默认)或weighted(归一化FTS/vector各50%),参数写入config_snapshot。真实本地单查询Embedding可命中有界进程缓存,provenance.query_embedding_cache为hit/miss;比较延迟须分别报告冷暖样本。HashEmbedding仍仅为确定性单元测试,不是当前生产检索模型。
|
||||
|
||||
@@ -156,3 +156,14 @@ PDF、DOCX 保持浅色打印样式;选择其他主题时返回明确 warning
|
||||
警告框识别与工作区一致:标记与标题之间可不留空格,类型允许数字、下划线和连字符;自定义类型回退 note 配色并保留自定义标题,省略标题时使用类型名称首字母大写。
|
||||
|
||||
警告框、普通引用、列表及交叉嵌套中的 Markdown 表格均启用容器内部解析,HTML 输出 table、PDF 输出 Table、DOCX 输出原生表格。测试逐一检查单元格内容和产物结构。每个 HTML 警告框独立初始化颜色变量,避免 NOTE 等类型继承外层 WARNING 的颜色;已在五套内置导出主题中检查嵌套配色及表格显示。
|
||||
|
||||
|
||||
### PDF 主题与资源策略更新(2026-09-07)
|
||||
|
||||
当前 PDF 行为以此节为准,覆盖上文早期 PR 的浅色打印和资源预算说明。
|
||||
|
||||
PDF 使用导出按钮点击时的主题配色快照,支持六种内置/社区主题与自定义主题的七项颜色。页背景、正文、引用、代码块、表格、链接、语义提示块、Mermaid、公式与函数图均参与主题适配;公式使用透明底再合成主题表面色,深色曲线使用较亮的默认色。标题随下一块分页,代码保留背景与边框。PDF 不执行 CSS 装饰或主题脚本。
|
||||
|
||||
PDF 取消导出源/产物大小限制、Mermaid 数量和像素预算、请求资源数量和字节预算、Vault 图片大小/累计预算、MathText 长度/深度预算、函数图数量/表达式数量及 AST 预算。HTML/DOCX、在线预览仍使用原有限制;有效图片、Vault 路径、表达式语法校验和数值求解退出条件仍生效。无限制指移除应用导出配额,实际文件规模仍受浏览器、解析器和可用内存约束。
|
||||
|
||||
关闭窗口仅结束 UI 生命周期,导出流程继续;主动取消仍取消提交中的后台任务。回归测试见 `ExportDialog.spec.ts`、`exportService.spec.ts`、`test_pdf_theme_resources.py`。
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# PDF 主题与资源限制修复验收
|
||||
|
||||
工作目录:`G:/OSProject/NotesAgent`;分支:`feat/phase2-completion`。
|
||||
|
||||
## 完成内容
|
||||
|
||||
1. 修复关闭窗口误取消提交中的导出任务,保留主动取消。
|
||||
2. PDF 移除前后端导出数量、大小、图片像素及累计资源配额,详见接口契约。
|
||||
3. PDF 读取点击导出时的主题颜色快照,覆盖六套主题和自定义调色板,移除强制浅色打印提示。
|
||||
4. 公式透明底、Mermaid 主题变量、矢量函数图、代码背景与边框、表格、提示块和页面背景都使用对应主题颜色。
|
||||
|
||||
## 验证
|
||||
|
||||
- 全量后端:879 项通过,1 条既有 Starlette/httpx 弃用警告。
|
||||
- 全量前端:82 文件、448 项通过。
|
||||
- 分页/代码背景最终调整后:相关后端 108 项通过。
|
||||
- 前端生产构建通过,仍有既有大分包提示。
|
||||
- 超旧限制回归:17 个 Mermaid、65 个文档资源、单图超过 400 万像素、超过旧源/产物阈值、17 条函数表达式与20个函数图。
|
||||
- 真实前端 Mermaid 栅格化 + 后端导出流水线生成 light/dark/sepia/paper-moments/ocean-blue/midnight-purple 六份 PDF;Poppler 渲染并检查全部12页,未出现白底公式、不可读深色文字、图表裁切或孤立章节标题。
|
||||
- 验证数据与截图:本机 `.local-plans/pdf-theme/`;全部接口拦截为测试数据,未访问真实模型或用户笔记。
|
||||
|
||||
本次未改动用户已有的三份笔记修改。主题适配使用颜色与语义样式,不将任意主题 CSS/脚本直接用于 PDF。
|
||||
@@ -0,0 +1,104 @@
|
||||
[
|
||||
{
|
||||
"theme": "light",
|
||||
"pages": 2,
|
||||
"bytes": 67245,
|
||||
"sha256": "5b6efed909df971f455253958ceadce47a7bd198b52ca1a1c755d9d25c51dc05",
|
||||
"palette": {
|
||||
"page": "#ffffff",
|
||||
"surface": "#ffffff",
|
||||
"text": "#1f2328",
|
||||
"muted": "#656d76",
|
||||
"code": "#f7f8fa",
|
||||
"border": "#e4e7eb",
|
||||
"accent": "#5b67f1"
|
||||
},
|
||||
"warnings": [],
|
||||
"visual_review": "passed"
|
||||
},
|
||||
{
|
||||
"theme": "dark",
|
||||
"pages": 2,
|
||||
"bytes": 66788,
|
||||
"sha256": "b09da4dc97246b7444f17d2b5756dea6dda004981cbcbd360bc2de3d26bd00cf",
|
||||
"palette": {
|
||||
"page": "#0d1117",
|
||||
"surface": "#161b22",
|
||||
"text": "#e6edf3",
|
||||
"muted": "#8b949e",
|
||||
"code": "#161b22",
|
||||
"border": "#30363d",
|
||||
"accent": "#7d8bff"
|
||||
},
|
||||
"warnings": [],
|
||||
"visual_review": "passed"
|
||||
},
|
||||
{
|
||||
"theme": "sepia",
|
||||
"pages": 2,
|
||||
"bytes": 66836,
|
||||
"sha256": "abc329f9691ba46d8ddd25e4b3621b63fc4cc8baba8823800c47d68feb910e0c",
|
||||
"palette": {
|
||||
"page": "#fbf3df",
|
||||
"surface": "#fff8e8",
|
||||
"text": "#40372b",
|
||||
"muted": "#746653",
|
||||
"code": "#f4e8ca",
|
||||
"border": "#ddcfad",
|
||||
"accent": "#8a5b32"
|
||||
},
|
||||
"warnings": [],
|
||||
"visual_review": "passed"
|
||||
},
|
||||
{
|
||||
"theme": "paper-moments",
|
||||
"pages": 2,
|
||||
"bytes": 66808,
|
||||
"sha256": "e1929fbec0486b59abcc808fab557f4103ec102ad70e6fb9f0b26f84414c0fe4",
|
||||
"palette": {
|
||||
"page": "#faf7ee",
|
||||
"surface": "#fffdf5",
|
||||
"text": "#493f35",
|
||||
"muted": "#6e6053",
|
||||
"code": "#f3eee3",
|
||||
"border": "#b5a693",
|
||||
"accent": "#875343"
|
||||
},
|
||||
"warnings": [],
|
||||
"visual_review": "passed"
|
||||
},
|
||||
{
|
||||
"theme": "ocean-blue",
|
||||
"pages": 2,
|
||||
"bytes": 67260,
|
||||
"sha256": "1e567daeb2ba8bcb5c13af465f174865a3662ade444c58cd09af66ae99233346",
|
||||
"palette": {
|
||||
"page": "#ffffff",
|
||||
"surface": "#ffffff",
|
||||
"text": "#1e293b",
|
||||
"muted": "#64748b",
|
||||
"code": "#f8fafc",
|
||||
"border": "#e2e8f0",
|
||||
"accent": "#0077b6"
|
||||
},
|
||||
"warnings": [],
|
||||
"visual_review": "passed"
|
||||
},
|
||||
{
|
||||
"theme": "midnight-purple",
|
||||
"pages": 2,
|
||||
"bytes": 66788,
|
||||
"sha256": "fd5efcedec0d7f4892fb987e0e4ba9052aa88b7361159cbb2ca3b7e00dde495c",
|
||||
"palette": {
|
||||
"page": "#1a1b26",
|
||||
"surface": "#24283b",
|
||||
"text": "#c0caf5",
|
||||
"muted": "#9aa5ce",
|
||||
"code": "#24283b",
|
||||
"border": "#3b3f5c",
|
||||
"accent": "#9d4edd"
|
||||
},
|
||||
"warnings": [],
|
||||
"visual_review": "passed"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user