[js] 让日记根据日期永久锁定

缘由

如题,自己常用思源做流水账日记,为防止误触或其他原因,增加日期锁定功能,其实就是拦截锁定的 api 并进行判断。

效果

如下图显示,打开非当前日期的指定日记时会拦截请求并提示。

PixPin20250506134555.png

用法

  1. 设置→外观→代码片段设置→js代码 中增加一个 js 代码块。
  2. 复制下面代码,将 targetBoxID 的值改为你想要应用日期锁定的笔记本
// 全局设置笔记本ID - 需要根据实际情况修改 const targetBoxID = ""; // 这里设置需要特殊处理的笔记本ID // 保存原始的fetch方法 const originalFetch = window.fetch; // 重写fetch方法进行API拦截 window.fetch = async function(input, init) { // 只拦截setBlockAttrs请求 if (typeof input === 'string' && input.includes('/api/attr/setBlockAttrs')) { // 克隆请求参数,避免修改原始请求 const clonedInit = { ...init }; if (init && init.body) { // 解析请求体 const requestBody = JSON.parse(init.body); const blockID = requestBody.id; // 检查此文档所属的笔记本是否为目标笔记本 const boxInfo = await checkDocumentBox(blockID); if (boxInfo && boxInfo.box === targetBoxID) { // 提取文档ID中的日期部分 (前8位) const docDate = blockID.substring(0, 8); const today = getTodayDateString(); // 如果不是当天的文档且正在尝试修改锁定状态 if (docDate !== today && requestBody.attrs && "custom-sy-readonly" in requestBody.attrs) { // 创建新的请求体,强制设置锁定状态为true const newBody = { ...requestBody }; newBody.attrs["custom-sy-readonly"] = "true"; // 更新请求 clonedInit.body = JSON.stringify(newBody); console.log("已锁定非当天文档:", blockID); // 显示弹窗提示 showLockNotification(docDate); } } } // 使用可能修改过的参数继续请求 return originalFetch(input, clonedInit); } // 非目标API,正常请求 return originalFetch(input, init); }; // 获取文档所属的笔记本ID async function checkDocumentBox(blockID) { try { const response = await originalFetch("/api/block/getBlockInfo", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: blockID }) }); const result = await response.json(); if (result.code === 0 && result.data) { return result.data; } return null; } catch (error) { console.error("获取文档信息失败:", error); return null; } } // 获取当前日期字符串,格式为YYYYMMDD function getTodayDateString() { const today = new Date(); const year = today.getFullYear(); const month = String(today.getMonth() + 1).padStart(2, '0'); const day = String(today.getDate()).padStart(2, '0'); return `${year}${month}${day}`; } // 显示锁定通知弹窗 function showLockNotification(docDate) { // 格式化日期显示 const year = docDate.substring(0, 4); const month = docDate.substring(4, 6); const day = docDate.substring(6, 8); const formattedDate = `${year}-${month}-${day}`; // 创建弹窗元素 const notification = document.createElement('div'); notification.style.position = 'fixed'; notification.style.top = '20px'; notification.style.left = '50%'; notification.style.transform = 'translateX(-50%)'; notification.style.backgroundColor = '#ff4d4f'; notification.style.color = 'white'; notification.style.padding = '12px 24px'; notification.style.borderRadius = '4px'; notification.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)'; notification.style.zIndex = '9999'; notification.style.fontWeight = 'bold'; notification.style.fontSize = '14px'; notification.style.display = 'flex'; notification.style.alignItems = 'center'; notification.style.gap = '8px'; // 添加图标 const icon = document.createElement('span'); icon.innerHTML = '🔒'; icon.style.fontSize = '16px'; notification.appendChild(icon); // 添加文本 const text = document.createElement('span'); text.textContent = `该日记(${formattedDate})非当前时间,已永久锁定`; notification.appendChild(text); // 添加到页面 document.body.appendChild(notification); // 3秒后自动移除 setTimeout(() => { notification.style.opacity = '0'; notification.style.transition = 'opacity 0.5s ease'; setTimeout(() => notification.remove(), 500); }, 3000); } console.log("思源笔记API拦截器已加载,目标笔记本ID:", targetBoxID);

获取笔记本 id

  1. 打开开发者工具
  2. 选择网络选项卡
  3. 清除已有的请求
  4. 打开任意一个待设置的笔记本下的文档
  5. 网络中找到 getBlockInfo 这个请求
  6. 在预览中复制 box 的值即为笔记本 id

PixPin20250506135813.webp

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    25834 引用 • 106980 回帖
  • 代码片段

    代码片段分为 CSS 与 JS 两种代码,添加在 [设置 - 外观 - 代码片段] 中,这些代码会在思源笔记加载时自动执行,用于改善笔记的样式或功能。

    用户在该标签下分享代码片段时需在帖子标题前添加 [css] [js] 用于区分代码片段类型。

    177 引用 • 1247 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 其实也可以简单的把 锁定按钮 加个 disabled 属性,省得拦截 api 的麻烦了。

    1 回复
  • Zynismus16

    对喔,是我想复杂了 😂

    有空再改下

    1 回复
  • 也可简单的这样

    .protyle-breadcrumb button[data-type="readonly"] { pointer-events: none; /* 禁止所有鼠标事件 */ opacity: 0.5; }

    补充:

    你这个获取笔记本 id 的方法也太麻烦了,小白估计有难度,直接下面的操作就行

    image.png

    1 操作
    wilsons 在 2025-05-06 20:11:49 更新了该回帖
  • 我经常把过去的日记反复编辑,严格说他并不是我的日记,而是我分散在不同日期反复编辑的收集箱。

  • huaji 锁定?叶归以前可是按块锁定的,直到我出了一堆变成了 html 块的内容,我把自动锁定功能给去掉了