news 2026/9/9 13:58:47

思源笔记 v2.9.7 版本深度解析:云端数据损坏修复、S3/WebDAV 登录策略收紧与 30 余项体验改进

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
思源笔记 v2.9.7 版本深度解析:云端数据损坏修复、S3/WebDAV 登录策略收紧与 30 余项体验改进

思源笔记 v2.9.7 版本深度解析:云端数据损坏修复、S3/WebDAV 登录策略收紧与 30 余项体验改进

【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间,让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan

v2.9.7 是思源笔记(SiYuan)同步与数据安全路线上的一个关键版本:本版修复了一个可能导致云端数据损坏的问题,官方建议所有用户尽快升级;同时自本版起,接入第三方云端存储 S3/WebDAV 进行数据同步与备份必须先登录思源账号。本文以仓库内官方更新日志 app/changelogs/v2.8.4-v2.12.8/v2.9.7/v2.9.7_zh_CN.md(对应英文版 v2.9.7.md)为主线,结合内核 Go 源码与桌面端实现,逐条拆解本版改动的技术背景、实现原理与升级注意事项,帮助开发者理解“为什么必须升级”以及“登录策略变化背后的校验链路”。

一、版本概览:一次建议“尽快升级”的维护性发布

该变更日志(下文简称“文档”)开头即给出两条高度浓缩的关键信息:

  1. 本版修复了一个导致云端数据损坏的问题,因此强烈建议尽快升级;
  2. 自本版起,使用第三方云端存储 S3/WebDAV 需要先登录账号,用户需提前知悉这一行为变化。

其余内容为分类变更清单,共覆盖五大类别:

类别条目数说明
改进功能17 项块引浮窗、搜索、移动端输入、文档树提示等 UI 与交互优化
修复缺陷1 项导出 Word 不渲染行级元素
开发重构1 项升级 Electron
开发者3 项属性视图日期列、全局鼠标变量、内核 readDir 符号链接支持

下面按“为什么重要 → 底层怎么实现 → 用户如何受益”的顺序展开。

二、核心修复:文件被外部占用时不再导致云端数据损坏

文档强调的第一个要点是:此前当本地文件被外部进程占用(例如被同步盘、杀毒软件或手动编辑器锁定时)触发数据同步,有可能导致云端数据损坏;v2.9.7 修复了该问题。

2.1 同步链路上的“占用”风险点

思源的数据同步内核基于 Git 式的仓库(repository)机制,关键代码位于 kernel/model/repository.go 与 kernel/model/sync.go。一次同步会经历:

  1. 本地索引比对:找出本地与云端的差异文件;
  2. 打包上传/下载:通过repository完成数据包传输;
  3. 写入索引:将本次同步结果写入本地/云端索引与同步目录。

其中第 2、3 步涉及对磁盘文件的读写。若某个文档或资源文件恰好被外部进程锁定(例如 Windows 下被其他软件独占打开),读写阶段可能抛出异常或被截断,若异常处理不完善,就可能把不完整或错误的数据状态回写到云端索引,最终表现为云端数据损坏。

从源码结构看,kernel/model/sync.go 中的同步入口会对不同模式(自动/手动/完全手动)、是否启动/退出同步等场景做精细的checkSync判断,本版正是在这类边界条件下补强了异常防护,避免“文件被占用 → 同步继续 → 云端数据被污染”的连锁反应。文档中的原话“文件被外部占用时数据同步不再导致云端数据损坏”即对应这一修复,这也是官方将其列为“建议尽快升级”的首要原因。

2.2 给使用者的操作建议

  • 升级前:如果怀疑本地存在被外部程序长期占用的数据文件,可先关闭可能占用工作空间的第三方同步盘或文件监听工具;
  • 升级后:首次启动会按新逻辑重建/校验同步状态,建议在网络稳定时手动执行一次完整同步;
  • 多设备场景:让所有客户端都升级到 v2.9.7 及以上,避免旧版本客户端仍携带该缺陷参与同步。

三、策略变更:S3/WebDAV 数据同步与备份需要登录

文档第二条关键信息:“从此版本开始,接入第三方云端存储 S3/WebDAV 需要登录后才能使用”。这一改动同时作用于数据同步数据备份两条功能链路。

3.1 为什么需要登录

