ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

思源笔记 v3.5.3 深度解析:拖放性能优化、导出增强与新增批量块内容内核 API

2026/9/10 13:10:03 拓冰建站 浏览量
思源笔记 v3.5.3 深度解析:拖放性能优化、导出增强与新增批量块内容内核 API 思源笔记 v3.5.3 深度解析拖放性能优化、导出增强与新增批量块内容内核 API【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan本篇技术指南围绕思源笔记SiYuanv3.5.3 版本的官方变更记录v3.5.3_zh_CN.md展开逐一拆解该版本在性能、导出、同步、桌面端体验四个方向上的改进项、缺陷修复与开发者接口变更。读者可以通过本文掌握每个变更背后的内核实现位置与调用链从而理解思源在改进细节这类小版本迭代中的实际工程取舍并可直接对照源码验证。版本概述与变更范围v3.5.3 的官方定位是此版本改进了一些细节但从变更记录看它实际覆盖了编辑体验、数据同步、资源管理、导出链路、桌面端打包与开发者 API 六个领域共约 27 项功能改进、4 项缺陷修复和 1 项新增内核 API。该版本同时发布简体中文、繁体中文与英文三份变更记录本仓库中对应文件为 v3.5.3_zh_CN.md、v3.5.3_zh_CHT.md 与 v3.5.3.md。下文按主题分组解读全部变更项并在每节给出对应的仓库源码证据。编辑体验与界面交互改进文档树拖放性能与动态加载本版本改进文档树的拖放drag drop性能并支持剪切块后动态加载文档issue 16767。后者意味着当块被剪切到其他文档时目标文档不再要求整体预加载而是按需动态装载文档树节点这与内核侧loadTreeByBlockIDInBox的按需加载模型一致——在批量导出、剪切粘贴等场景中文档树均以块 ID 为单位按需读取见下文 API 一节的源码分析。撤销恢复光标位置与 ChatGPT 粘贴体验撤销应在按回车后恢复光标位置issue 16595在编辑器中触发回车后执行撤销光标会回到按下回车前的位置避免撤销后光标漂移到文档末尾或错误行。改进从 ChatGPT 应用复制文本的体验issue 14819针对 AI 对话应用复制出的富文本/带标记内容改进粘贴时的解析与清洗减少多余格式残留。折叠标题与列表编辑细节改进列表编辑中折叠标题的处理issue 16769折叠标题heading 折叠状态在列表项编辑过程中不再被错误展开或丢失。改进在提示、引用和列表项中折叠标题指示器的显示issue 16805折叠标题的指示器折叠箭头在提示块hint block、引用和列表项等嵌套场景下的显示位置与层级得到修正。改善可折叠列表块中 Mermaid 块的渲染issue 16802Mermaid 图表在折叠列表块内的渲染时序被调整避免折叠状态下图表空白或加载失败。改进提示块图标的交互issue 16758与提示块、数据库中修改表情不再更新常用表情列表issue 16746前者优化了提示块图标的点击/悬停响应后者属于行为修正——此前在提示块或数据库属性中改动表情会污染全局常用表情列表v3.5.3 起此类改动不再写入常用表情记录。搜索结果定位与表格复制改进搜索结果打开编辑器时的定位issue 16739从搜索结果跳转打开编辑器时滚动定位更精确目标块能稳定进入视口。改进表格复制PR 16783从渲染表格复制到外部应用时单元格分隔与换行规则更贴近表格语义。只读模式与数据库交互修正修复只读模式下点击文档导致错误issue 16762只读角色ReadOnlyRole下点击文档不再触发异常。内核侧存在完整的只读上下文判定逻辑model.IsReadOnlyRoleContext与发布访问过滤filterBlockKramdownsByPublishAccess此修复使前端在只读上下文中跳过写路径操作。修复分组视图下数据库单元格拖放填充行为异常issue 16760数据库分组视图layout_gallery、layout_kanban、layout_table等分组布局中单元格拖放填充的取值与落点校验得到修正相关布局实现位于 kernel/av/layout_gallery.go、kernel/av/layout_kanban.go 与 kernel/av/layout_table.go。改进数据库资源字段菜单中图片点击的行为PR 16671资源字段菜单内点击图片时优先打开图片预览而非误触发其他操作。资源、导入与导出链路增强支持将代码块导出为文件PR 16774这是本版本较有工程价值的一项能力代码块现在可以直接导出为.txt文件而不再需要复制代码再手动新建文件。内核侧实现路径清晰API 入口为 kernel/api/export.go 中的exportCodeBlock接收必填参数id块 ID内部调用model.ExportCodeBlock(id)。核心逻辑位于 kernel/model/export.gonode : treenode.GetNodeInTree(tree, blockID) if ast.NodeCodeBlock ! node.Type { return errors.New(not a code block) } code : node.ChildByType(ast.NodeCodeBlockCode) if nil code { return errors.New(code block has no code node) } name : tree.Root.IALAttr(title) - util.CurrentTimeSecondsStr() .txt exportFolder : filepath.Join(util.TempDir, export) // 加密笔记本的导出归入 boxID 子目录 if IsEncryptedBox(tree.Box) { exportFolder filepath.Join(exportFolder, tree.Box) }从源码可以确认三个行为细节一是仅块类型为NodeCodeBlock时才允许导出否则返回not a code block错误二是导出文件名由文档标题加时间戳组成三是导出文件先写入TempDir/export临时目录加密笔记本IsEncryptedBox还会按boxID分子目录并通过registerManagedEncryptedExport注册托管 token 后才能被下载/export/...路径这保证了加密笔记本的明文代码不会绕过锁定状态被读取。优化导出为 Word .docx 时对资源的处理issue 15253导出 Word 文档时对资源图片、附件的处理得到优化。内核导出链路中ExportMarkdownHTMLkernel/model/export.go在docxtrue时会调用getAssetsLinkDests(tree.Root, docx)收集资源链接目标再经由 pandoc 转换为 docxpandoc : exec.Command(Conf.Export.PandocBin, args...)。v3.5.3 的优化主要落在资源链接目标assetLinkDest的判定与复制环节减少 docx 导出后资源缺失或路径错乱的情况。改进导出预览模式issue 16732导出预览export preview模式下的渲染细节得到修正预览内容与实际导出文件的一致性更高。改进 PDF 矩形注释截图的旋转处理PR 16714PDF 矩形注释highlight/rect annotation生成截图时对旋转页面Rotate 属性非 0的坐标变换做了修正避免旋转页面上的注释截图方向错误。PDF 相关处理逻辑位于 kernel/model/pdf.go。改进 PlantUML 的 PDF 导出issue 16776PlantUML 图在 PDF 导出中的渲染兼容性得到修正避免图块在 PDF 中丢失或排版错乱。改进 HTML 块解析issue 16778HTML 块的解析规则做了收紧与修正提升粘贴/导入 HTML 内容时的结构化转换质量相关解析与 Lute 引擎联动kernel/model与kernel/util/lute.go中维护了解析参数。数据同步、代码片段与存储维护提升 S3 数据同步与 RustFS 的兼容性issue 16742S3 协议数据同步在与 RustFS 类对象存储如自建 Rust 实现的 S3 兼容存储对接时的兼容性得到提升主要涉及分片上传、ETag 校验等协议细节使更多自托管对象存储后端可以稳定使用思源的 S3 同步方案。该能力属于 kernel/conf/sync.go 与 kernel/model/sync.go 配置与执行链路的一部分。改进移动端数据同步后资源数据索引的更新issue 16747移动端在数据同步完成后资源数据索引asset content 索引的更新时序被修正避免同步后搜索/引用资源内容时索引滞后。数据同步后自动应用代码片段issue 16736此前用户修改代码片段JS/CSS snippet后需要手动重启或重载才能生效v3.5.3 起数据同步完成后会自动重新加载并应用代码片段。内核侧片段的管理入口在 kernel/model/snippet.goLoadSnippets()通过snippetsLock互斥锁保护从util.SnippetsPath/conf.json读取片段配置type支持css/js并统计启停数量同步完成后触发片段重新加载即是对该文件读取链路的再次调用使conf.json中enabled的 CSS/JS 片段无需手动刷新即可生效。支持清理临时文件issue 16745本版本新增清理临时文件能力可一键回收运行过程中在临时目录里累积的导出、导入、转换等中间产物。内核实现API 路由POST /api/system/clearTempFileskernel/api/router.go需要登录与管理员角色model.CheckAuth、model.CheckAdminRole、model.CheckReadonly。入口处理kernel/api/system.go 的clearTempFiles直接委托model.ClearTempFiles()。清理范围kernel/model/box.go 中的ClearTempFiles依次清理util.TempDir下的bazaar、export、import、convert、os、base64、install、thumbnails、repo等子目录并统计删除的文件数量与释放字节数通过util.PushMsg/util.PushUpdateMsg向前端推送进度与结果结果文案使用humanize.BytesCustomCeil格式化容量。这意味着导出文档、导入数据、集市下载、缩略图生成等活动遗留的中间文件都可以通过该功能安全回收。桌面端与发布相关改进Windows 端安装后自动清理 siyuan-updaterissue 16733Windows 桌面版安装完成后会自动删除\%LOCALAPPDATA%\siyuan-updater\文件夹清理升级器残留的旧版本文件避免升级器目录持续膨胀。改进桌面自动更新PR 16764桌面端自动更新流程得到改进包括更新包下载、校验与安装步骤的稳健性减少更新失败后的半更新状态。桌面端打包与签名脚本见 app/scripts/afterPack.js 与 app/scripts/signDevElectron.js。优化错误窗口信息布局PR 16735错误弹窗的信息布局被重新组织堆栈信息与错误上下文更易读便于排查。发布服务关闭时自动关闭浏览器页面PR 16804当思源发布服务publish被关闭时若此前通过浏览器打开了发布页面相关浏览器页面会自动关闭避免残留失效页面。发布访问控制的过滤逻辑与只读上下文判定可参见 kernel/model/publish_access.go。缺陷修复汇总v3.5.3 共修复 4 项缺陷缺陷影响场景说明搜索时文档标题显示不正确issue 16741搜索结果列表标题高亮/截断逻辑修正恢复正确标题文本分组视图下数据库单元格拖放填充行为异常issue 16760数据库分组视图分组后的单元格拖放填充取值与落点校验修正只读模式下点击文档导致错误issue 16762只读角色/发布上下文只读上下文下点击文档不再触发异常路径多工作区访问鉴权错误issue 16786多工作区切换不同工作区之间的访问令牌/鉴权状态隔离修正其中只读模式与多工作区鉴权两项与内核的会话与权限体系相关只读判定贯穿kernel/model的发布访问过滤鉴权中间件则统一注册在 kernel/api/router.go 的model.CheckAuth、model.CheckAdminRole等处理器上。开发者新增内核 API/api/block/getBlockKramdowns作为面向开发者的一项实质增量v3.5.3 新增了批量获取块内容的内核 APIPR 16751可一次请求返回多个块的 Kramdown 内容适用于插件、脚本或集成方批量读取文档块内容避免对单个块逐一调用既有接口。路由注册与权限路由注册于 kernel/api/router.goginServer.Handle(POST, /api/block/getBlockKramdowns, model.CheckAuth, model.CheckAdminRole, getBlockKramdowns)与单块接口/api/block/getBlockKramdown并列同样要求已登录且具备管理员角色。请求参数与实现细节实现位于 kernel/api/block.go 的getBlockKramdowns核心处理逻辑如下ids必填字符串数组目标块 ID 列表。源码会对每个 ID 做格式校验util.InvalidIDPattern跳过无效 ID。mode可选字符串导出模式默认md仅接受两个取值mdMarkdown 标记符模式使用标记符marker导出内部走treenode.ExportNodeStdMd并开启SetPreventEncodeLinkSpace(true)链接/图片 URL 中的空格不再被编码对应 issue 15611 的既有行为textmark文本标记模式使用 span 标签导出内部走render.NewFormatRenderer渲染。传入其他值返回code -1、msg Invalid mode。加密笔记本参数通过encryptedNotebookFromArg(arg)解析boxID当存在boxID时改走model.GetBlockKramdownsInBox保证加密笔记本的读取被正确路由到其 box 上下文。返回结构为{ code: 0, data: { blockID: kramdown 内容, ... } }在只读角色上下文model.IsReadOnlyRoleContext下还会通过filterBlockKramdownsByPublishAccess按发布访问控制过滤掉无权读取的块防止通过该 API 绕过发布权限。底层批量读取模型内核模型层实现位于 kernel/model/block.gofunc GetBlockKramdowns(ids []string, mode string) (ret map[string]string) { return GetBlockKramdownsInBox(ids, mode, ) } func GetBlockKramdownsInBox(ids []string, mode, boxID string) (ret map[string]string) { ret make(map[string]string, len(ids)) luteEngine : NewLute() for _, id : range ids { // 节点会被移走tree 不能共享需重新加载 tree, err : loadTreeByBlockIDInBox(id, boxID) if err ! nil { continue } ret[id] getBlockKramdown0(tree, id, mode, luteEngine) } return }源码注释明确说明了批量实现的关键约束由于块可能被移动剪切/粘贴每个 ID 都必须重新加载所在文档树loadTreeByBlockIDInBox不能共享同一个tree实例。getBlockKramdown0会先addBlockIALNodes补充块属性列表IAL节点再把目标块与其 IAL 包装进一个临时NodeDocument根节点后执行导出因此返回内容包含块的 IAL 属性信息适合需要读取块属性如自定义属性、样式标记的集成场景。调用示例curl -X POST http://127.0.0.1:6806/api/block/getBlockKramdowns \ -H Authorization: Token 你的API令牌 \ -H Content-Type: application/json \ -d { ids: [20240101120000-abcdefg, 20240101120001-hijklmn], mode: md }响应示例{ code: 0, msg: , data: { 20240101120000-abcdefg: 这是一段段落文本。\n{: id\20240101120000-abcdefg\}, 20240101120001-hijklmn: go\nfmt.Println(\hello\)\n\n{: id\20240101120001-hijklmn\} } }上述响应中的 ID 格式与 IAL 尾部标记仅为示意实际内容以目标文档为准。下载与升级v3.5.3 随版本发布提供各平台安装包。升级后建议重点关注以下可验证行为在设置中体验新增的清理临时文件入口对应/api/system/clearTempFiles对代码块执行导出为文件以及通过开发者工具或脚本调用/api/block/getBlockKramdowns验证批量读取。仓库内还保留了该版本其余语言与后续版本的变更记录见 app/changelogs 目录可作为版本演进的对照参考。【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考