/** * @description 使用 fetch 直接请求 API,查找内容为 YYYY-MM-DD 格式且类型为 'd' 的块,并为其添加 custom-YYYYMMDD 属性。消息显示块内容。 */ async function addDateAttributesToDailyNoteBlocksDirect() { // --- 配置 --- const SIYUAN_API_URL = `${window.location.protocol}//${window.location.hostname}:${window.location.port}`; const API_TOKEN = typeof window.siyuan?.config?.apiToken !== 'undefined' ? window.siyuan.config.apiToken : "YOUR_API_TOKEN"; const headers = { 'Authorization': `Token ${API_TOKEN}`, 'Content-Type': 'application/json', }; // --- 封装的 API 请求函数 --- async function fetchAPI(endpoint, data) { try { const response = await fetch(`${SIYUAN_API_URL}${endpoint}`, { method: 'POST', headers: headers, body: JSON.stringify(data), }); const result = await response.json(); if (!response.ok) { throw new Error(result.msg || `HTTP 错误! 状态码: ${response.status}`); } if (result.code !== 0) { throw new Error(result.msg || `API 错误码: ${result.code}`); } return result.data; } catch (error) { console.error(`调用 API ${endpoint} 失败:`, error); throw error; } } // --- 封装的通知函数 --- async function pushNotification(message, isError = false, timeout = 5000) { const endpoint = isError ? '/api/notification/pushErrMsg' : '/api/notification/pushMsg'; try { await fetchAPI(endpoint, { msg: message, timeout: timeout }); } catch (notificationError) { console.warn(`发送通知失败: ${notificationError.message}`); if (isError) { alert(`错误: ${message}`); } else { alert(message); } } } // --- 主要逻辑开始 --- console.log("开始查找并处理日记块属性..."); await pushNotification("开始查找并处理日记块属性...", false, 3000); // 1. 查找块 const query = "SELECT id, content FROM blocks WHERE type = 'd' AND content LIKE '____-__-__'"; let blocks = []; try { blocks = await fetchAPI('/api/query/sql', { stmt: query }); } catch (error) { pushNotification(`查找日期块时出错: ${error.message}`, true); return; } if (!blocks || blocks.length === 0) { console.log("未找到符合条件的日期块。"); pushNotification("未找到符合条件的日期块。", false); return; } console.log(`找到 ${blocks.length} 个候选块,开始精确匹配和处理...`); // 2. 准备统计和正则 let updatedCount = 0; const errors = []; const dateRegex = /^\d{4}-\d{2}-\d{2}$/; // 3. 遍历处理 for (const block of blocks) { const { id, content } = block; // 同时获取 id 和 content // 精确匹配格式 if (!dateRegex.test(content)) { console.log(`块内容 "${content}" (ID: ${id}) 非标准 YYYY-MM-DD,跳过。`); // 保留ID供调试 continue; } try { const dateValue = content.replace(/-/g, ''); const attrName = `custom-dailynote-${dateValue}`; const attrs = { [attrName]: dateValue }; await fetchAPI('/api/attr/setBlockAttrs', { id: id, attrs: attrs }); // 设置属性仍需 ID updatedCount++; // 修改日志:显示 content console.log(`成功为块 "${content}" 添加属性 ${attrName}=${dateValue}`); // 可选延时 // await new Promise(resolve => setTimeout(resolve, 30)); } catch (error) { // 修改日志和错误记录:显示 content console.error(`为块 "${content}" 添加属性时出错:`, error); errors.push({ id: id, content: content, error: error.message || error }); // 错误记录中保留 id 和 content // 暂时不在这里为每个错误发送通知,汇总后发送 } } // 4. 最终报告 const successMessage = `处理完成。共检查 ${blocks.length} 个候选块,成功更新 ${updatedCount} 个块。`; console.log(successMessage); pushNotification(successMessage, false); if (errors.length > 0) { // 修改错误报告:指出是哪些日期的块出错了 const errorContents = errors.map(e => e.content).join(', '); const errorMessage = `有 ${errors.length} 个块在更新属性时出错 (例如: ${errorContents.substring(0, 50)}${errorContents.length > 50 ? '...' : ''})。详情请见控制台。`; console.error("出错的块详情:", errors); pushNotification(errorMessage, true, 8000); } } // --- 创建界面按钮 --- (这部分代码不变) function createProcessButton() { const buttonId = 'add-daily-note-date-attrs-button'; if (document.getElementById(buttonId)) { console.log("处理按钮已存在。"); return; } const button = document.createElement('button'); button.id = buttonId; button.textContent = '为日记块加日期属性'; button.style.position = 'fixed'; button.style.top = '70px'; button.style.right = '20px'; button.style.zIndex = '1001'; button.style.padding = '8px 12px'; button.style.border = 'none'; button.style.backgroundColor = '#2d7ff9'; button.style.color = 'white'; button.style.borderRadius = '5px'; button.style.cursor = 'pointer'; button.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)'; button.title = '点击处理所有内容为 YYYY-MM-DD 的文档块'; button.onclick = async () => { if (!confirm("确定要为所有符合条件的日记块添加日期属性吗?这个操作会修改块数据。")) { return; } button.disabled = true; button.textContent = '处理中...'; button.style.backgroundColor = '#aaa'; try { await addDateAttributesToDailyNoteBlocksDirect(); } catch (e) { console.error("执行过程中发生意外错误:", e); alert(`发生意外错误: ${e.message}`); try { await fetch(`${window.location.protocol}//${window.location.hostname}:${window.location.port}/api/notification/pushErrMsg`, { method: 'POST', headers: {'Content-Type': 'application/json', 'Authorization': `Token ${window.siyuan?.config?.apiToken || 'YOUR_API_TOKEN'}`}, body: JSON.stringify({ msg: `执行意外出错: ${e.message}`, timeout: 7000 }), }); } catch(notifyErr) {} } finally { button.disabled = false; button.textContent = '为日记块加日期属性'; button.style.backgroundColor = '#2d7ff9'; } }; document.body.appendChild(button); console.log("添加日期属性按钮已创建并添加到页面右上角。"); } // --- 初始化 --- (这部分代码不变) setTimeout(() => { if (typeof window.siyuan?.config !== 'undefined') { createProcessButton(); } else { console.warn("似乎不在思源环境中,按钮未创建。"); } }, 1500);
近期热议
推荐标签 标签
-
支付宝
29 引用 • 347 回帖 • 1 关注
支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。
-
RabbitMQ
49 引用 • 60 回帖 • 341 关注
RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
-
Ruby
7 引用 • 31 回帖 • 248 关注
Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。
-
友情链接
24 引用 • 373 回帖
确认过眼神后的灵魂连接,站在链在!
-
Dubbo
60 引用 • 82 回帖 • 615 关注
Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。
-
Follow
4 引用 • 12 回帖 • 12 关注
-
Flume
9 引用 • 6 回帖 • 654 关注
Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。
-
Gzip
9 引用 • 12 回帖 • 166 关注
gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。
-
App
91 引用 • 384 回帖 • 1 关注
App(应用程序,Application 的缩写)一般指手机软件。
-
Visio
1 引用 • 2 回帖 • 3 关注
-
sts
2 引用 • 2 回帖 • 228 关注
-
面试
325 引用 • 1395 回帖 • 2 关注
面试造航母,上班拧螺丝。多面试,少加班。
-
CloudFoundry
5 引用 • 18 回帖 • 181 关注
Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。
-
OneDrive
2 引用 • 1 关注
-
Sublime
10 引用 • 5 回帖 • 2 关注
Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。
-
心情
59 引用 • 369 回帖
心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。
-
Excel
31 引用 • 28 回帖
-
Solidity
3 引用 • 18 回帖 • 436 关注
Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。
-
Thymeleaf
11 引用 • 19 回帖 • 390 关注
Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。
-
JVM
180 引用 • 120 回帖
JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。
-
GraphQL
4 引用 • 3 回帖 • 11 关注
GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。
-
Flutter
39 引用 • 92 回帖 • 3 关注
Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。
-
Shell
125 引用 • 74 回帖 • 1 关注
Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。
-
博客
273 引用 • 2388 回帖
记录并分享人生的经历。
-
JavaScript
730 引用 • 1280 回帖 • 4 关注
JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。
-
Quicker
37 引用 • 157 回帖 • 3 关注
Quicker 您的指尖工具箱!操作更少,收获更多!
-
Ngui
7 引用 • 9 回帖 • 397 关注
Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于