思源将第三方对象存储接入视为需要账号体系支撑的高级能力。登录后内核才能校验账号的订阅/一次性付费状态,从而决定是否放行 S3/WebDAV 数据通路。在仓库当前源码中,这一校验链路的证据非常清晰:

  • 存储提供者枚举定义在 kernel/conf/sync.go:
const ( ProviderSiYuan = 0 // ProviderSiYuan 为思源官方提供的云端存储服务 ProviderS3 = 2 // ProviderS3 为 S3 协议对象存储提供的云端存储服务 ProviderWebDAV = 3 // ProviderWebDAV 为 WebDAV 协议提供的云端存储服务 ProviderLocal = 4 // ProviderLocal 为本地文件系统提供的存储服务 )
  • 同步放行判断位于 kernel/model/sync.go 的checkSync
switch Conf.Sync.Provider { case conf.ProviderSiYuan: if !IsSubscriber() { ... return false } case conf.ProviderWebDAV, conf.ProviderS3, conf.ProviderLocal: if !IsPaidUser() { ... return false } }

即:官方云存储要求“订阅用户”,而 S3/WebDAV(以及本地文件系统)要求“已登录且为付费用户”。账号判定函数定义在 kernel/model/conf.go:

  • IsSubscriber():用户已登录且订阅状态正常(未订阅、封禁或过期均不通过);
  • IsPaidUser():是订阅用户,或完成过一次性的 PRO 功能付费;未登录(GetUser()为 nil)时直接返回 false

这正是“接入 S3/WebDAV 需要登录”的内核实现:登录是第一步,付费状态是第二步。

3.2 配置模型与 API 鉴权

S3 与 WebDAV 的配置结构同样定义在 kernel/conf/sync.go:

type S3 struct { Endpoint string `json:"endpoint"` // 服务端点 AccessKey string `json:"accessKey"` // Access Key SecretKey string `json:"secretKey"` // Secret Key Bucket string `json:"bucket"` // 存储空间 Region string `json:"region"` // 存储区域 PathStyle bool `json:"pathStyle"` // 是否使用路径风格 SkipTlsVerify bool `json:"skipTlsVerify"` // 是否跳过 TLS 验证 Timeout int `json:"timeout"` // 超时时间,单位:秒 ConcurrentReqs int `json:"concurrentReqs"` // 并发请求数 } type WebDAV struct { Endpoint string `json:"endpoint"` // 服务端点 Username string `json:"username"` // 用户名 Password string `json:"password"` // 密码 SkipTlsVerify bool `json:"skipTlsVerify"` // 是否跳过 TLS 验证 Timeout int `json:"timeout"` // 超时时间,单位:秒 ConcurrentReqs int `json:"concurrentReqs"` // 并发请求数 }

在写入配置时,内核会对端点、密钥、桶名等做规范化处理,例如SetSyncProviderS3会对 Endpoint 做NormalizeEndpoint、对超时与并发数做取值范围归一(见 kernel/model/sync.go);SetSyncProviderWebDAV还会显式拒绝坚果云 WebDAV(接口限制所致),返回本地化提示(对应 app/appearance/langs/en.json 的 key 194)。

在内核 API 层,所有同步与备份相关接口都挂载了统一的鉴权中间件。以 kernel/api/router.go 为例:

ginServer.Handle("POST", "/api/sync/setSyncProviderS3", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncProviderS3) ginServer.Handle("POST", "/api/sync/setSyncProviderWebDAV", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setSyncProviderWebDAV) ginServer.Handle("POST", "/api/sync/performSync", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, performSync) ginServer.Handle("POST", "/api/sync/performBootSync", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, performBootSync)

任何未登录/非管理员会话请求这些端点都会被CheckAuth拦截,从服务端入口层面保障了“S3/WebDAV 必须登录后才可用”的策略一致性。

3.3 对存量用户的影响与处置

  • 已配置 S3/WebDAV 的老用户升级后,若未登录,同步与备份会按新策略停止或提示登录;
  • 处置方式:在设置 → 账号中登录思源账号并确认付费状态(一次性 PRO 或订阅均可),再回到同步设置重新触发同步;
  • 若收到诸如“requires logging into the account…”之类的本地化提示(见 app/appearance/langs/en.json key 214),说明账号尚未登录或付费状态未生效,可参考提示刷新或重新登录。

四、改进功能逐项解读(17 项)

文档“改进功能”部分罗列了 17 项,覆盖编辑器、搜索、移动端、文档树与视觉细节,可归纳为以下几组。

4.1 块引与引用体验

  • 改进块引浮窗位置和大小:优化块引用悬停浮窗的定位算法与尺寸自适应,避免浮窗遮挡正文或在大屏/小屏下显示异常;
  • 改进块引计数显示位置:调整块引用计数(引用次数角标)的渲染位置,与行内内容对齐更自然。

4.2 搜索与替换

  • Alt+↓/↑选择搜索历史关键字:在搜索输入框聚焦时,可通过Alt+↓/↑在历史关键字间循环切换,减少重复输入;
  • 改进搜索替换:对查找/替换流程的命中定位与高亮联动做了细化;
  • 搜索界面添加刷新按钮:在搜索面板增加“刷新”入口,便于重新执行当前关键字搜索;
  • Ctrl+P搜索不再沿用上一次指定的路径:此前Ctrl+P(全局搜索)会沿用上次手动指定的搜索路径,容易让用户误以为搜索范围不对;本版改为每次按当前上下文/默认范围发起搜索。

4.3 移动端与输入

  • 改进移动端字体设置交互:优化移动端设置界面中字体选择/预览的交互路径;
  • 改进 Android 端输入法相关问题:针对 Android 软键盘弹起、候选词与编辑器滚动冲突等问题做适配。

4.4 编辑器视觉与文档操作细节

  • 修改图标改为随机图标:将文档/笔记本图标菜单中的操作语义从“修改”改为“随机”,更贴合“从 emoji 中随机挑一个”的实际行为;
  • 优化文档树提示文案文字间隙大小:修正文档树 tooltip 中文字间距过大导致的排版问题;
  • 代码块操作图标不再被遮挡:修复代码块右上角操作按钮(复制、运行等)在部分主题/宽度下被裁切的问题;
  • 嵌入块显示提示文案:为嵌入块补充悬停提示,说明其引用来源,便于理解嵌入内容来自何处;
  • 优化标签背景和文字颜色:提升标签在深浅主题下的对比度与可读性;
  • 删除块后刷新面包屑:删除块后同步更新顶部面包屑导航,避免残留已删除路径;
  • 改进菜单滚动条:优化弹出菜单在内容超高时的滚动条样式与交互。

五、缺陷修复:导出 Word 不渲染行级元素

文档“修复缺陷”部分仅一条:修复导出 Word 时不渲染行级元素的问题(Issue #8774)。

行级元素包括加粗、斜体、行内代码、超链接、标记等 Markdown 行内语法。此前从思源导出 Word(docx)时,这些行内样式可能丢失,只保留块级段落结构,导致导出的文档“有段落、无强调”。本版针对导出链路中行级节点的渲染逻辑做了修复,使.docx输出完整保留行内样式。若读者日常使用“导出 Word”功能分发文档,本项修复直接关系到导出质量。

六、开发重构:升级 Electron

文档将“升级 Electron”列为开发重构项(Issue #8797)。桌面端由 app/package.json 声明 Electron 依赖并以 Electron 承载渲染层与主进程,升级主要带来内核安全补丁与系统兼容性改善,同时为后续桌面端新特性奠定基础。值得注意的是,文档把“导出 Word 渲染缺陷”单独列为 bugfix、把“升级 Electron”单独列为 refactor,二者在本版同时合入,升级 Electron 时通常也要求对 app/electron 下的主进程代码做相应回归验证。

七、面向开发者的三项变更

文档“开发者”部分包含三项对二次开发与插件生态有直接价值的改动。

7.1 属性视图添加日期类型列(Issue #8692)

属性视图(数据库)新增date 日期类型。在仓库当前源码中,属性视图的键类型枚举定义于 kernel/av/av.go,KeyTypeDate = "date",并配有日期相关的值结构与时间展示能力。这意味着开发者可以在属性视图中直接为条目建立“日期”维度字段,用于按时间管理文档、任务或条目。

7.2 添加全局鼠标位置变量(PR #8793)

为前端/插件运行环境新增一个全局鼠标位置变量,使开发者无需自行监听mousemove即可在需要的地方读取当前光标坐标。这类能力通常用于浮窗跟随光标、右键菜单定位、拖拽辅助等需要感知指针位置的交互场景。

7.3 内核 API/api/file/readDir支持返回符号链接信息(PR #8805)

文件管理类内核接口/api/file/readDir现在会为每个目录项附带是否为符号链接的标记。在仓库当前实现中,kernel/api/router.go 将该端点注册为:

ginServer.Handle("POST", "/api/file/readDir", model.CheckAuth, model.CheckAdminRole, readDir)

而 kernel/api/file.go 中读取目录项时会调用util.IsSymlink(entry),将结果以isSymlink字段随每个文件项返回:

files = append(files, map[string]any{ "name": entry.Name(), "isDir": info.IsDir(), "isSymlink": util.IsSymlink(entry), "updated": info.ModTime().Unix(), })

该能力对工作空间外部目录/云盘挂载目录类功能尤其重要:插件或外部集成在枚举目录时,可以识别出符号链接,避免误将链接当作普通文件处理,或据此决定是否跟随链接递归遍历。

八、升级与验证建议

综合以上分析,给出针对本版的落地建议:

  1. 尽快升级:鉴于“云端数据损坏”修复的优先级,官方建议尽快升级到 v2.9.7 及以上;升级后先在单台设备上验证同步状态再逐步覆盖多端;
  2. 登录检查:若使用 S3/WebDAV 同步/备份,请确认账号已登录且为订阅或 PRO 付费状态,否则新版会按策略拒绝数据通路;
  3. 导出验证:常用 Word 导出的用户,升级后可导出一份包含行内样式(加粗、行内代码、超链接)的文档核验修复效果;
  4. 开发者自测:若你开发属性视图插件或使用/api/file/readDir,可分别验证 date 列行为与目录项返回结构中的isSymlink字段。

本版所有变更明细均可在仓库 app/changelogs/v2.8.4-v2.12.8/v2.9.7 目录下查阅到中/英/繁三语版本;与同步策略、配置模型、账号判定及文件枚举相关的实现可进一步阅读 kernel/conf/sync.go、kernel/model/sync.go、kernel/model/conf.go 与 kernel/api/file.go 对应源码。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 13:57:37

用Python实现带好感度系统的拟人化聊天机器人

聊天机器人入门其实不难,网上随便一搜就是一大把“用 Python 写一个自动回复”的教程。但多数人写完之后会陷入一个很尴尬的处境:机器人确实是能回复了,但它不像“人”,更像一个复读机。你问一句它答一句,离开关键词就…

作者头像 李华
网站建设 2026/9/9 13:54:02

AI行业非技术岗完全指南:从产品运营到售前,零代码也能入局

1. 先说清楚:AI圈子的非技术岗,到底解决什么问题过去两年,我见过太多人对着AI行业的招聘JD犯迷糊——技术岗写着Transformer、PyTorch、RAG、微调,非技术岗好像门槛不高,但点进去一看,岗位描述里也全是“了…

作者头像 李华
网站建设 2026/9/9 13:53:49

国产TTS芯片实测:离线语音合成选型避坑指南

国产TTS芯片这几年的热度一直不低,尤其是智能家居、陪护机器人、车载语音交互这些产品扎堆出现之后,大家发现:与其在MCU上死磕算法资源,不如直接塞一颗带语音合成能力的芯片进去,省事、稳定、离线可用。我这两年因为做…

作者头像 李华
网站建设 2026/9/9 13:52:37

Jsoncpp动态库与静态库:编译、链接与部署全攻略

简介:面向Windows平台C开发者的Jsoncpp预编译库资源,专为Visual Studio使用者设计,开发者下载后可直接将库文件链接进项目,无需从源码编译,开箱即可用于JSON解析。压缩包共6个文件,涵盖2个头文件、2个静态库…

作者头像 李华
网站建设 2026/9/9 13:50:05

Swiper loop模式克隆slide导致Vue动态类名失效的根因与破解方案

前段时间在做一个多指标数据大屏,左侧要放一组横向滚动的任务卡片轮播,卡片根据优先级分三种状态:高优先级红色描边、中优先级黄色描边、低优先级绿色描边。技术栈是 Vue 3 Swiper,很自然地用了swiper-slide组件和:class"pr…

作者头像 李华