<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>留心博客</title><description>风过留痕，雁过留声</description><link>https://fuwari.vercel.app/</link><language>zh_CN</language><item><title>3-2-1 备份规则：数据安全的不变真理</title><link>https://fuwari.vercel.app/posts/3-2-1-%E5%A4%87%E4%BB%BD%E8%A7%84%E5%88%99/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/3-2-1-%E5%A4%87%E4%BB%BD%E8%A7%84%E5%88%99/</guid><description>深入解析 3-2-1 备份策略的核心原则，探讨在云存储与勒索软件威胁并存的今天，这一经典规则如何演进以守护您的数字资产。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;自 3-2-1 备份规则在 21 世纪初首次提出以来，发生了很多变化。当时，iPad 还只是苹果公司的一个构想。Facebook 只有区区 5 亿用户。泰勒·斯威夫特只发行了两张专辑。百视达视频还存在，Netflix 还在送 DVD 到你家门口。&lt;/p&gt;
&lt;p&gt;与科技领域的大多数事物不同，3-2-1 备份规则多年来一直屹立不倒。尽管备份方法随着现代数据保护和云存储服务的发展而不断演变，但该规则仍然是数据冗余的事实标准。今天，我将解释什么是 3-2-1 备份规则，它发生了哪些变化，以及你如何轻松实现 3-2-1 备份，以保证你的&lt;a href=&quot;https://www.backblaze.com/cloud-storage&quot;&gt;数据安全和受保护&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;什么是 3-2-1 备份规则？&lt;/h2&gt;
&lt;p&gt;3-2-1 备份规则是一种简单、有效的数据备份策略，用于保护你的数据安全。它建议你将数据的三个副本存储在两种不同的介质上，其中一个副本存放在异地。让我们详细分解一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;三份数据副本&lt;/strong&gt;：你的三个副本包括原始数据（也称为生产数据），再加上另外两个副本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;两种不同的介质&lt;/strong&gt;：你应该将数据存储在两种不同的存储介质上，例如本地驱动器和云存储服务。如今，这与 21 世纪初的含义有所不同。我稍后会详细说明这一点。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一份异地副本&lt;/strong&gt;：你应该将一份数据副本存放在异地，理想情况下，与另外两个副本相距几英里以上，以防范可能影响本地副本的自然和物理灾难。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你想保护你的个人信息、照片、工作文件或其他重要数据，3-2-1 备份策略是一个不错的选择。通过使用多种存储类型和位置，它有助于避免出现单点故障，从而防范人为错误、&lt;a href=&quot;https://www.backblaze.com/blog/backblaze-drive-stats-for-q1-2024/&quot;&gt;硬盘崩溃&lt;/a&gt;、盗窃、自然灾害或&lt;a href=&quot;https://www.backblaze.com/blog/category/cloud-storage/ransomware/&quot;&gt;勒索软件&lt;/a&gt;带来的风险。&lt;/p&gt;
&lt;h2&gt;3-2-1 备份规则如何运作？&lt;/h2&gt;
&lt;p&gt;假设多年前你为了给税务会计提供资料，给你的社会安全卡拍了一张照片——这个文件名为“&lt;code&gt;socialsecurity.jpg&lt;/code&gt;”，存放在你家的电脑上，作为原始数据。这也是数据的第一个“副本”。&lt;/p&gt;
&lt;p&gt;你家里还有一个外部硬盘，用于&lt;a href=&quot;https://www.backblaze.com/cloud-backup/personal/mac-online-backup&quot;&gt;备份你常用的 Mac&lt;/a&gt; 或游戏用的&lt;a href=&quot;https://www.backblaze.com/cloud-backup/personal/windows-online-backup&quot;&gt;PC&lt;/a&gt;。这个外部硬盘会在备份过程中备份 &lt;code&gt;socialsecurity.jpg&lt;/code&gt;。这是不同存储介质上的第二个副本。&lt;/p&gt;
&lt;p&gt;除了这个外部硬盘，你还有一个&lt;a href=&quot;https://www.backblaze.com/cloud-backup&quot;&gt;在线备份解决方案&lt;/a&gt;（我们推荐 Backblaze，你懂的！）。在线备份会持续扫描你的电脑，并将你的数据上传到云端（通俗地说，就是异地数据中心）。&lt;code&gt;Socialsecurity.jpg&lt;/code&gt; 也会被包含在这次上传中，成为数据的第三个副本。&lt;/p&gt;
&lt;p&gt;哦！另外，你的纸质社会安全卡希望能存放在&lt;a href=&quot;https://www.backblaze.com/blog/building-your-digital-go-bag/&quot;&gt;防火保险箱&lt;/a&gt;里（而不是你的钱包里），这算是一个额外的保障。&lt;/p&gt;
&lt;h2&gt;3-2-1 备份策略发生了哪些变化？&lt;/h2&gt;
&lt;p&gt;当 3-2-1 规则首次提出时，有更多类型的介质可供选择来存储数据——不起眼的软盘、CD、蓝光光盘、U盘、外部硬盘驱动器（HDD）、固态硬盘（SSD）、网络附加存储（NAS）、磁带库等等。其中一些已经不再受欢迎，并且不再适用于现代数据存储需求（CD 和 DVD，我正看着你们呢）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.backblaze.com/blog/wp-content/uploads/2022/08/Backblaze-3-2-1_1_Floppy-Disks.png&quot; alt=&quot;一张咖啡杯放在软盘上的照片。&quot; /&gt;&lt;/p&gt;
&lt;p&gt;别担心，软盘。我们为你找到了用处。&lt;/p&gt;
&lt;p&gt;有些介质对于想要备份数据的典型家庭电脑用户来说既不实用也不划算（例如磁带库）。有些技术在当时价格高得令人望而却步，但现在已经便宜多了（如 SSD）。&lt;/p&gt;
&lt;p&gt;还有一个重要的方面在当时还不主流：云™（你可能听说过它被称为“别人的电脑”）。&lt;/p&gt;
&lt;p&gt;那么，这对 3-2-1 备份策略意味着什么呢？你还需要将数据保存在两种不同的介质上吗？&lt;/p&gt;
&lt;h3&gt;真的需要两种不同的介质吗？&lt;/h3&gt;
&lt;p&gt;简单来说：是，但也不是。如今，你&lt;strong&gt;不需要将数据保存在两种不同类型的介质上，但你确实需要将数据保存在两种不同的设备上。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;详细来说就复杂一些了。最初，使用两种存储介质的想法有两个原因。其一，它可以防止其中一种介质在&lt;a href=&quot;https://www.backblaze.com/blog/storage-tech-of-the-future-ceramics-dna-and-more/&quot;&gt;新存储技术&lt;/a&gt;出现时被淘汰（还是在说你呢，CD），导致数据无法用新存储技术读取。其二，将备份副本保存在单独的设备上是明智之举，这样硬件故障就不会同时影响两个本地副本。例如，如果你的电脑突然无法充电，你仍然可以从硬盘中恢复数据。&lt;/p&gt;
&lt;p&gt;虽然介质淘汰始终是一个令人担忧的问题，但云存储用于备份的出现几乎消除了这一问题。云服务提供商负责维护物理存储设备，并&lt;a href=&quot;https://www.backblaze.com/blog/backblaze-network-stats/&quot;&gt;确保你的数据随时可访问&lt;/a&gt;。因此，如果你使用云备份服务，你只需要担心将数据保存在两个设备上，而不是两种不同的介质上。这具体是什么样子呢？&lt;/p&gt;
&lt;h3&gt;最简单的 3-2-1 备份&lt;/h3&gt;
&lt;p&gt;如果你将家用电脑备份到外部硬盘，并使用诸如 &lt;a href=&quot;https://www.backblaze.com/cloud-backup&quot;&gt;Backblaze 电脑备份&lt;/a&gt;之类的服务将这两个设备都备份到云端，你就实现了 3-2-1 备份。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你拥有&lt;strong&gt;三份数据副本&lt;/strong&gt;：一份在你的电脑上，一份在你的硬盘上，一份在云端。&lt;/li&gt;
&lt;li&gt;你的数据存储在&lt;strong&gt;两种不同的设备&lt;/strong&gt;上：你的电脑和你的外部硬盘。（严格来说，是三种设备，因为你的数据也存储在云端）。&lt;/li&gt;
&lt;li&gt;其中&lt;strong&gt;一份&lt;/strong&gt;副本是异地的：云端的副本。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3-2-1 策略仍然是标准吗？&lt;/h2&gt;
&lt;p&gt;如果你根本没有进行备份，那么实施 3-2-1 备份策略仍然是保护你的数据的最佳做法。但是，在当今世界，3-2-1 规则更多地成为了一个起点，而不是一个完整的数据备份解决方案。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.backblaze.com/blog/complete-guide-ransomware/&quot;&gt;勒索软件攻击&lt;/a&gt;的兴起要求加强 3-2-1 策略的基本原则——冗余、地理距离和访问——并增加额外的保护措施。针对联网机器并捕获包括备份在内的所有数据的网络犯罪日益增多，这意味着数据安全需要额外的保护层。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.backblaze.com/blog/wp-content/uploads/2022/08/Backblaze-3-2-1_2_Cyberpig.png&quot; alt=&quot;一幅装饰性图片，展示了一个名为“网络猪”的网络攻击猪角色，正用他的笔记本电脑攻击服务器。&quot; /&gt;&lt;/p&gt;
&lt;p&gt;已经出现了这种行之有效的备份策略的新版本，例如 &lt;a href=&quot;https://www.backblaze.com/blog/whats-the-diff-3-2-1-vs-3-2-1-1-0-vs-4-3-2/&quot;&gt;3-2-1-1-0 或 4-3-2 备份&lt;/a&gt;。听起来有些多余？其实不然。&lt;/p&gt;
&lt;p&gt;好消息是，像 Backblaze 这样的公司至少可以让异地备份这部分变得不那么麻烦——我们会为你完成这项工作，并遵循安全最佳实践。&lt;/p&gt;
&lt;h2&gt;为什么我既需要本地备份又需要异地备份？&lt;/h2&gt;
&lt;p&gt;无论你是想&lt;a href=&quot;https://www.backblaze.com/cloud-backup/personal/mac-online-backup&quot;&gt;备份 Mac&lt;/a&gt; 还是&lt;a href=&quot;https://www.backblaze.com/cloud-backup/personal/windows-online-backup&quot;&gt;PC&lt;/a&gt;，本地备份都是在电脑出现问题时快速访问数据的简单方法。如果你的笔记本电脑或台式机的硬盘崩溃了，而你有一个最新的外部硬盘，你可以快速找回大部分数据，或者在你的电脑维修或更换期间，将外部硬盘用于另一台电脑。&lt;/p&gt;
&lt;p&gt;如果你记得让外部硬盘保持更新，数据丢失的风险就会很小，因为你可能只会丢失笔记本电脑上未复制的文件。大多数外部硬盘甚至都附带了确保其随时更新的软件。&lt;/p&gt;
&lt;p&gt;拥有本地备份是一个很好的开始，但拥有异地备份（例如云存储备份）是完整备份策略的关键组成部分。&lt;/p&gt;
&lt;p&gt;更新的备份策略利用了云的优势，提供：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;便利性&lt;/strong&gt;：在云端备份大量数据速度很快。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;耐用性和可靠性&lt;/strong&gt;：你的数据受到保护，免受火灾、自然灾害等影响。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;协作性&lt;/strong&gt;：通过权限进行共享直观且轻松。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3-2-1 备份规则是完美的吗？&lt;/h2&gt;
&lt;p&gt;世上没有完美的备份系统，但 3-2-1 方法对大多数人和企业来说都是一个很好的起点。甚至美国政府也推荐这种方法。在 2012 年为美国计算机应急准备小组（US-CERT）撰写的一篇论文中，卡内基梅隆大学在其出版物《数据备份选项》中推荐了 3-2-1 方法。&lt;/p&gt;
&lt;p&gt;然而，随着数据风险的演变，特别是随着勒索软件等网络威胁的增加以及针对备份副本的定向攻击，许多组织正在探索增强型策略，如 3-2-1-1-0 或 4-3-2。这些较新的方法在 3-2-1 规则的基础上，增加了额外的数据完整性和安全性层。&lt;/p&gt;
&lt;p&gt;实际上，3-2-1 规则提供了一种平衡的方法：将三份数据副本存储在两种不同的存储类型中，并进行一份异地备份，可防范硬件故障、自然灾害和大多数网络攻击。&lt;/p&gt;
&lt;p&gt;但根据你的业务连续性需求和数据敏感性，你可能希望探索提供更快恢复时间和额外数据保护的其他备份解决方案。&lt;/p&gt;
&lt;h2&gt;备份是最好的保障&lt;/h2&gt;
&lt;p&gt;3-2-1 计划非常适合备份你的文件。如果你把这个策略看作是一份保险单，你会希望它能在不可想象的事情发生时提供所需的保障。服务也很重要；拥有本地、异地和离线备份会给你更多的备份恢复选择。&lt;/p&gt;
&lt;h4&gt;Backblaze 备份，3-2-1 就绪……&lt;/h4&gt;
&lt;p&gt;虽然 Backblaze 无法帮助解决停电、电脑加密或防盗技术问题（尽管我们可以&lt;a href=&quot;https://www.backblaze.com/cloud-backup/features/find-my-computer&quot;&gt;定位电脑&lt;/a&gt;），但我们简化了你的数据备份过程。而且（根据我们最近的调查），只有 &lt;a href=&quot;https://www.backblaze.com/blog/2023-state-of-the-backup-as-data-needs-grow-backups-need-to-fill-the-gaps/&quot;&gt;11% 的拥有电脑的受访者每天进行备份&lt;/a&gt;，人们确实需要帮助！&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.backblaze.com/cloud-backup&quot;&gt;开始使用&lt;/a&gt; Backblaze 电脑备份（适用于你的个人或企业电脑）有助于解决你完整的 3-2-1 备份策略中至关重要的“1”。而且，凭借我们包含的一年版本历史功能（如果你想升级，还可以选择&lt;a href=&quot;https://www.backblaze.com/cloud-backup/features/extended-version-history&quot;&gt;永久版本历史&lt;/a&gt;），如果你的物理设备出现任何问题，你对备份数据会有额外的保护层。&lt;/p&gt;
</content:encoded></item><item><title>Fuwari 博客改造计划：为页面添加“双向滚动”控制（置顶与置底）</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E5%8F%8C%E5%90%91%E6%BB%9A%E5%8A%A8%E6%8E%A7%E5%88%B6/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0%E5%8F%8C%E5%90%91%E6%BB%9A%E5%8A%A8%E6%8E%A7%E5%88%B6/</guid><description>本文详细介绍了如何重构 Fuwari 的返回顶部组件，不仅增加了“下滑到底部”功能，还解决了 Swup 路由下按钮失效的深度兼容性问题。</description><pubDate>Sun, 05 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;为什么需要双向滚动？&lt;/h2&gt;
&lt;p&gt;Fuwari 原生只提供了一个“返回顶部”按钮。但在实际阅读长文或翻阅评论区时，用户往往也需要快速“直达底部”。为了保持界面的一致性，我们将这两个功能整合在同一个视觉区域，通过智能的算法自动判断该显示哪一个按钮，从而提升导航效率。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;设计架构&lt;/h2&gt;
&lt;p&gt;这是一个典型的“状态驱动”交互，我们需要处理好 UI、逻辑与框架生命周期的协作：&lt;/p&gt;
&lt;h3&gt;1. UI 表现层 (Component Layer)&lt;/h3&gt;
&lt;p&gt;我们将原有的单按钮组件重构为 &lt;code&gt;flex-col&lt;/code&gt; 垂直排列的按钮组。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;容器定位&lt;/strong&gt;：使用 &lt;code&gt;fixed&lt;/code&gt; 定位在屏幕右侧，并利用 &lt;code&gt;transform&lt;/code&gt; 处理初始的隐藏偏移。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;视觉反馈&lt;/strong&gt;：通过 &lt;code&gt;transition&lt;/code&gt; 实现平滑的缩放和位移过渡。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 核心逻辑层 (Logic Layer)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;滚动判定&lt;/strong&gt;：通过 &lt;code&gt;window.onscroll&lt;/code&gt; 实时对比 &lt;code&gt;scrollTop&lt;/code&gt;（当前滚动距离）、&lt;code&gt;clientHeight&lt;/code&gt;（视口高度）与 &lt;code&gt;scrollHeight&lt;/code&gt;（页面总高度）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;智能互斥&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;当页面不在顶部时，显示“返回顶部”。&lt;/li&gt;
&lt;li&gt;当页面距离底部超过一定阈值（如 100px）时，显示“下滑到底部”。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 生命周期适配层 (Integration Layer)&lt;/h3&gt;
&lt;p&gt;由于 Fuwari 使用了 Swup 路由，页面跳转时 DOM 会被替换。如果只在初次加载时获取按钮引用，跳转后脚本将无法找到新页面的按钮。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;重新初始化&lt;/strong&gt;：必须在 Swup 的 &lt;code&gt;page:view&lt;/code&gt; 钩子中重新执行 &lt;code&gt;getElementById&lt;/code&gt;，确保逻辑始终绑定在当前的活动元素上。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;核心实现步骤&lt;/h2&gt;
&lt;h3&gt;1. 重构基础组件&lt;/h3&gt;
&lt;p&gt;修改 &lt;code&gt;src/components/control/BackToTop.astro&lt;/code&gt;。我们将原来的 ID 移到了内部的按钮容器上，并引入了 Flex 布局。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;scroll-controls-wrapper hidden lg:block&quot;&amp;gt;
    &amp;lt;div class=&quot;scroll-controls-container flex flex-col gap-2&quot;&amp;gt;
        &amp;lt;!-- 返回顶部 --&amp;gt;
        &amp;lt;div id=&quot;back-to-top-btn&quot; class=&quot;scroll-btn hide&quot; onclick=&quot;window.scroll({top: 0, behavior: &apos;smooth&apos;})&quot;&amp;gt;
            &amp;lt;button class=&quot;btn-card h-[3.75rem] w-[3.75rem]&quot;&amp;gt;
                &amp;lt;Icon name=&quot;material-symbols:keyboard-arrow-up-rounded&quot; /&amp;gt;
            &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;!-- 下滑到底部 --&amp;gt;
        &amp;lt;div id=&quot;scroll-to-bottom-btn&quot; class=&quot;scroll-btn&quot; onclick=&quot;window.scroll({top: document.documentElement.scrollHeight, behavior: &apos;smooth&apos;})&quot;&amp;gt;
            &amp;lt;button class=&quot;btn-card h-[3.75rem] w-[3.75rem]&quot;&amp;gt;
                &amp;lt;Icon name=&quot;material-symbols:keyboard-arrow-down-rounded&quot; /&amp;gt;
            &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 注入全局滚动算法&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;src/layouts/Layout.astro&lt;/code&gt; 中找到 &lt;code&gt;scrollFunction&lt;/code&gt; 并升级它。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关键代码解析：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function scrollFunction() {
    let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    let scrollHeight = document.documentElement.scrollHeight;
    let clientHeight = document.documentElement.clientHeight;

    // 如果向下滚动超过 Banner，显示返回顶部
    if (scrollTop &amp;gt; bannerHeight) backToTopBtn.classList.remove(&apos;hide&apos;);
    else backToTopBtn.classList.add(&apos;hide&apos;);

    // 如果还没滚到底部（预留100px），显示滑到底部
    if (scrollTop + clientHeight &amp;lt; scrollHeight - 100) {
        scrollToBottomBtn.classList.remove(&apos;hide&apos;);
    } else {
        scrollToBottomBtn.classList.add(&apos;hide&apos;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 解决 Swup 跳转失效问题&lt;/h3&gt;
&lt;p&gt;这是很多改造者容易忽略的一步。在 &lt;code&gt;Layout.astro&lt;/code&gt; 的 &lt;code&gt;setup&lt;/code&gt; 函数中，我们需要监听 &lt;code&gt;page:view&lt;/code&gt; 事件来重新获取 DOM 引用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;window.swup.hooks.on(&apos;page:view&apos;, () =&amp;gt; {
    // 页面跳转后，旧的按钮对象已不存在于文档中，必须重新获取
    backToTopBtn = document.getElementById(&apos;back-to-top-btn&apos;);
    scrollToBottomBtn = document.getElementById(&apos;scroll-to-bottom-btn&apos;);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;细节优化建议&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;间距调整&lt;/strong&gt;：我们在按钮组中使用了 &lt;code&gt;gap-2&lt;/code&gt;，确保两个按钮之间有微小的缝隙，防止误触。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;阴影与背景&lt;/strong&gt;：复用了 Fuwari 的 &lt;code&gt;btn-card&lt;/code&gt; 类，使其在暗色模式下也能保持完美的视觉一致性。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;通过这次改造，您的博客不仅能“快速回头”，也能“一冲到底”。这种对细节的极致追求，能显著降低用户在长文中的操作疲劳感。&lt;/p&gt;
</content:encoded></item><item><title>Fuwari 博客改造计划：为侧边栏添加 Sticky 文章目录</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%9C%A8%E4%BE%A7%E8%BE%B9%E6%A0%8F%E6%B7%BB%E5%8A%A0%E6%96%87%E7%AB%A0%E7%9B%AE%E5%BD%95%E7%B4%A2%E5%BC%95/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%9C%A8%E4%BE%A7%E8%BE%B9%E6%A0%8F%E6%B7%BB%E5%8A%A0%E6%96%87%E7%AB%A0%E7%9B%AE%E5%BD%95%E7%B4%A2%E5%BC%95/</guid><description>本文介绍了如何在阅读文章时，通过侧边栏动态替换头像卡片为目录索引，并实现随滚动固定的 Sticky 效果。</description><pubDate>Sun, 05 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;为什么需要侧边栏目录？&lt;/h2&gt;
&lt;p&gt;Fuwari 原生的目录索引仅在 2K 屏幕以上可见。对于大多数 1080P 或更小屏幕的用户，阅读长文章时缺乏导航。此外，在阅读文章时，顶部的头像卡片（Profile）信息冗余。通过“动态替代”方案，我们可以在阅读时将头像换成目录，并让它始终固定在侧边栏顶部。&lt;/p&gt;
&lt;h2&gt;设计架构&lt;/h2&gt;
&lt;p&gt;为了实现平滑的切换和高效的导航，我们采用了&lt;strong&gt;容器替换 + 路由感知&lt;/strong&gt;的设计模式：&lt;/p&gt;
&lt;h3&gt;1. 动态路由感知 (Route Awareness)&lt;/h3&gt;
&lt;p&gt;在侧边栏组件中注入当前路径判断逻辑。只有当路径匹配 &lt;code&gt;/posts/&lt;/code&gt; 且文章包含标题数据（Headings）时，才会激活目录显示。&lt;/p&gt;
&lt;h3&gt;2. 局部容器替换 (Partial Hydration &amp;amp; Swup)&lt;/h3&gt;
&lt;p&gt;利用 Swup 的局部容器更新特性，将侧边栏顶部划分为独立容器 &lt;code&gt;#sidebar-top&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;首页/归档页&lt;/strong&gt;：渲染 Profile 组件。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章页&lt;/strong&gt;：渲染 SideBarTOC 组件。
Swup 会在页面跳转时精准替换此区域，实现“移花接木”的效果。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 粘性布局 (Sticky Strategy)&lt;/h3&gt;
&lt;p&gt;将目录组件放入侧边栏的 &lt;code&gt;sticky&lt;/code&gt; 区域。通过隐藏非 Sticky 的头像卡片，目录卡片会自动上移至侧边栏的最顶端，并在滚动时始终锁定在视口内。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;核心实现步骤&lt;/h2&gt;
&lt;h3&gt;1. 创建 SideBarTOC.astro&lt;/h3&gt;
&lt;p&gt;创建 &lt;code&gt;src/components/widget/SideBarTOC.astro&lt;/code&gt;。为保持简洁，我们仅提取一级标题展示。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import type { MarkdownHeading } from &quot;astro&quot;;
import { siteConfig } from &quot;../../config&quot;;
import { url } from &quot;../../utils/url-utils&quot;;

interface Props {
	class?: string;
	headings: MarkdownHeading[];
}

let { headings = [] } = Astro.props;
let minDepth = Math.min(...headings.map(h =&amp;gt; h.depth), 10);
---
&amp;lt;div class:list={[&quot;card-base p-4&quot;, Astro.props.class]}&amp;gt;
    &amp;lt;div class=&quot;font-bold transition text-lg text-neutral-900 dark:text-neutral-100 relative ml-4 mb-2
        before:w-1 before:h-4 before:rounded-md before:bg-[var(--primary)]
        before:absolute before:left-[-16px] before:top-[5.5px]&quot;&amp;gt;
        目录
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;max-h-[70vh] overflow-y-auto hide-scrollbar&quot;&amp;gt;
        {headings.filter(h =&amp;gt; h.depth === minDepth).map((heading, idx) =&amp;gt; (
            &amp;lt;a href={`#${heading.slug}`} class=&quot;px-2 flex gap-2 relative transition w-full py-2 hover:bg-[var(--toc-btn-hover)] rounded-xl&quot;&amp;gt;
                &amp;lt;div class=&quot;bg-[var(--toc-badge-bg)] text-[var(--btn-content)] w-5 h-5 shrink-0 rounded-lg text-xs flex items-center justify-center font-bold&quot;&amp;gt;
                    {idx + 1}
                &amp;lt;/div&amp;gt;
                &amp;lt;div class=&quot;text-sm text-50&quot;&amp;gt;{heading.text.replace(/#$/, &apos;&apos;)}&amp;lt;/div&amp;gt;
            &amp;lt;/a&amp;gt;
        ))}
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 集成到 SideBar&lt;/h3&gt;
&lt;p&gt;修改 &lt;code&gt;src/components/widget/SideBar.astro&lt;/code&gt;，实现组件切换。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;sidebar&quot;&amp;gt;
    &amp;lt;div id=&quot;sidebar-top&quot; class=&quot;transition-swup-fade mb-4&quot;&amp;gt;
        {!isPostsRoute &amp;amp;&amp;amp; &amp;lt;Profile /&amp;gt;}
    &amp;lt;/div&amp;gt;
    &amp;lt;div id=&quot;sidebar-sticky&quot; class=&quot;sticky top-4&quot;&amp;gt;
        &amp;lt;div id=&quot;sidebar-toc&quot; class=&quot;transition-swup-fade&quot;&amp;gt;
            {isPostsRoute &amp;amp;&amp;amp; &amp;lt;SideBarTOC headings={headings} /&amp;gt;}
        &amp;lt;/div&amp;gt;
        &amp;lt;Categories /&amp;gt;
        &amp;lt;!-- ... 其他小组件 --&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 配置 Swup 容器&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;astro.config.mjs&lt;/code&gt; 中，将新定义的 ID 加入更新列表：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;containers: [&quot;main&quot;, &quot;#toc&quot;, &quot;#sidebar-top&quot;, &quot;#sidebar-toc&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;这种方案不仅不占额外的屏幕空间，还极大提升了长文阅读的导航便利性，是针对侧边栏空间的二次利用。&lt;/p&gt;
</content:encoded></item><item><title>Fuwari 博客改造计划：为侧边栏添加音乐播放器卡片</title><link>https://fuwari.vercel.app/posts/fuwari%E4%B8%BB%E9%A2%98%E4%BE%A7%E8%BE%B9%E6%A0%8F%E9%9F%B3%E4%B9%90%E6%92%AD%E6%94%BE%E5%99%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88---xagunel%E3%81%AEblog/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E4%B8%BB%E9%A2%98%E4%BE%A7%E8%BE%B9%E6%A0%8F%E9%9F%B3%E4%B9%90%E6%92%AD%E6%94%BE%E5%99%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88---xagunel%E3%81%AEblog/</guid><description>本文介绍了如何在 Fuwari 主题中通过封装 Astro 组件，集成 Aplayer 和 MetingJS，在侧边栏实现一个支持全局播放、自动销毁实例且高度契合主题样式的音乐播放器卡片。</description><pubDate>Sun, 05 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;为什么选择侧边栏？&lt;/h2&gt;
&lt;p&gt;Fuwari 默认的 Aplayer 通常固定在左下角，虽然功能完整，但在视觉上略显突兀，且容易遮挡页面内容。通过将播放器封装为侧边栏卡片，不仅能让博客界面更加整洁、原生，还能利用 Fuwari 优秀的侧边栏粘性（Sticky）效果，让音乐控制始终触手可及。&lt;/p&gt;
&lt;h2&gt;设计架构&lt;/h2&gt;
&lt;p&gt;为了在 Astro 这种静态站点生成器中实现一个稳定、不重叠的音乐播放器，我们采用了以下分层架构：&lt;/p&gt;
&lt;h3&gt;1. 组件封装层 (Component Layer)&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;MusicPlayer.astro&lt;/code&gt; 作为核心。它负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资源注入&lt;/strong&gt;：按需引入 APlayer 和 MetingJS 的 CDN 脚本与样式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DOM 占位&lt;/strong&gt;：提供一个标准的 &lt;code&gt;card-base&lt;/code&gt; 容器，确保视觉样式与主题统一。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配置声明&lt;/strong&gt;：通过 Data Attributes（在脚本中动态设置）定义歌单来源。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 生命周期管理层 (Lifecycle Management)&lt;/h3&gt;
&lt;p&gt;由于 Fuwari 使用了 Swup 进行无刷新跳转，传统的脚本执行逻辑会失效。我们构建了一个闭环的生命周期：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;初始化 (Init)&lt;/strong&gt;：在 &lt;code&gt;DOMContentLoaded&lt;/code&gt; 和 &lt;code&gt;astro:page-load&lt;/code&gt; 时触发，确保首次进入或刷新页面时播放器可用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;清理 (Cleanup)&lt;/strong&gt;：在 Swup 的 &lt;code&gt;content:replace&lt;/code&gt; 阶段，主动调用 &lt;code&gt;aplayer.destroy()&lt;/code&gt;。这是&lt;strong&gt;防止多重音轨叠加&lt;/strong&gt;的核心逻辑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重建 (Rebuild)&lt;/strong&gt;：在 Swup 的 &lt;code&gt;page:view&lt;/code&gt; 阶段重新实例化，确保在切换页面后播放器依然存在于新的侧边栏 DOM 中。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 数据与逻辑通信 (Data &amp;amp; Logic)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;全局单例&lt;/strong&gt;：将 APlayer 实例挂载到 &lt;code&gt;window.musicPlayerInstance&lt;/code&gt;，实现跨组件、跨页面的实例追踪。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步适配&lt;/strong&gt;：由于 MetingJS 是异步渲染 DOM，架构中包含了一个&lt;strong&gt;轮询捕获机制&lt;/strong&gt;，确保在 DOM 准备就绪后再绑定实例控制权。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;核心实现步骤&lt;/h2&gt;
&lt;h3&gt;1. 创建 MusicPlayer 组件&lt;/h3&gt;
&lt;p&gt;创建文件 &lt;code&gt;src/components/MusicPlayer.astro&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
---
&amp;lt;!-- 引入 APlayer 和 MetingJS 的 CDN 资源 --&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css&quot; /&amp;gt;
&amp;lt;script is:inline src=&quot;https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script is:inline src=&quot;https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;div class=&quot;pb-4 card-base&quot;&amp;gt;
    &amp;lt;!-- 卡片标题样式，契合 Fuwari 主题 --&amp;gt;
    &amp;lt;div class=&quot;font-bold transition text-lg text-neutral-900 dark:text-neutral-100 relative ml-8 mt-4 mb-2
      before:w-1 before:h-4 before:rounded-md before:bg-[var(--primary)]
      before:absolute before:left-[-16px] before:top-[5.5px]&quot;&amp;gt;
        音乐
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- 播放器容器 --&amp;gt;
    &amp;lt;div class=&quot;px-4&quot; id=&quot;music-player-container&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script is:inline&amp;gt;
// 全局变量存储播放器实例，用于后续销毁
window.musicPlayerInstance = null;

function initMusicPlayer() {
    // 1. 销毁已存在的实例，防止页面切换后出现多个播放器叠加或报错
    if (window.musicPlayerInstance) {
        try {
            window.musicPlayerInstance.destroy();
        } catch (e) {
            console.error(&apos;销毁旧播放器实例失败:&apos;, e);
        }
        window.musicPlayerInstance = null;
    }

    // 2. 清除并重建容器
    const container = document.getElementById(&apos;music-player-container&apos;);
    if (!container) return;
    container.innerHTML = &apos;&apos;;

    // 3. 动态创建 meting-js 元素
    const metingElement = document.createElement(&apos;meting-js&apos;);
    metingElement.setAttribute(&apos;server&apos;, &apos;netease&apos;); 
    metingElement.setAttribute(&apos;type&apos;, &apos;playlist&apos;); 
    metingElement.setAttribute(&apos;id&apos;, &apos;2501170701&apos;); 
    metingElement.setAttribute(&apos;fixed&apos;, &apos;false&apos;);  
    metingElement.setAttribute(&apos;autoplay&apos;, &apos;false&apos;);
    metingElement.setAttribute(&apos;theme&apos;, &apos;var(--primary)&apos;);
    metingElement.setAttribute(&apos;loop&apos;, &apos;all&apos;);
    metingElement.setAttribute(&apos;order&apos;, &apos;list&apos;);
    metingElement.setAttribute(&apos;preload&apos;, &apos;auto&apos;);
    metingElement.setAttribute(&apos;list-folded&apos;, &apos;true&apos;);
    metingElement.setAttribute(&apos;list-max-height&apos;, &apos;300px&apos;);

    container.appendChild(metingElement);

    // 4. 手动触发 MetingJS 初始化
    if (typeof window.Meting === &apos;function&apos;) {
        window.Meting(metingElement);
    }

    // 5. 轮询获取生成的 APlayer 实例并存储
    let retryCount = 0;
    const maxRetries = 10;
    const checkAPlayer = () =&amp;gt; {
        const aplayerElement = container.querySelector(&apos;.aplayer&apos;);
        if (aplayerElement &amp;amp;&amp;amp; aplayerElement.aplayer) {
            window.musicPlayerInstance = aplayerElement.aplayer;
        } else if (retryCount &amp;lt; maxRetries) {
            retryCount++;
            setTimeout(checkAPlayer, 200);
        }
    };
    checkAPlayer();
}

// 适配多种页面加载场景
document.addEventListener(&apos;DOMContentLoaded&apos;, initMusicPlayer);
document.addEventListener(&apos;astro:page-load&apos;, initMusicPlayer);

// 特别适配 Swup 路由切换
if (window.swup) {
    window.swup.hooks.on(&apos;content:replace&apos;, () =&amp;gt; {
        if (window.musicPlayerInstance) {
            try {
                window.musicPlayerInstance.destroy();
            } catch (e) {
                console.log(&apos;Swup 切换时销毁播放器:&apos;, e);
            }
            window.musicPlayerInstance = null;
        }
    });
    window.swup.hooks.on(&apos;page:view&apos;, initMusicPlayer);
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 集成到侧边栏&lt;/h3&gt;
&lt;p&gt;打开 &lt;code&gt;src/components/widget/SideBar.astro&lt;/code&gt;，将刚才创建的组件引入并放置在合适的位置。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
// ... 其他导入
import MusicPlayer from &quot;../MusicPlayer.astro&quot;;
// ...
---
&amp;lt;div id=&quot;sidebar&quot; class:list={[className, &quot;w-full&quot;]}&amp;gt;
    &amp;lt;!-- ... Profile 等组件 --&amp;gt;
    &amp;lt;div id=&quot;sidebar-sticky&quot; ...&amp;gt;
        &amp;lt;Categories ... /&amp;gt;
        &amp;lt;Tag ... /&amp;gt;
        &amp;lt;!-- 在这里添加音乐播放器 --&amp;gt;
        &amp;lt;MusicPlayer class=&quot;onload-animation&quot; style=&quot;animation-delay: 250ms&quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;技术细节说明&lt;/h2&gt;
&lt;h3&gt;Swup 路由适配&lt;/h3&gt;
&lt;p&gt;Fuwari 使用了 Swup 实现无刷新页面切换。如果不做处理，切换页面时旧的 APlayer 实例会残留在 DOM 之外继续工作，导致出现“重音”或者无法控制的情况。我们在脚本中监听了 &lt;code&gt;content:replace&lt;/code&gt; 钩子，确保在页面内容更新前彻底销毁旧实例。&lt;/p&gt;
&lt;h3&gt;实例获取&lt;/h3&gt;
&lt;p&gt;由于 MetingJS 是异步生成 APlayer 结构的，我们使用了一个简单的 &lt;code&gt;setTimeout&lt;/code&gt; 轮询机制来捕获生成的 &lt;code&gt;aplayer&lt;/code&gt; 对象，以便我们在全局范围管理它。&lt;/p&gt;
&lt;h2&gt;如何自定义&lt;/h2&gt;
&lt;p&gt;你只需要修改 &lt;code&gt;MusicPlayer.astro&lt;/code&gt; 中的 &lt;code&gt;meting-js&lt;/code&gt; 属性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;server&lt;/strong&gt;: 平台（netease - 网易云，tencent - QQ音乐）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;id&lt;/strong&gt;: 歌单、专辑或单曲的 ID。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;theme&lt;/strong&gt;: 播放器主色调，代码中已设为 &lt;code&gt;var(--primary)&lt;/code&gt; 以匹配你的主题色。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;通过这种方式实现的音乐播放器，不仅外观上与 Fuwari 的卡片式设计完美融合，而且在性能和稳定性上也针对 Astro 的特性进行了优化。快去换上你喜欢的歌单吧！&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;参考与致谢&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原始方案参考&lt;/strong&gt;：&lt;a href=&quot;https://blog.xomoe.cn/posts/2025-08-22/musicplayer/&quot;&gt;fuwari主题侧边栏音乐播放器解决方案 - xagunelのblog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技术支持&lt;/strong&gt;：APlayer &amp;amp; MetingJS&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Fuwari 博客改造计划：如何使用 Expressive Code</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8expressive-code/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8expressive-code/</guid><description>探索如何在 Markdown 中使用 Expressive Code 增强代码块显示效果。</description><pubDate>Fri, 03 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在这篇文章中，我们将探索如何使用 &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt; 来增强 Markdown 中的代码块显示。以下示例基于官方文档，您可以查阅文档以获取更多详细信息。&lt;/p&gt;
&lt;h2&gt;1. 语法高亮 (Syntax Highlighting)&lt;/h2&gt;
&lt;p&gt;Expressive Code 提供了强大的&lt;a href=&quot;https://expressive-code.com/key-features/syntax-highlighting/&quot;&gt;语法高亮&lt;/a&gt;功能。&lt;/p&gt;
&lt;h4&gt;常规语法高亮&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;这段代码具有语法高亮！&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;渲染 ANSI 转义序列&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ANSI 颜色示例:
- 标准: [31m红色[0m [32m绿色[0m [33m黄色[0m [34m蓝色[0m [35m洋红[0m [36m青色[0m
- 加粗: [1;31m红色[0m [1;32m绿色[0m [1;33m黄色[0m [1;34m蓝色[0m [1;35m洋红[0m [1;36m青色[0m
- 变暗: [2;31m红色[0m [2;32m绿色[0m [2;33m黄色[0m [2;34m蓝色[0m [2;35m洋红[0m [2;36m青色[0m

256 色 (显示 160-177):
[38;5;160m160 [38;5;161m161 [38;5;162m162 [38;5;163m163 [38;5;164m164 [38;5;165m165[0m
[38;5;166m166 [38;5;167m167 [38;5;168m168 [38;5;169m169 [38;5;170m170 [38;5;171m171[0m
[38;5;172m172 [38;5;173m173 [38;5;174m174 [38;5;175m175 [38;5;176m176 [38;5;177m177[0m

全 RGB 颜色:
[38;2;34;139;34m森林绿 - RGB(34, 139, 34)[0m

文本格式: [1m加粗[0m [2m变暗[0m [3m斜体[0m [4m下划线[0m
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 编辑器与终端外框 (Editor &amp;amp; Terminal Frames)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/frames/&quot;&gt;编辑器与终端外框&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;代码编辑器外框&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```js title=&quot;my-test-file.js&quot;
console.log(&apos;带有标题属性的示例&apos;)```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;带有标题属性的示例&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;```html  &amp;lt;!-- src/content/index.html --&amp;gt;
&amp;lt;div&amp;gt;通过注释指定文件名的示例&amp;lt;/div&amp;gt;```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/content/index.html --&amp;gt;
&amp;lt;div&amp;gt;通过注释指定文件名的示例&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;终端外框&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```bash
echo &quot;这个终端外框没有标题&quot;```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;这个终端外框没有标题&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;```powershell title=&quot;PowerShell 终端示例&quot;
Write-Output &quot;这个带有一个标题！&quot;```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Write-Output &quot;这个带有一个标题！&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;覆盖外框类型&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```sh frame=&quot;none&quot;
echo &quot;看，没有任何外框！&quot;```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;看，没有任何外框！&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;```ps frame=&quot;code&quot; title=&quot;PowerShell Profile.ps1&quot;
# 如果不手动覆盖，这通常会被自动识别为终端外框
function Watch-Tail { Get-Content -Tail 20 -Wait $args }
New-Alias tail Watch-Tail```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 如果不手动覆盖，这通常会被自动识别为终端外框
function Watch-Tail { Get-Content -Tail 20 -Wait $args }
New-Alias tail Watch-Tail
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. 文本与行标记 (Text &amp;amp; Line Markers)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/text-markers/&quot;&gt;文本与行标记&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;标记整行或行范围&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```js {1, 4, 7-8}
// 第 1 行 - 通过行号标记
// 第 2 行
// 第 3 行
// 第 4 行 - 通过行号标记
// 第 5 行
// 第 6 行
// 第 7 行 - 通过范围 &quot;7-8&quot; 标记
// 第 8 行 - 通过范围 &quot;7-8&quot; 标记```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 第 1 行 - 通过行号标记
// 第 2 行
// 第 3 行
// 第 4 行 - 通过行号标记
// 第 5 行
// 第 6 行
// 第 7 行 - 通过范围 &quot;7-8&quot; 标记
// 第 8 行 - 通过范围 &quot;7-8&quot; 标记
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;选择行标记类型 (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```js title=&quot;line-markers.js&quot; del={2} ins={3-4} {6}
function demo() {
  console.log(&apos;这一行被标记为已删除&apos;)
  // 这一行和下一行被标记为已插入
  console.log(&apos;这是第二个插入行&apos;)

  return &apos;这一行使用中性的默认标记类型&apos;
}```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;这一行被标记为已删除&apos;)
  // 这一行和下一行被标记为已插入
  console.log(&apos;这是第二个插入行&apos;)

  return &apos;这一行使用中性的默认标记类型&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;为行标记添加标签&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```jsx {&quot;1&quot;:5} del={&quot;2&quot;:7-8} ins={&quot;3&quot;:10-12}
// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}
  value={value}
  className={buttonClassName}
  disabled={disabled}
  active={active}
&amp;gt;
  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}
  value={value}
  className={buttonClassName}
  disabled={disabled}
  active={active}
&amp;gt;
  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加长标签&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```jsx {&quot;1. 在这里提供 value 属性:&quot;:5-6} del={&quot;2. 移除 disabled 和 active 状态:&quot;:8-10} ins={&quot;3. 添加此项以在按钮内渲染子元素:&quot;:12-15}
// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}

  value={value}
  className={buttonClassName}

  disabled={disabled}
  active={active}
&amp;gt;

  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}

  value={value}
  className={buttonClassName}

  disabled={disabled}
  active={active}
&amp;gt;

  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用类似 Diff 的语法&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```diff
+这一行将被标记为已插入
-这一行将被标记为已删除
这是一行普通代码```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;+这一行将被标记为已插入
-这一行将被标记为已删除
这是一行普通代码
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;```diff
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+这是一个真实的 diff 文件示例
-所有内容都将保持原样
 连空格也不会被移除```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+这是一个真实的 diff 文件示例
-所有内容都将保持原样
 连空格也不会被移除
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;将语法高亮与 Diff 语法结合&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```diff lang=&quot;js&quot;
  function thisIsJavaScript() {
    // 整个代码块按 JavaScript 高亮，
    // 同时我们仍然可以添加 diff 标记！
-   console.log(&apos;旧的代码将被移除&apos;)
+   console.log(&apos;全新的闪亮代码！&apos;)
  }```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;  function thisIsJavaScript() {
    // 整个代码块按 JavaScript 高亮，
    // 同时我们仍然可以添加 diff 标记！
-   console.log(&apos;旧的代码将被移除&apos;)
+   console.log(&apos;全新的闪亮代码！&apos;)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;标记行内的特定文本&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```js &quot;指定文本&quot;
function demo() {
  // 标记行内任何出现的“指定文本”
  return &apos;支持多次匹配指定文本&apos;;
}```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  // 标记行内任何出现的“指定文本”
  return &apos;支持多次匹配指定文本&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;正则表达式&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```ts /ye[sp]/
console.log(&apos;单词 yes 和 yep 都将被标记。&apos;)```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;单词 yes 和 yep 都将被标记。&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;标记行内标记类型 (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```js &quot;return true;&quot; ins=&quot;inserted&quot; del=&quot;deleted&quot;
function demo() {
  console.log(&apos;这些是 inserted 和 deleted 标记类型&apos;);
  // return 语句使用默认标记类型
  return true;
}```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;这些是 inserted 和 deleted 标记类型&apos;);
  // return 语句使用默认标记类型
  return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4. 自动换行 (Word Wrap)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/word-wrap/&quot;&gt;自动换行&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;为单个代码块配置换行&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```js wrap
// 开启换行的示例
function getLongString() {
  return &apos;这是一段非常长的字符串，如果不开启自动换行，它很可能超出现在容器的显示范围，除非容器极宽。&apos;
}```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 开启换行的示例
function getLongString() {
  return &apos;这是一段非常长的字符串，如果不开启自动换行，它很可能超出现在容器的显示范围，除非容器极宽。&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;```js wrap=false
// 关闭换行的示例 (wrap=false)
function getLongString() {
  return &apos;这是一段非常长的字符串，如果不开启自动换行，它很可能超出现在容器的显示范围，除非容器极宽。&apos;
}```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 关闭换行的示例 (wrap=false)
function getLongString() {
  return &apos;这是一段非常长的字符串，如果不开启自动换行，它很可能超出现在容器的显示范围，除非容器极宽。&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置换行后的缩进&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;```js wrap preserveIndent
// 保持缩进示例 (默认开启)
function getLongString() {
  return &apos;长字符串换行后会保持与上一行相同的缩进位置。&apos;
}```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 保持缩进示例 (默认开启)
function getLongString() {
  return &apos;长字符串换行后会保持与上一行相同的缩进位置。&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;```js wrap preserveIndent=false
// 关闭保持缩进示例 (preserveIndent=false)
function getLongString() {
  return &apos;长字符串换行后将不再保持缩进，而是从行首开始。&apos;
}```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 关闭保持缩进示例 (preserveIndent=false)
function getLongString() {
  return &apos;长字符串换行后将不再保持缩进，而是从行首开始。&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;5. 可折叠代码段 (Collapsible Sections)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/collapsible-sections/&quot;&gt;可折叠代码段插件&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```js collapse={1-5, 12-14, 21-24}
// 这里的初始化样板代码将被折叠
import { someBoilerplateEngine } from &apos;@example/some-boilerplate&apos;
import { evenMoreBoilerplate } from &apos;@example/even-more-boilerplate&apos;

const engine = someBoilerplateEngine(evenMoreBoilerplate())

// 这部分代码默认可见
engine.doSomething(1, 2, 3, calcFn)

function calcFn() {
  // 您可以设置多个折叠区域
  const a = 1
  const b = 2
  const c = a + b

  // 这一行保持可见
  console.log(`计算结果: ${a} + ${b} = ${c}`)
  return c
}

// 结尾的样板代码也会被再次折叠
engine.closeConnection()
engine.freeMemory()
engine.shutdown({ reason: &apos;End of example boilerplate code&apos; })```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 这里的初始化样板代码将被折叠
import { someBoilerplateEngine } from &apos;@example/some-boilerplate&apos;
import { evenMoreBoilerplate } from &apos;@example/even-more-boilerplate&apos;

const engine = someBoilerplateEngine(evenMoreBoilerplate())

// 这部分代码默认可见
engine.doSomething(1, 2, 3, calcFn)

function calcFn() {
  // 您可以设置多个折叠区域
  const a = 1
  const b = 2
  const c = a + b

  // 这一行保持可见
  console.log(`计算结果: ${a} + ${b} = ${c}`)
  return c
}

// 结尾的样板代码也会被再次折叠
engine.closeConnection()
engine.freeMemory()
engine.shutdown({ reason: &apos;End of example boilerplate code&apos; })
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;6. 行号 (Line Numbers)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/line-numbers/&quot;&gt;行号插件&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;为代码块显示行号&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;```js showLineNumbers
// 这个代码块将显示行号
console.log(&apos;来自第 2 行的问候！&apos;)
console.log(&apos;我在第 3 行&apos;)```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 这个代码块将显示行号
console.log(&apos;来自第 2 行的问候！&apos;)
console.log(&apos;我在第 3 行&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;```js showLineNumbers=false
// 这个代码块禁用了行号
console.log(&apos;你好？&apos;)
console.log(&apos;抱歉，你知道我在哪一行吗？&apos;)```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;// 这个代码块禁用了行号
console.log(&apos;你好？&apos;)
console.log(&apos;抱歉，你知道我在哪一行吗？&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;修改起始行号&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;```js showLineNumbers startLineNumber=5
console.log(&apos;来自第 5 行的问候！&apos;)
console.log(&apos;我在第 6 行&apos;)```
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;来自第 5 行的问候！&apos;)
console.log(&apos;我在第 6 行&apos;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Windows 环境下配置 Path 环境变量教程</title><link>https://fuwari.vercel.app/posts/windows-%E7%8E%AF%E5%A2%83%E4%B8%8B%E9%85%8D%E7%BD%AE-path-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/windows-%E7%8E%AF%E5%A2%83%E4%B8%8B%E9%85%8D%E7%BD%AE-path-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E6%95%99%E7%A8%8B/</guid><description>本文介绍了多种在 Windows 中快速打开环境变量的方法，并分享了如何利用 AutoHotkey 脚本实现从 Sublime Text 一键在浏览器预览 Markdown 文档。</description><pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;安装某个命令行软件和编程语言时，配置 Path 是 Windows 特有的流程，这里是详细的教程，以及易错点纠正。&lt;/p&gt;
&lt;h2&gt;Step1 找到软件的安装路径&lt;a href=&quot;https://pinpe.top/posts/set-path/#step1-%E6%89%BE%E5%88%B0%E8%BD%AF%E4%BB%B6%E7%9A%84%E5%AE%89%E8%A3%85%E8%B7%AF%E5%BE%84&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;配置 Path 需要具体的软件安装路径，这可能是一个文件或一个文件夹，具体路径可参照软件文档和你安装此软件的位置。&lt;/p&gt;
&lt;p&gt;找到后，请复制路径到剪贴板备用。&lt;/p&gt;
&lt;h2&gt;Step2 打开环境变量设置&lt;a href=&quot;https://pinpe.top/posts/set-path/#step2-%E6%89%93%E5%BC%80%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E8%AE%BE%E7%BD%AE&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在 Windows 系统中，打开“环境变量”设置的方法有很多，从最直观的图形界面到高效的命令行都有。&lt;/p&gt;
&lt;h3&gt;1. 最快捷的方法：运行命令（推荐）&lt;/h3&gt;
&lt;p&gt;这种方法不依赖系统版本（Win10/Win11 通用），且速度最快。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;按下键盘上的 &lt;strong&gt;&lt;code&gt;Win + R&lt;/code&gt;&lt;/strong&gt; 键，打开“运行”对话框。&lt;/li&gt;
&lt;li&gt;输入以下命令并回车：
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;sysdm.cpl&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;在弹出的“系统属性”窗口中，点击 &lt;strong&gt;高级 (Advanced)&lt;/strong&gt; 选项卡，下方即可看到 &lt;strong&gt;环境变量 (Environment Variables)&lt;/strong&gt; 按钮。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. “开始”菜单搜索法&lt;/h3&gt;
&lt;p&gt;这是最符合直觉的操作方式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;点击任务栏的 &lt;strong&gt;搜索图标&lt;/strong&gt; 或直接按下 &lt;strong&gt;&lt;code&gt;Win&lt;/code&gt;&lt;/strong&gt; 键。&lt;/li&gt;
&lt;li&gt;输入 &lt;strong&gt;“环境变量”&lt;/strong&gt;（英文系统输入 &lt;code&gt;env&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;选择 &lt;strong&gt;“编辑系统环境变量”&lt;/strong&gt; 或 &lt;strong&gt;“编辑账户的环境变量”&lt;/strong&gt; 即可直接跳转。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 设置面板路径（Win10/Win11）&lt;/h3&gt;
&lt;p&gt;如果你习惯在 UI 界面中点击：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Win11:&lt;/strong&gt; 设置 -&amp;gt; 系统 -&amp;gt; 关于 -&amp;gt; &lt;strong&gt;高级系统设置&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Win10:&lt;/strong&gt; 设置 -&amp;gt; 系统 -&amp;gt; 关于 -&amp;gt; 右侧或下方的 &lt;strong&gt;高级系统设置&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 命令行一键直达（高级用户）&lt;/h3&gt;
&lt;p&gt;如果你已经打开了终端（CMD 或 PowerShell），可以直接通过命令唤起：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CMD:&lt;/strong&gt; 输入 &lt;code&gt;rundll32.exe sysdm.cpl,EditEnvironmentVariables&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PowerShell:&lt;/strong&gt; 输入 &lt;code&gt;Start-Process rundll32.exe -ArgumentList &quot;sysdm.cpl,EditEnvironmentVariables&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 通过控制面板（传统方式）&lt;/h3&gt;
&lt;p&gt;虽然控制面板在淡出，但依然可用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开 &lt;strong&gt;控制面板&lt;/strong&gt; -&amp;gt; &lt;strong&gt;系统和安全&lt;/strong&gt; -&amp;gt; &lt;strong&gt;系统&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;高级系统设置&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 小贴士：用户变量 vs 系统变量
在打开的窗口中，你会看到上下两个框：
&lt;strong&gt;用户变量（上方）：&lt;/strong&gt; 仅对当前登录的 Windows 账号生效，安全性更高，推荐平时安装软件使用。
&lt;strong&gt;系统变量（下方）：&lt;/strong&gt; 对这台电脑的所有用户生效，修改需谨慎。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Step3 找到 Path 环境变量，并添加路径&lt;a href=&quot;https://pinpe.top/posts/set-path/#step3-%E6%89%BE%E5%88%B0path%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E5%B9%B6%E6%B7%BB%E5%8A%A0%E8%B7%AF%E5%BE%84&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在系统变量里面找到名为&lt;code&gt;Path&lt;/code&gt;的数组型变量，点击编辑：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://pinpe.top/_astro/path.uAdDr54B_Z17h4iV.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;点击&lt;code&gt;新建&lt;/code&gt;，粘贴第一步就复制的路径，一路确定，完成。&lt;/p&gt;
</content:encoded></item><item><title>为 Fuwari 添加 Giscus 评论系统</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E6%B7%BB%E5%8A%A0-giscus-%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F---thws-blog/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E6%B7%BB%E5%8A%A0-giscus-%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F---thws-blog/</guid><description>手把手教你如何在基于 Astro 架构的 Fuwari 主题中配置并安装基于 GitHub Discussions 的 Giscus 评论系统。</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;介绍&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Fuwari&lt;/strong&gt; 作为一款基于 Astro 框架的轻量级静态博客模板，以其简洁的设计和卓越的性能受到开发者青睐。然而，评论功能一直是静态博客的短板，传统评论系统往往需要复杂的后端配置和数据库支持。&lt;/p&gt;
&lt;p&gt;本文将详细介绍如何为 Fuwari 静态博客无缝集成 &lt;strong&gt;Giscus 评论系统&lt;/strong&gt;，实现基于 GitHub Discussions 的轻量级、无需数据库的评论解决方案。并实现兼容亮色/暗色主题的自适应效果。&lt;/p&gt;
&lt;h2&gt;项目架构&lt;/h2&gt;
&lt;h3&gt;1. 组件封装层 (&lt;code&gt;src/components/misc/Giscus.astro&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;Fuwari 将评论功能封装为一个独立的 &lt;strong&gt;Astro 组件&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;属性传递&lt;/strong&gt;：通过 &lt;code&gt;Astro.props&lt;/code&gt; 接收 &lt;code&gt;repo&lt;/code&gt;、&lt;code&gt;repoId&lt;/code&gt;、&lt;code&gt;categoryId&lt;/code&gt; 等配置参数。这种做法将配置信息（存储在 &lt;code&gt;src/config.ts&lt;/code&gt; 或直接传参）与显示逻辑分离。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态注入&lt;/strong&gt;：使用 &lt;code&gt;&amp;lt;script define:vars={{...}}&amp;gt;&lt;/code&gt; 将服务器端的配置变量安全地传递给客户端 JavaScript。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 执行逻辑层 (Client-side JS)&lt;/h3&gt;
&lt;p&gt;组件内部的脚本负责评论区的生命周期管理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;按需加载&lt;/strong&gt;：通过 &lt;code&gt;document.createElement(&apos;script&apos;)&lt;/code&gt; 动态创建 &lt;code&gt;script&lt;/code&gt; 标签。这样做可以避免在页面初始加载时阻塞渲染，提升 Fuwari 引以为傲的性能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;容器绑定&lt;/strong&gt;：评论区被挂载到一个特定的 DOM 元素（如 &lt;code&gt;#giscus-container&lt;/code&gt;），这使得评论区在页面布局中位置固定且可控。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 主题同步机制 (Theme Bridge)&lt;/h3&gt;
&lt;p&gt;这是 Fuwari 集成中最关键的部分。Fuwari 允许用户手动切换亮/暗模式，Giscus 必须实时响应：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MutationObserver&lt;/strong&gt;：脚本注册了一个 &lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver&quot;&gt;MutationObserver&lt;/a&gt;，监控 &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; 标签的 &lt;code&gt;class&lt;/code&gt; 属性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;postMessage 通信&lt;/strong&gt;：由于 Giscus 运行在 &lt;code&gt;iframe&lt;/code&gt; 中，主页面无法直接修改其样式。当观察到主题 class 变化（如切换到 &lt;code&gt;.dark&lt;/code&gt;）时，主页面会通过 &lt;code&gt;postMessage&lt;/code&gt; 向 &lt;code&gt;iframe&lt;/code&gt; 发送一个 &lt;code&gt;setConfig&lt;/code&gt; 消息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无刷新切换&lt;/strong&gt;：Giscus 接收到消息后，内部会动态更换 CSS 变量，从而实现无需刷新页面就能完成评论区颜色的无缝切换。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 路由适配层 (&lt;code&gt;src/pages/posts/[...slug].astro&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;在 Astro 的动态路由模板中，Giscus 被放置在内容渲染区域（Markdown 内容和 &lt;a href=&quot;https://blog.142588.xyz/posts/%E4%B8%BA-fuwari-%E6%B7%BB%E5%8A%A0-giscus-%E8%AF%84%E8%AE%BA%E7%B3%BB%E7%BB%9F---thws-blog/&quot;&gt;License 组件&lt;/a&gt;）之后。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ID 匹配&lt;/strong&gt;：通常使用 &lt;code&gt;mapping=&quot;pathname&quot;&lt;/code&gt;。这意味着 Giscus 会将当前页面的 URL 路径（如 &lt;code&gt;/posts/my-article&lt;/code&gt;）作为 GitHub Discussion 的标题或标签，从而确保每篇文章都有独立的评论池。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 存储架构 (Backend-less)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;无数据库&lt;/strong&gt;：整个 Fuwari 项目依然保持 100% 静态。所有的评论数据、用户信息、点赞互动全部存储在你的 &lt;strong&gt;GitHub Repository Discussions&lt;/strong&gt; 中。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全性&lt;/strong&gt;：通过 &lt;code&gt;giscus.json&lt;/code&gt;（如果配置了的话）可以限制哪些域名可以调用该评论插件，防止他人盗用你的评论仓库。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;配置&lt;/h2&gt;
&lt;h3&gt;准备 GitHub 仓库&lt;/h3&gt;
&lt;p&gt;首先，我们需要在 GitHub 上创建一个专门用于存储评论的仓库。&lt;strong&gt;这个仓库必须是公开的&lt;/strong&gt;，因为 Giscus 需要通过访问 GitHub 仓库来加载和提交评论。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建新仓库&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登录 GitHub，点击右上角 ”+” 按钮&lt;/li&gt;
&lt;li&gt;选择 “New repository”&lt;/li&gt;
&lt;li&gt;填写仓库名称（如 &lt;code&gt;fuwari-comments&lt;/code&gt;）和其他必要信息&lt;/li&gt;
&lt;li&gt;确保仓库可见性设置为 &lt;strong&gt;Public&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;启用 Discussions 功能&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入仓库的 &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Features&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;找到 “Discussions” 选项并勾选&lt;/li&gt;
&lt;li&gt;点击 “Save changes” 保存&lt;/li&gt;
&lt;li&gt;Discussions 是 GitHub 为项目讨论提供的平台，Giscus 将利用这一功能存储评论&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;配置 Giscus&lt;/h3&gt;
&lt;p&gt;接下来，我们需要配置 Giscus 以将评论与我们的仓库关联起来。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;连接仓库&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前往 &lt;a href=&quot;https://giscus.app/zh-CN&quot;&gt;https://giscus.app/zh-CN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;选择语言后在下方填写你的仓库&lt;/li&gt;
&lt;li&gt;通过检查后 Discussion 将被连接到该仓库&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.tianhw.top/_astro/3_Z1VfYN6.webp&quot; alt=&quot;Giscus 仓库配置&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;选择映射关系&lt;/strong&gt; 推荐选择 &lt;code&gt;pathname&lt;/code&gt;，假如你的文章路径为 &lt;code&gt;posts/helloworld&lt;/code&gt;，那么只要你保证这个路径不变，评论和页面就永远匹配&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.tianhw.top/_astro/2_bvJNT.webp&quot; alt=&quot;Giscus 映射配置&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;选择 Discussion 分类&lt;/strong&gt; 推荐使用 &lt;strong&gt;公告（Announcements）&lt;/strong&gt; 类型的分类，以确保新 discussion 只能由仓库维护者和 giscus 创建&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.tianhw.top/_astro/1_2jiuqT.webp&quot; alt=&quot;Giscus 分类配置&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;获取配置信息&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;完成以上步骤后，记录以下配置信息，稍后将在 Fuwari 中使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仓库名称&lt;/li&gt;
&lt;li&gt;仓库 ID&lt;/li&gt;
&lt;li&gt;分类名称&lt;/li&gt;
&lt;li&gt;分类 ID&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;添加到 Fuwari&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;创建 Giscus 组件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为了实现在亮色/暗色下都能使 Giscus 完美显示,我们需要在 &lt;code&gt;src/components&lt;/code&gt; 目录下创建 &lt;code&gt;giscus.astro&lt;/code&gt; 文件，内容如下：&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;interface Props {
  repo: string;
  repoId: string;
  category: string;
  categoryId: string;
  mapping?: string;
  reactionsEnabled?: boolean;
  emitMetadata?: boolean;
  inputPosition?: &apos;top&apos; | &apos;bottom&apos;;
  lang?: string;
}

const {
  repo,
  repoId,
  category,
  categoryId,
  mapping = &apos;pathname&apos;,
  reactionsEnabled = true,
  emitMetadata = false,
  inputPosition = &apos;bottom&apos;,
  lang = &apos;zh-CN&apos;
} = Astro.props;
---

&amp;lt;div id=&quot;giscus-container&quot;&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;script define:vars={{ repo, repoId, category, categoryId, mapping, reactionsEnabled, emitMetadata, inputPosition, lang }}&amp;gt;
  function loadGiscus() {
    const container = document.getElementById(&apos;giscus-container&apos;);
    if (!container) return;

    const isDark = document.documentElement.classList.contains(&apos;dark&apos;);
    const theme = isDark ? &apos;dark&apos; : &apos;light&apos;;

    const script = document.createElement(&apos;script&apos;);
    script.src = &apos;https://giscus.app/client.js&apos;;
    script.setAttribute(&apos;data-repo&apos;, repo);
    script.setAttribute(&apos;data-repo-id&apos;, repoId);
    script.setAttribute(&apos;data-category&apos;, category);
    script.setAttribute(&apos;data-category-id&apos;, categoryId);
    script.setAttribute(&apos;data-mapping&apos;, mapping);
    script.setAttribute(&apos;data-strict&apos;, &apos;0&apos;);
    script.setAttribute(&apos;data-reactions-enabled&apos;, reactionsEnabled ? &apos;1&apos; : &apos;0&apos;);
    script.setAttribute(&apos;data-emit-metadata&apos;, emitMetadata ? &apos;1&apos; : &apos;0&apos;);
    script.setAttribute(&apos;data-input-position&apos;, inputPosition);
    script.setAttribute(&apos;data-theme&apos;, theme);
    script.setAttribute(&apos;data-lang&apos;, lang);
    script.setAttribute(&apos;data-loading&apos;, &apos;lazy&apos;);
    script.crossOrigin = &apos;anonymous&apos;;
    script.async = true;

    container.appendChild(script);
  }

  // 监听主题变化
  function updateGiscusTheme() {
    const giscusFrame = document.querySelector(&apos;iframe[src*=&quot;giscus&quot;]&apos;);
    if (giscusFrame) {
      const isDark = document.documentElement.classList.contains(&apos;dark&apos;);
      const theme = isDark ? &apos;dark&apos; : &apos;light&apos;;

      giscusFrame.contentWindow.postMessage({
        giscus: {
          setConfig: {
            theme: theme
          }
        }
      }, &apos;https://giscus.app&apos;);
    }
  }

  // 监听DOM变化来检测主题切换
  const observer = new MutationObserver((mutations) =&amp;gt; {
    mutations.forEach((mutation) =&amp;gt; {
      if (mutation.type === &apos;attributes&apos; &amp;amp;&amp;amp; mutation.attributeName === &apos;class&apos;) {
        updateGiscusTheme();
      }
    });
  });

  // 页面加载时初始化
  if (document.readyState === &apos;loading&apos;) {
    document.addEventListener(&apos;DOMContentLoaded&apos;, loadGiscus);
  } else {
    loadGiscus();
  }

  // 开始观察主题变化
  observer.observe(document.documentElement, {
    attributes: true,
    attributeFilter: [&apos;class&apos;]
  });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;添加到文章页面&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;src/pages/posts/[...slug].astro&lt;/code&gt; 文件中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首先导入 Giscus 组件：&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;import path from &quot;node:path&quot;;
import License from &quot;@components/misc/License.astro&quot;;
import Markdown from &quot;@components/misc/Markdown.astro&quot;;
import AISummary from &quot;@components/misc/AISummary.astro&quot;;
 import Giscus from &quot;../../components/misc/Giscus.astro&quot;;
import I18nKey from &quot;@i18n/i18nKey&quot;;
import { i18n } from &quot;@i18n/translation&quot;;
import MainGridLayout from &quot;@layouts/MainGridLayout.astro&quot;;
import { getSortedPosts } from &quot;@utils/content-utils&quot;;
import { getDir, getPostUrlBySlug } from &quot;@utils/url-utils&quot;;
import { Icon } from &quot;astro-icon/components&quot;;
import { licenseConfig } from &quot;src/config&quot;;
import ImageWrapper from &quot;../../components/misc/ImageWrapper.astro&quot;;
import PostMetadata from &quot;../../components/PostMeta.astro&quot;;
import { profileConfig, siteConfig } from &quot;../../config&quot;;
import { formatDateToYYYYMMDD } from &quot;../../utils/date-utils&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;然后在许可证组件之后添加 Giscus 组件：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;     &amp;lt;!-- always show cover as long as it has one --&amp;gt;

    {entry.data.image &amp;amp;&amp;amp;
        &amp;lt;ImageWrapper id=&quot;post-cover&quot; src={entry.data.image} basePath={path.join(&quot;content/posts/&quot;, getDir(entry.id))} class=&quot;mb-8 rounded-xl banner-container onload-animation&quot;/&amp;gt;
    }

    &amp;lt;Markdown class=&quot;mb-6 markdown-content onload-animation&quot;&amp;gt;
        &amp;lt;Content /&amp;gt;
    &amp;lt;/Markdown&amp;gt;

    {licenseConfig.enable &amp;amp;&amp;amp; &amp;lt;License title={entry.data.title} slug={entry.slug} pubDate={entry.data.published} class=&quot;mb-6 rounded-xl license-container onload-animation&quot;&amp;gt;&amp;lt;/License&amp;gt;}

   &amp;lt;Giscus
       repo=&quot;username/repo&quot;
       repoId=&quot;&quot;
       category=&quot;Announcements&quot;
       categoryId=&quot;&quot;
   /&amp;gt;
   &amp;lt;br&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;添加到友链页面&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在 &lt;code&gt;src/pages/friends.astro&lt;/code&gt; 文件中：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-   首先导入 Giscus 组件：
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;import { getEntry, render } from &quot;astro:content&quot;;
import Giscus from &quot;@components/misc/Giscus.astro&quot;;
import Markdown from &quot;@components/misc/Markdown.astro&quot;;
import MainGridLayout from &quot;@layouts/MainGridLayout.astro&quot;;
import { Icon } from &quot;astro-icon/components&quot;;
import { siteConfig } from &quot;../config&quot;;
import { friends } from &quot;../friends_data&quot;;

&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;然后在友链卡片组件之后添加 Giscus 组件：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;        &amp;lt;div class=&quot;grid grid-cols-1 md:grid-cols-2 gap-4&quot;&amp;gt;
            {friends.map((friend) =&amp;gt; (
                &amp;lt;a href={friend.url} target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;friend-card&quot;&amp;gt;
                    &amp;lt;div class=&quot;flex items-center gap-2&quot;&amp;gt;
                        &amp;lt;img src={friend.avatar} loading=&quot;lazy&quot; class=&quot;w-5 h-5 rounded&quot; alt={friend.name}&amp;gt;
                        &amp;lt;div class=&quot;font-bold text-black dark:text-white&quot;&amp;gt;{friend.name}&amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;
                    &amp;lt;div class=&quot;text-sm text-black/50 dark:text-white/50&quot;&amp;gt;{friend.description}&amp;lt;/div&amp;gt;
                &amp;lt;/a&amp;gt;
            ))}
        &amp;lt;/div&amp;gt;

        &amp;lt;Giscus
             repo=&quot;worhllo2/Blog-fuwari&quot;
             repoId=&quot;R_kgDOR4xu1A&quot;
             category=&quot;General&quot;
             categoryId=&quot;DIC_kwDOR4xu1M4C58lt&quot;
        /&amp;gt;

        &amp;lt;/div&amp;gt;
&amp;lt;/MainGridLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存文件后重新构建项目即可看到评论区&lt;/p&gt;
&lt;p&gt;通过以上步骤，你就成功为 &lt;strong&gt;Fuwari&lt;/strong&gt; 添加了功能完善的评论系统，！🎉&lt;/p&gt;
&lt;h2&gt;转载说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-giscus/&quot;&gt;为 Fuwari 添加 Giscus 评论系统 - THW&apos;s Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>为 Astro 加上在新标签页打开链接的功能</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-astro-%E5%8A%A0%E4%B8%8A%E5%9C%A8%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5%E6%89%93%E5%BC%80%E9%93%BE%E6%8E%A5%E7%9A%84%E5%8A%9F%E8%83%BD/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-astro-%E5%8A%A0%E4%B8%8A%E5%9C%A8%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5%E6%89%93%E5%BC%80%E9%93%BE%E6%8E%A5%E7%9A%84%E5%8A%9F%E8%83%BD/</guid><description>原版 Astro（包括 Fuwari）中，打开外部链接默认在当前页面。本文教你如何配置 rehype-external-links 插件，让链接自动在新标签页打开。</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在原生的 &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt; 或 &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;Fuwari&lt;/a&gt; 主题中，点击外部链接通常会在当前页面直接打开。这对于需要频繁参考外部文档的教程类文章来说体验并不友好。虽然也能鼠标中键在新标签页打开链接，不过还是挺麻烦的。&lt;/p&gt;
&lt;p&gt;何谓点击连接在新标签页打开，最简单的例子：&lt;a href=&quot;https://www.bing.com/&quot;&gt;打开必应&lt;/a&gt;   |   &lt;a href=&quot;https://www.bing.com/&quot;&gt;在新标签页打开必应&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;两者的区别：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1&amp;lt;a href=&quot;https://www.bing.com&quot;&amp;gt;打开必应&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;1&amp;lt;a href=&quot;https://www.bing.com&quot; target=&quot;_blank&quot;&amp;gt;在新标签页打开必应&amp;lt;/a&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因此，本文将介绍如何使用 &lt;a href=&quot;https://www.npmjs.com/package/rehype-external-links&quot;&gt;rehype-external-links&lt;/a&gt; 插件来完美解决这个问题。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;安装插件&lt;a href=&quot;https://blog.adclosenn.top/posts/newtab_link/#%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;假如你的项目使用的包管理器是 pnpm，那就用 pnpm 的命令安装。npm 同理。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1pnpm i rehype-external-links
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;1npm i rehype-external-links
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装成功后你的 &lt;code&gt;package.json&lt;/code&gt; 中会新增一个类似于 &lt;code&gt;&quot;rehype-external-links&quot;: &quot;^3.0.0&quot;,&lt;/code&gt; 的行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &quot;rehype-components&quot;: &quot;^0.3.0&quot;,
    &quot;rehype-external-links&quot;: &quot;^3.0.0&quot;,
    &quot;rehype-katex&quot;: &quot;^7.0.1&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置插件&lt;a href=&quot;https://blog.adclosenn.top/posts/newtab_link/#%E9%85%8D%E7%BD%AE%E6%8F%92%E4%BB%B6&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在根目录的 &lt;code&gt;astro.config.mjs&lt;/code&gt; 文件内加入以下&lt;strong&gt;5行&lt;/strong&gt;代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;新增的代码在132至137行
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;import sitemap from &quot;@astrojs/sitemap&quot;;
import svelte from &quot;@astrojs/svelte&quot;;
import tailwind from &quot;@astrojs/tailwind&quot;;
import { pluginCollapsibleSections } from &quot;@expressive-code/plugin-collapsible-sections&quot;;
import { pluginLineNumbers } from &quot;@expressive-code/plugin-line-numbers&quot;;
import swup from &quot;@swup/astro&quot;;
import expressiveCode from &quot;astro-expressive-code&quot;;
import icon from &quot;astro-icon&quot;;
import { defineConfig } from &quot;astro/config&quot;;
import rehypeAutolinkHeadings from &quot;rehype-autolink-headings&quot;;
import rehypeComponents from &quot;rehype-components&quot;; /* Render the custom directive content */
import rehypeKatex from &quot;rehype-katex&quot;;
import rehypeSlug from &quot;rehype-slug&quot;;
import remarkDirective from &quot;remark-directive&quot;; /* Handle directives */
import remarkGithubAdmonitionsToDirectives from &quot;remark-github-admonitions-to-directives&quot;;
import remarkMath from &quot;remark-math&quot;;
import remarkSectionize from &quot;remark-sectionize&quot;;
import { expressiveCodeConfig } from &quot;./src/config.ts&quot;;
import { pluginLanguageBadge } from &quot;./src/plugins/expressive-code/language-badge.ts&quot;;
import { AdmonitionComponent } from &quot;./src/plugins/rehype-component-admonition.mjs&quot;;
import { GithubCardComponent } from &quot;./src/plugins/rehype-component-github-card.mjs&quot;;
import { parseDirectiveNode } from &quot;./src/plugins/remark-directive-rehype.js&quot;;
import { remarkExcerpt } from &quot;./src/plugins/remark-excerpt.js&quot;;
import { remarkReadingTime } from &quot;./src/plugins/remark-reading-time.mjs&quot;;
import { pluginCustomCopyButton } from &quot;./src/plugins/expressive-code/custom-copy-button.js&quot;;
import rehypeExternalLinks from &apos;rehype-external-links&apos;;

// https://astro.build/config
export default defineConfig({
  site: &quot;https://adclosenn.top&quot;,
  base: &quot;/&quot;,
  trailingSlash: &quot;always&quot;,
  integrations: [
    tailwind({
      nesting: true,
    }),
    swup({
      theme: false,
      animationClass: &quot;transition-swup-&quot;, // see https://swup.js.org/options/#animationselector
      // the default value `transition-` cause transition delay
      // when the Tailwind class `transition-all` is used
      containers: [&quot;main&quot;, &quot;#toc&quot;],
      smoothScrolling: true,
      cache: true,
      preload: true,
      accessibility: true,
      updateHead: true,
      updateBodyClass: false,
      globalInstance: true,
    }),
    icon({
      include: {
        &quot;preprocess: vitePreprocess(),&quot;: [&quot;*&quot;],
        &quot;fa6-brands&quot;: [&quot;*&quot;],
        &quot;fa6-regular&quot;: [&quot;*&quot;],
        &quot;fa6-solid&quot;: [&quot;*&quot;],
      },
    }),
    expressiveCode({
      themes: [expressiveCodeConfig.theme, expressiveCodeConfig.theme],
      plugins: [
        pluginCollapsibleSections(),
        pluginLineNumbers(),
        pluginLanguageBadge(),
        pluginCustomCopyButton()
      ],
      defaultProps: {
        wrap: true,
        overridesByLang: {
          &apos;shellsession&apos;: {
            showLineNumbers: false,
          },
        },
      },
      styleOverrides: {
        codeBackground: &quot;var(--codeblock-bg)&quot;,
        borderRadius: &quot;0.75rem&quot;,
        borderColor: &quot;none&quot;,
        codeFontSize: &quot;0.875rem&quot;,
        codeFontFamily: &quot;&apos;Cascadia Mono&apos;, &apos;JetBrains Mono&apos;&quot;,
        codeLineHeight: &quot;1.5rem&quot;,
        frames: {
          editorBackground: &quot;var(--codeblock-bg)&quot;,
          terminalBackground: &quot;var(--codeblock-bg)&quot;,
          terminalTitlebarBackground: &quot;var(--codeblock-topbar-bg)&quot;,
          editorTabBarBackground: &quot;var(--codeblock-topbar-bg)&quot;,
          editorActiveTabBackground: &quot;none&quot;,
          editorActiveTabIndicatorBottomColor: &quot;var(--primary)&quot;,
          editorActiveTabIndicatorTopColor: &quot;none&quot;,
          editorTabBarBorderBottomColor: &quot;var(--codeblock-topbar-bg)&quot;,
          terminalTitlebarBorderBottomColor: &quot;none&quot;
        },
        textMarkers: {
          delHue: 0,
          insHue: 180,
          markHue: 250
        }
      },
      frames: {
        showCopyToClipboardButton: false,
      }
    }),
        svelte(),
    sitemap(),
  ],
  markdown: {
    remarkPlugins: [
      remarkMath,
      remarkReadingTime,
      remarkExcerpt,
      remarkGithubAdmonitionsToDirectives,
      remarkDirective,
      remarkSectionize,
      parseDirectiveNode,
    ],
    rehypePlugins: [
      rehypeKatex,
      rehypeSlug,
      [
        rehypeComponents,
        {
          components: {
            github: GithubCardComponent,
            note: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;note&quot;),
            tip: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;tip&quot;),
            important: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;important&quot;),
            caution: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;caution&quot;),
            warning: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;warning&quot;),
          },
        },
      ],
      [
        rehypeExternalLinks,
        {
        target: &apos;_blank&apos;,
        },
      ],
      [
        rehypeAutolinkHeadings,
        {
          behavior: &quot;append&quot;,
          properties: {
            className: [&quot;anchor&quot;],
          },
          content: {
            type: &quot;element&quot;,
            tagName: &quot;span&quot;,
            properties: {
              className: [&quot;anchor-icon&quot;],
              &quot;data-pagefind-ignore&quot;: true,
            },
            children: [
              {
                type: &quot;text&quot;,
                value: &quot;#&quot;,
              },
            ],
          },
        },
      ],
    ],
  },
  vite: {
    build: {
      rollupOptions: {
        onwarn(warning, warn) {
          // temporarily suppress this warning
          if (
            warning.message.includes(&quot;is dynamically imported by&quot;) &amp;amp;&amp;amp;
            warning.message.includes(&quot;but also statically imported by&quot;)
          ) {
            return;
          }
          warn(warning);
        },
      },
    },
  },
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至此，插件的配置就完成了。随便找个&lt;strong&gt;文章内链接&lt;/strong&gt;点击，应该会在&lt;strong&gt;新标签页&lt;/strong&gt;打开，而非原来的在当页打开。&lt;/p&gt;
</content:encoded></item><item><title>常见电脑架构与软件选择指南</title><link>https://fuwari.vercel.app/posts/x86_64%E5%92%8Camd64%E5%92%8Carm64%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85%E6%A5%9A/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/x86_64%E5%92%8Camd64%E5%92%8Carm64%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85%E6%A5%9A/</guid><description>本文整理了 x86_64、amd64、arm64 等常见电脑架构的定义、区分方法及等价关系，帮助用户在下载软件时选择正确的安装包版本。</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 什么是指令集？&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;指令集（Instruction Set）&lt;/strong&gt; 是软件与硬件之间的“翻译官”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心作用&lt;/strong&gt;：它定义了 CPU 可以执行的基本操作（如加法、读取内存等）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;兼容性&lt;/strong&gt;：操作系统和应用软件必须针对特定的指令集进行编写。如果架构不匹配，软件将无法运行。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 如何查看自己电脑的架构？&lt;/h2&gt;
&lt;p&gt;在 GitHub 或官网下载软件时，常会看到 &lt;code&gt;x64&lt;/code&gt;、&lt;code&gt;arm64&lt;/code&gt; 等后缀。你可以通过以下方法确认自己的设备类型：&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Windows 用户&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;按下 &lt;code&gt;Win + R&lt;/code&gt;，输入 &lt;code&gt;msinfo32&lt;/code&gt; 并回车。&lt;/li&gt;
&lt;li&gt;在“系统摘要”中找到 &lt;strong&gt;“系统类型”&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;显示 &lt;code&gt;x64-based PC&lt;/code&gt; 即为 &lt;strong&gt;x86_64&lt;/strong&gt; 架构。&lt;/li&gt;
&lt;li&gt;显示 &lt;code&gt;ARM64-based PC&lt;/code&gt; 即为 &lt;strong&gt;ARM&lt;/strong&gt; 架构（常见于 Surface Pro 9 ARM 版等）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&lt;strong&gt;macOS 用户&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;点击左上角  图标 &amp;gt; &lt;strong&gt;“关于本机”&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;查看 &lt;strong&gt;“芯片”&lt;/strong&gt; 或 &lt;strong&gt;“处理器”&lt;/strong&gt; 栏：
&lt;ul&gt;
&lt;li&gt;若显示 &lt;code&gt;Apple M1/M2/M3&lt;/code&gt;，则为 &lt;strong&gt;arm64&lt;/strong&gt; 架构。&lt;/li&gt;
&lt;li&gt;若显示 &lt;code&gt;Intel Core i5/i7&lt;/code&gt;，则为 &lt;strong&gt;x86_64&lt;/strong&gt; 架构。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;&lt;strong&gt;Linux / 服务器用户&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在终端输入以下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;lscpu
# 或者
uname -m
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;输出 &lt;code&gt;x86_64&lt;/code&gt; 表示 64 位 Intel/AMD 架构。&lt;/li&gt;
&lt;li&gt;输出 &lt;code&gt;aarch64&lt;/code&gt; 表示 64 位 ARM 架构。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 架构名称等价关系清单&lt;/h2&gt;
&lt;p&gt;下载软件时，请根据下表寻找对应的版本。同一行内的名称通常是&lt;strong&gt;兼容或等效&lt;/strong&gt;的：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类别&lt;/th&gt;
&lt;th&gt;常见名称 (等价/兼容)&lt;/th&gt;
&lt;th&gt;适用设备&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;现代 PC 主流&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;x86_64&lt;/strong&gt;, x64, amd64&lt;/td&gt;
&lt;td&gt;绝大多数 Intel/AMD 处理器的电脑、服务器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;现代移动/新型 Mac&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;arm64&lt;/strong&gt;, aarch64, ARMv8&lt;/td&gt;
&lt;td&gt;iPhone、安卓手机、Apple Silicon (M系列) Mac&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;老旧/嵌入式 ARM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;armv7l, armhf, arm&lt;/td&gt;
&lt;td&gt;旧款树莓派、早期安卓设备&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;淘汰边缘 (32位)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;x86, i386, i686&lt;/td&gt;
&lt;td&gt;2010年以前的老旧电脑&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 常见安装包格式补充&lt;/h2&gt;
&lt;p&gt;除了架构名，后缀名也决定了能否安装：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;.exe / .msi&lt;/strong&gt;：Windows 专用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.dmg / .pkg&lt;/strong&gt;：macOS 专用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.deb / .rpm&lt;/strong&gt;：Linux 专用（如 Ubuntu/CentOS）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.AppImage / .sh&lt;/strong&gt;：Linux 通用便携格式。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;参考说明&lt;/strong&gt;：本文部分内容参考自 &lt;a href=&quot;https://blog.csdn.net/xxx&quot;&gt;x86_64和AMD64和ARM64？傻傻分不清楚？&lt;/a&gt;（此处为原博文参考意图）。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Markdown 编辑器如何修改图片大小</title><link>https://fuwari.vercel.app/posts/markdown%E7%B3%BB%E5%88%97markdown-%E7%BC%96%E8%BE%91%E5%99%A8%E5%A6%82%E4%BD%95%E4%BF%AE%E6%94%B9%E5%9B%BE%E7%89%87%E5%A4%A7%E5%B0%8F/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/markdown%E7%B3%BB%E5%88%97markdown-%E7%BC%96%E8%BE%91%E5%99%A8%E5%A6%82%E4%BD%95%E4%BF%AE%E6%94%B9%E5%9B%BE%E7%89%87%E5%A4%A7%E5%B0%8F/</guid><description>本文详细介绍了在 Markdown 中调整图片尺寸的三种实用方法：使用 HTML 标签、添加 CSS 样式后缀以及通过全局 Style 统一控制。</description><pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;方法一、嵌入HTML代码&lt;/h2&gt;
&lt;h3&gt;1.1 使用 &lt;strong&gt;img标签&lt;/strong&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;img src=&quot;./xxx.png&quot; width = &quot;300&quot; height = &quot;200&quot; alt=&quot;图片名称&quot; align=center /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.2 如果需要居中的话只要在外面包围&lt;strong&gt;div标签&lt;/strong&gt;即可&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div align=&quot;center&quot;&amp;gt; ... &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;方法二、直接在图片后面加上对应的&lt;strong&gt;CSS样式&lt;/strong&gt;即可&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;![test image size](url){:class=&quot;img-responsive&quot;}
![test image size](url){:height=&quot;50%&quot; width=&quot;50%&quot;}
![test image size](url){:height=&quot;100px&quot; width=&quot;400px&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;方法三、一劳永逸通用思路&lt;/h2&gt;
&lt;p&gt;在文章头部添加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;style&amp;gt;
img{
    width: 60%;
    padding-left: 20%;
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个对文章所有图片都有效，如果图片尺寸标准差异过大，建议还是用单独的&amp;lt;img&amp;gt;标签来定义。&lt;/p&gt;
</content:encoded></item><item><title>如何在 Fuwari 博客页脚添加 ICP 备案及运行时间</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%9C%A8-fuwari-%E5%8D%9A%E5%AE%A2%E9%A1%B5%E8%84%9A%E6%B7%BB%E5%8A%A0-icp-%E5%A4%87%E6%A1%88%E5%8F%8A%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%9C%A8-fuwari-%E5%8D%9A%E5%AE%A2%E9%A1%B5%E8%84%9A%E6%B7%BB%E5%8A%A0-icp-%E5%A4%87%E6%A1%88%E5%8F%8A%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4/</guid><description>本教程详细介绍了如何通过修改 src/components/Footer.astro 文件，为 Fuwari 主题添加自定义页脚信息，包括网站运行时间 JS 脚本、ICP 备案链接以及又拍云等赞助标识。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;架构&lt;/h2&gt;
&lt;p&gt;其核心逻辑是：&lt;strong&gt;在页脚组件中通过 HTML 结构承载内容，利用 CSS 进行样式美化，并配合 JavaScript 实现动态的时间计算。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;1. 结构层 (HTML/Astro Component)&lt;/h3&gt;
&lt;p&gt;Fuwari 是基于 Astro 框架构建的，页脚逻辑位于 &lt;code&gt;src/components/Footer.astro&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ICP 备案：&lt;/strong&gt; 通常在页脚的 &lt;code&gt;div&lt;/code&gt; 容器内添加一个新的 &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; 或 &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; 标签。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;架构要点：&lt;/strong&gt; 必须包含指向工信部官网的超链接（&lt;code&gt;href=&quot;https://beian.miit.gov.cn/&quot;&lt;/code&gt;），这是合规性的基本要求。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;运行时间：&lt;/strong&gt; 添加一个带有特定 &lt;code&gt;id&lt;/code&gt;（如 &lt;code&gt;runtime_span&lt;/code&gt;）的占位容器，用于后续脚本动态填充内容。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 逻辑层 (JavaScript)&lt;/h3&gt;
&lt;p&gt;由于“运行时间”需要实时更新（或在页面加载时计算），需要在 &lt;code&gt;.astro&lt;/code&gt; 文件的 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 标签内编写逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;起始时间设定：&lt;/strong&gt; 定义一个初始化的 &lt;code&gt;Date&lt;/code&gt; 对象作为建站日期。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;计算函数：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;获取当前时间：&lt;code&gt;new Date()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;计算差值：$t2 - t1$。&lt;/li&gt;
&lt;li&gt;单位转换：通过数学运算将毫秒差值转换为 &lt;strong&gt;天、时、分、秒&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定时更新：&lt;/strong&gt; 使用 &lt;code&gt;setInterval(update_function, 1000)&lt;/code&gt; 每秒刷新一次 DOM 内容，确保时间是“跳动”的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 表现层 (CSS/Tailwind)&lt;/h3&gt;
&lt;p&gt;Fuwari 默认使用 Tailwind CSS。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;布局控制：&lt;/strong&gt; 备案号与运行时间通常使用 &lt;code&gt;flex&lt;/code&gt; 布局或简单的换行符进行排列，以确保在移动端和桌面端都能居中对齐。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;样式细节：&lt;/strong&gt; 通过类名（如 &lt;code&gt;text-sm&lt;/code&gt;, &lt;code&gt;opacity-70&lt;/code&gt;）调整字体大小和透明度，使其与原主题的极简风格保持一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;总结架构流程图&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;步骤&lt;/th&gt;
&lt;th&gt;涉及文件&lt;/th&gt;
&lt;th&gt;核心动作&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;定位&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Footer.astro&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;找到页脚的 HTML 渲染区域&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;注入&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;HTML 标签&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;写入备案号文本和运行时间占位符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;计算&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;编写 JS 逻辑处理时间戳差值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;渲染&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DOM 操作&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;innerText&lt;/code&gt; 将结果填充进占位符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;优化&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Tailwind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;调整边距、颜色和响应式显示&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;实操&lt;/h2&gt;
&lt;p&gt;找到 &lt;code&gt;src/components/Footer.astro&lt;/code&gt; 这个文件&lt;br /&gt;
你会发现页脚的rss以及sitemap都在这里&lt;br /&gt;
直接复制rss的模板，填写好你想要添加的信息后复制在后面&lt;br /&gt;
当然，不需要rss/sitemap，以及powered by的也可以直接在此删除&lt;/p&gt;
&lt;p&gt;:::note
注意在添加跳转链接时&lt;br /&gt;
记得把href={&lt;code&gt;url(&lt;/code&gt;’xxxx’&lt;code&gt;)&lt;/code&gt;}&lt;br /&gt;
的url等删除，否则跳转链接前会自带你设置的站点网址&lt;br /&gt;
当然删除与否根据你的需求来判断
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import { profileConfig } from &apos;../config&apos;
import { url } from &apos;../utils/url-utils&apos;
---

&amp;lt;div class=&quot;card-base max-w-[var(--page-width)] min-h-[4.5rem] rounded-b-none mx-auto flex items-center px-6 justify-between&quot;&amp;gt;

&amp;lt;!--左侧信息 --&amp;gt;
    &amp;lt;div class=&quot;transition text-50 text-sm max-md:text-left mt-2&quot;&amp;gt;
        © 2024 {profileConfig.name}. All Rights Reserved. /
        &amp;lt;a class=&quot;link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href={url(&apos;rss.xml&apos;)}&amp;gt;RSS&amp;lt;/a&amp;gt;
    &amp;lt;!--
        &amp;lt;a class=&quot;link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href={url(&apos;sitemap-index.xml&apos;)}&amp;gt;Sitemap&amp;lt;/a&amp;gt;
    --&amp;gt;
        &amp;lt;br&amp;gt;
        Powered by
        &amp;lt;a class=&quot;link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href=&quot;https://astro.build&quot;&amp;gt;Astro&amp;lt;/a&amp;gt; &amp;amp;
        &amp;lt;a class=&quot;link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href=&quot;https://github.com/saicaca/fuwari&quot;&amp;gt;Fuwari&amp;lt;/a&amp;gt; &amp;amp;
        &amp;lt;a class=&quot;link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href=&quot;https://www.upyun.com/?utm_source=lianmeng&amp;amp;utm_medium=referral&quot;&amp;gt;又拍云CDN&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;

&amp;lt;!--运行时间 --&amp;gt;
    &amp;lt;script type=&quot;text/javascript&quot;&amp;gt;function runtime(){const t=new Date(&quot;09/01/2024 08:00:00&quot;),n=new Date,s=n-t,e=Math.floor(s/1e3),o=Math.floor(e/86400),i=Math.floor(e%86400/3600),a=Math.floor(e%3600/60),r=e%60;document.getElementById(&quot;runningtime&quot;).innerHTML=`⭐本站已运行: ${o}天${i}小时${a}分${r}秒 ☁️`}setInterval(runtime,1e3)&amp;lt;/script&amp;gt;
    &amp;lt;div class=&quot;transition text-50 text-sm text-center hidden md:block&quot;&amp;gt;&amp;lt;p id=&quot;runningtime&quot;&amp;gt; &amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;!--右侧备案等信息 --&amp;gt;
    &amp;lt;div class=&quot;transition text-50 text-sm max-md:text-right mt-2&quot;&amp;gt;
        &amp;lt;a class=&quot;link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href={&apos;https://beian.miit.gov.cn&apos;}&amp;gt;xICP备xxxxxxxxxx号&amp;lt;/a&amp;gt;
        &amp;lt;br&amp;gt;
        &amp;lt;a class=&quot;link text-[var(--primary)] font-medium&quot; target=&quot;_blank&quot; href={&apos;https://icp.gov.moe/?keyword=20245060&apos;}&amp;gt;萌ICP备20245060号&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;⚠️ 常见问题：构建失败 (expand-animation)&lt;/h2&gt;
&lt;p&gt;如果在部署到 Cloudflare Pages 或进行 Vite 构建时遇到类似以下的错误：
&lt;code&gt;[postcss] /src/styles/markdown.css:23:9: The expand-animation class does not exist.&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;错误原因&lt;/h3&gt;
&lt;p&gt;这是因为 Fuwari 主题在 &lt;code&gt;markdown.css&lt;/code&gt; 中使用了 Tailwind 的 &lt;code&gt;@apply&lt;/code&gt; 指令来引用 &lt;code&gt;expand-animation&lt;/code&gt; 类，但该类定义在 &lt;code&gt;main.css&lt;/code&gt; 中。在某些构建环境下，PostCSS 无法跨文件识别非原生的 Tailwind 类。&lt;/p&gt;
&lt;h3&gt;解决方案&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;src/styles/markdown.css&lt;/code&gt; 文件的顶部（不要放在任何大括号内），手动添加该类的定义：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.expand-animation {
    @apply relative before:ease-out before:transition active:bg-none hover:before:bg-[var(--btn-plain-bg-hover)] active:before:bg-[var(--btn-plain-bg-active)] z-0
    before:absolute before:rounded-[inherit] before:inset-0 before:scale-[0.85] hover:before:scale-100 before:-z-10;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：不要在外面包裹 &lt;code&gt;@layer components&lt;/code&gt;，除非你在该文件顶部也引入了 &lt;code&gt;@tailwind components&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;💡 转载说明&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本文转载自：&lt;/strong&gt; &lt;a href=&quot;https://aulypc1.github.io/&quot;&gt;AULyPc 的博客&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;原文作者：&lt;/strong&gt; &lt;a href=&quot;https://aulypc1.github.io/about/&quot;&gt;AULyPc&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;原文标题：&lt;/strong&gt; 《如何在Fuwari页脚添加ICP、运行时间等信息》&lt;br /&gt;
&lt;strong&gt;原文链接：&lt;/strong&gt; &lt;a href=&quot;https://aulypc1.github.io/posts/website/add_icpruntime_in_fuwari-footer/&quot;&gt;https://aulypc1.github.io/posts/website/add_icpruntime_in_fuwari-footer/&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;许可协议：&lt;/strong&gt; 本文采用 &lt;a href=&quot;https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans&quot;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 许可协议，转载请注明出处。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title> 为Fuwari博客配置SEO </title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BAfuwari%E5%8D%9A%E5%AE%A2%E9%85%8D%E7%BD%AEseo-/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BAfuwari%E5%8D%9A%E5%AE%A2%E9%85%8D%E7%BD%AEseo-/</guid><description>本文详细介绍了 SEO 的基本概念、搜索引擎的工作原理，并针对 Fuwari 主题提供了具体的 TDK 优化、sitemap 配置及爬虫提交建议。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;一、SEO 配置前的准备工作&lt;/h2&gt;
&lt;p&gt;良好的 SEO 不仅有助于搜索引擎收录，也能提升社交平台分享时的预览效果。我们将从三部分入手：布局文件修改、类型定义扩展和站点配置完善。&lt;/p&gt;
&lt;h3&gt;1. 修改布局文件：&lt;code&gt;src/layouts/Layout.astro&lt;/code&gt;&lt;a href=&quot;https://blog.7003410.xyz/posts/seo/#1-%E4%BF%AE%E6%94%B9%E5%B8%83%E5%B1%80%E6%96%87%E4%BB%B6srclayoutslayoutastro&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;首先，我们需要在全局布局组件中添加关键的元信息（meta tags），确保每一页都能正确输出 SEO 数据。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE&lt;/p&gt;
&lt;p&gt;感谢ChuwuYo的宝贵建议。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang={siteLang} class=&quot;bg-[var(--page-bg)] transition text-[14px] md:text-[16px]&quot;
      data-overlayscrollbars-initialize&amp;gt;
  &amp;lt;head&amp;gt;
   &amp;lt;title&amp;gt;{pageTitle}&amp;lt;/title&amp;gt;

    &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
    &amp;lt;meta name=&quot;description&quot; content={description || siteConfig.description}&amp;gt; &amp;lt;!-- 更改 --&amp;gt;
    &amp;lt;meta name=&quot;author&quot; content={profileConfig.name}&amp;gt;

    &amp;lt;meta property=&quot;og:site_name&quot; content={siteConfig.title}&amp;gt;
    &amp;lt;meta property=&quot;og:url&quot; content={Astro.url}&amp;gt;
    &amp;lt;meta property=&quot;og:title&quot; content={pageTitle}&amp;gt;
    &amp;lt;meta property=&quot;og:description&quot; content={description || pageTitle}&amp;gt;
    {setOGTypeArticle ? (
        &amp;lt;meta property=&quot;og:type&quot; content=&quot;article&quot; /&amp;gt;
        ) : (
        &amp;lt;meta property=&quot;og:type&quot; content=&quot;website&quot; /&amp;gt;
        )}

    &amp;lt;meta name=&quot;description&quot; content={description || pageTitle}&amp;gt;  &amp;lt;!-- 新增 --&amp;gt;
    &amp;lt;meta name=&quot;twitter:card&quot; content=&quot;summary_large_image&quot;&amp;gt;
    &amp;lt;meta property=&quot;twitter:url&quot; content={Astro.url}&amp;gt;
    &amp;lt;meta name=&quot;twitter:title&quot; content={pageTitle}&amp;gt;
    &amp;lt;meta name=&quot;twitter:description&quot; content={description || pageTitle}&amp;gt;

    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width&quot; /&amp;gt;
    &amp;lt;meta name=&quot;generator&quot; content={Astro.generator} /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;...&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;2. 扩展类型定义：&lt;code&gt;src/types/config.ts&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;为了使 TypeScript 正确识别新增字段，我们需要在 &lt;code&gt;SiteConfig&lt;/code&gt; 类型中添加 &lt;code&gt;keywords&lt;/code&gt; 和 &lt;code&gt;description&lt;/code&gt; 字段。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import type { AUTO_MODE, DARK_MODE, LIGHT_MODE } from &quot;@constants/constants&quot;;

export type Favicon = {
  src: string;
  theme?: &quot;light&quot; | &quot;dark&quot;;
  sizes?: string;
};

export type SiteConfig = {
  title: string;
  subtitle: string;

  lang: string;
  keywords: string;        // 新增：SEO 关键词
  description: string;     // 新增：站点描述

  themeColor: {
    hue: number;
    fixed: boolean;
  };

  banner: {
    enable: boolean;
    src: string;
    position?: &quot;top&quot; | &quot;center&quot; | &quot;bottom&quot;;
    credit: {
      enable: boolean;
      text: string;
      url?: string;
    };
  };

  toc: {
    enable: boolean;
    depth: 1 | 2 | 3;
  };

  favicon: Favicon[];
};
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;3. 配置站点信息：&lt;code&gt;src/config.ts&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;最后，在实际配置文件中填入有意义的 SEO 内容，让搜索引擎和用户都能清晰了解你的博客定位。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const siteConfig: SiteConfig = {
  title: &quot;晓正杨博客&quot;,
  subtitle: &quot;分享技术内容&quot;,

  lang: &quot;zh_CN&quot;, // 支持 &apos;en&apos;, &apos;zh_CN&apos;, &apos;zh_TW&apos;, &apos;ja&apos;, &apos;ko&apos;, &apos;es&apos;, &apos;th&apos; 等语言
  keywords: &quot;前端开发, 游戏开发, 技术分享, JavaScript, Astro, 博客搭建&quot;,
  description: &quot;晓正杨的技术笔记与思考，专注前端与游戏开发领域，记录学习与实践心得。&quot;,

  themeColor: {
    hue: 250, // 色调值（0–360），如蓝色系
    fixed: false, // 是否禁用主题色切换
  },

  banner: {
    enable: false,
    src: &quot;&quot;,
    position: &quot;center&quot;,
    credit: {
      enable: false,
      text: &quot;&quot;,
      url: &quot;&quot;,
    },
  },

  toc: {
    enable: true,
    depth: 2,
  },

  favicon: [
    {
      src: &apos;https://q1.qlogo.cn/g?b=qq&amp;amp;nk=2540797494&amp;amp;s=640&apos;,
      theme: &apos;light&apos;,
      sizes: &apos;32x32&apos;,
    },
    // 可添加暗色模式专用图标
    // {
    //   src: &apos;/favicons/dark-favicon.png&apos;,
    //   theme: &apos;dark&apos;,
    //   sizes: &apos;32x32&apos;
    // }
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;✅ &lt;strong&gt;建议&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;keywords&lt;/code&gt; 应包含核心主题词，用英文逗号分隔，避免堆砌。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description&lt;/code&gt; 是搜索引擎结果页中显示的摘要，应简洁有力，控制在 80–160 字符以内。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;favicon&lt;/code&gt; 推荐使用多种尺寸和主题适配，提升品牌识别度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;二、接入必应网站管理员&lt;/h2&gt;
&lt;p&gt;在搜索引擎中，必应（Bing）是仅次于谷歌（Google）的全球第二大搜索引擎，拥有庞大的用户群体。&lt;/p&gt;
&lt;p&gt;为了提升 SEO 效果，我们还需要在必应中注册网站管理员，让搜索引擎能更准确地理解我们的网站。&lt;/p&gt;
&lt;p&gt;访问 &lt;a href=&quot;https://www.bing.com/webmasters&quot;&gt;必应站长工具&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;按照提示操作即可，无需额外配置。&lt;/p&gt;
&lt;h2&gt;三、接入Google Search Console&lt;a href=&quot;https://blog.7003410.xyz/posts/seo/#%E4%B8%89%E6%8E%A5%E5%85%A5google-search-console&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Google Search Console 是 Google 提供的免费网站管理工具，用于帮助网站管理员监控、维护和提升其网站在 Google 搜索中的表现。&lt;/p&gt;
&lt;p&gt;访问 &lt;a href=&quot;https://search.google.com/search-console&quot;&gt;Google Search Console&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;按照提示操作即可，无需额外配置。&lt;/p&gt;
&lt;h2&gt;特别提醒&lt;/h2&gt;
&lt;p&gt;千万不要用&lt;strong&gt;免费域名&lt;/strong&gt;,千万不要用&lt;strong&gt;免费域名&lt;/strong&gt;,千万不要用&lt;strong&gt;免费域名&lt;/strong&gt;,别问我是怎么知道(说多了都是泪)&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;转载说明&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;文章信息&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;标题&lt;/strong&gt;：SEO 基础入门与 Fuwari 主题优化指南&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作者&lt;/strong&gt;：晓正杨&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;来源&lt;/strong&gt;：&lt;a href=&quot;https://blog.7003410.xyz/&quot;&gt;晓正杨博客&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原文地址&lt;/strong&gt;：https://blog.7003410.xyz/posts/seo/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;注：本文由本人整理转载，旨在技术交流分享，所有权利归原作者所有。&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
</content:encoded></item><item><title>在 Fuwari 中添加 “随机一篇文章” 功能</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E4%B8%AD%E6%B7%BB%E5%8A%A0-%E9%9A%8F%E6%9C%BA%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0-%E5%8A%9F%E8%83%BD---pinpe-%E7%9A%84%E4%BA%91%E7%AB%AF/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E4%B8%AD%E6%B7%BB%E5%8A%A0-%E9%9A%8F%E6%9C%BA%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0-%E5%8A%9F%E8%83%BD---pinpe-%E7%9A%84%E4%BA%91%E7%AB%AF/</guid><description>本教程介绍如何在 Fuwari 博客中添加一个置顶的随机文章卡片，通过 Astro 组件和客户端脚本实现自动跳转，提升旧文章的曝光率</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;话不多说，立马开整&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://pinpe.top/_astro/img.Pv7aXBVG_Z1bSRMR.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;部署前，请先阅读以下事项&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;因为本博客的历史原因，仅随机带标签的文章，忽略没有标签的文章，如果要去除此特性，需要修改以下代码：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;if (isHomePage) {
  const posts = await getCollection(&apos;posts&apos;);
  postUrls = posts
    .filter(p =&amp;gt; !p.data.draft &amp;amp;&amp;amp; p.data.tags.length &amp;gt; 0)
    .map(p =&amp;gt; getPostUrlBySlug(p.slug));
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;包含此组件的页面在进行过渡动画时可能有轻微的抽搐、卡顿感，原因未知。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2&gt;第一步：创建组件&lt;a href=&quot;https://pinpe.top/posts/random-post/#%E7%AC%AC%E4%B8%80%E6%AD%A5%E5%88%9B%E5%BB%BA%E7%BB%84%E4%BB%B6&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在&lt;code&gt;src/components&lt;/code&gt;中，创建文件&lt;code&gt;RandomPostCard.astro&lt;/code&gt;，并且写入以下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import { getCollection } from &apos;astro:content&apos;;
import { getPostUrlBySlug } from &apos;../utils/url-utils&apos;;
import { Icon } from &apos;astro-icon/components&apos;;

// 1. 先判断当前页面是否为首页（仅主页执行后续逻辑）
const isHomePage = Astro.url.pathname === &apos;/&apos;;
let postUrls = [];

// 2. 仅主页获取文章 URL（非主页跳过，减少无效计算）
if (isHomePage) {
  const posts = await getCollection(&apos;posts&apos;);
  postUrls = posts
    .filter(p =&amp;gt; !p.data.draft &amp;amp;&amp;amp; p.data.tags.length &amp;gt; 0)
    .map(p =&amp;gt; getPostUrlBySlug(p.slug));
}
---

{/* 3. 核心条件：仅当是首页时，才渲染整个组件 */}
{isHomePage &amp;amp;&amp;amp; (
  &amp;lt;&amp;gt;
    {postUrls.length &amp;gt; 0 ? (
      &amp;lt;!-- 外层容器：添加 ID 对应样式，确保在 Swup 容器内 --&amp;gt;
      &amp;lt;div
        id=&quot;random-post-card&quot;
        class=&quot;card-base flex flex-col w-full rounded-[var(--radius-large)] overflow-hidden relative onload-animation &quot; 
        style=&quot;animation-delay: calc(var(--content-delay) + 0ms);&quot;
        data-post-urls={JSON.stringify(postUrls)}
      &amp;gt;
        &amp;lt;!-- 标题区域链接 --&amp;gt;
        &amp;lt;div class=&quot;pl-6 md:pl-9 pr-6 md:pr-2 pt-6 md:pt-7 pb-6 relative w-full&quot;&amp;gt;
          &amp;lt;a 
            href=&quot;#&quot; 
            class=&quot;random-post-link transition group w-full block font-bold text-2xl text-90
            hover:text-[var(--primary)] dark:hover:text-[var(--primary)]
            active:text-[var(--title-active)] dark:active:text-[var(--title-active)] md:before:block&quot;
            style=&quot;text-align: left;&quot;
            aria-label=&quot;随机文章&quot;
          &amp;gt;
            随机一篇文章
            &amp;lt;Icon class=&quot;inline text-[2rem] text-[var(--primary)] md:hidden translate-y-0.5 absolute bottom-7&quot; name=&quot;material-symbols:chevron-right-rounded&quot; /&amp;gt;
            &amp;lt;Icon class=&quot;text-[var(--primary)] text-[2rem] transition hidden md:inline absolute translate-y-0.5 opacity-0 group-hover:opacity-100 -translate-x-1 group-hover:translate-x-0 bottom-7&quot; name=&quot;material-symbols:chevron-right-rounded&quot; /&amp;gt;
          &amp;lt;/a&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;!-- 右上角跳转按钮 --&amp;gt;
        &amp;lt;a 
          href=&quot;#&quot; 
          class=&quot;random-post-link !hidden md:!flex btn-regular w-[3.25rem] absolute right-3 top-3 bottom-3 rounded-xl bg-[var(--enter-btn-bg)] hover:bg-[var(--enter-btn-bg-hover)] active:bg-[var(--enter-btn-bg-active)] active:scale-95&quot;
          style=&quot;--coverWidth: 28%;&quot;
          aria-label=&quot;进入随机文章&quot;
        &amp;gt;
          &amp;lt;Icon name=&quot;material-symbols:chevron-right-rounded&quot; class=&quot;transition text-[var(--primary)] text-4xl mx-auto&quot; /&amp;gt;
        &amp;lt;/a&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&quot;transition border-t-[1px] border-dashed mx-6 border-black/10 dark:border-white/[0.15] last:border-t-0 md:hidden&quot;&amp;gt;&amp;lt;/div&amp;gt;
    ) : (
      &amp;lt;p class=&quot;text-center py-6&quot;&amp;gt;没有可用的文章&amp;lt;/p&amp;gt;
    )}

    &amp;lt;!-- 4. 脚本逻辑：仅主页加载（随组件一起被条件包裹） --&amp;gt;
    &amp;lt;script is:inline&amp;gt;
      (function() {
        try {
          const container = document.querySelector(&apos;[data-post-urls]&apos;);
          if (!container) throw new Error(&apos;未找到文章 URL 容器&apos;);

          // 解析文章 URL 列表
          const postUrls = JSON.parse(container.dataset.postUrls || &apos;[]&apos;);
          if (!Array.isArray(postUrls) || postUrls.length === 0) throw new Error(&apos;无有效文章 URL&apos;);

          // 生成随机 URL（保留原有路径处理逻辑）
          const randomIndex = Math.floor(Math.random() * postUrls.length);
          let randomUrl = postUrls[randomIndex];
          if (randomUrl &amp;amp;&amp;amp; typeof randomUrl === &apos;string&apos;) {
            if (!randomUrl.startsWith(&apos;/&apos;) &amp;amp;&amp;amp; !randomUrl.startsWith(&apos;http&apos;)) {
              randomUrl = &apos;/&apos; + randomUrl;
            }
          } else {
            throw new Error(`无效 URL 格式: ${randomUrl}`);
          }

          // 仅设置 href，不阻止默认行为（Swup 会自动拦截链接）
          const links = document.querySelectorAll(&apos;.random-post-link&apos;);
          if (links.length === 0) throw new Error(&apos;未找到随机文章链接&apos;);

          links.forEach(link =&amp;gt; {
            link.href = randomUrl; // 确保 href 正确
            link.addEventListener(&apos;click&apos;, function() {
              console.log(&apos;跳转到随机文章:&apos;, randomUrl);
            });
          });

          console.log(&apos;随机文章链接初始化成功，URL:&apos;, randomUrl);
        } catch (error) {
          console.error(&apos;随机文章功能异常:&apos;, error);
          // 异常时确保链接可正常跳转（降级处理）
          document.querySelectorAll(&apos;.random-post-link&apos;).forEach(link =&amp;gt; {
            link.href = &apos;/&apos;; // 跳转到首页（可自定义降级路径）
          });
        }
      })();
    &amp;lt;/script&amp;gt;
  &amp;lt;/&amp;gt;
)}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第二步：使组件生效&lt;a href=&quot;https://pinpe.top/posts/random-post/#%E7%AC%AC%E4%BA%8C%E6%AD%A5%E4%BD%BF%E7%BB%84%E4%BB%B6%E7%94%9F%E6%95%88&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;打开&lt;code&gt;src/components/PostPage.astro&lt;/code&gt;文件，按照注释说明导入并激活组件，重点分别在第&lt;code&gt;4&lt;/code&gt;和第&lt;code&gt;13&lt;/code&gt;行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import { getPostUrlBySlug } from &apos;@utils/url-utils&apos;
import PostCard from &apos;./PostCard.astro&apos;
import RandomPostCard from &apos;./RandomPostCard.astro&apos; //导入组件
const { page } = Astro.props

let delay = 0
const interval = 50
---

&amp;lt;div class=&quot;transition flex flex-col rounded-[var(--radius-large)] bg-[var(--card-bg)] py-1 md:py-0 md:bg-transparent md:gap-4 mb-4&quot;&amp;gt;
    &amp;lt;!-- 激活组件 --&amp;gt;
    &amp;lt;RandomPostCard /&amp;gt;
    {page.data.map((entry, i) =&amp;gt; (
        &amp;lt;PostCard
            entry={entry}
            title={entry.data.title}
            tags={entry.data.tags}
            category={entry.data.category}
            published={entry.data.published}
            updated={entry.data.updated}
            url={getPostUrlBySlug(entry.slug)}
            image={entry.data.image}
            description={entry.data.description}
            draft={entry.data.draft}
            class:list=&quot;onload-animation&quot;
            style={`animation-delay: calc(var(--content-delay) + ${(i+1) * interval}ms);`}
        /&amp;gt;
    ))}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>如何为 Fuwari 博客添加一个精美的“友情链接”页面</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E4%B8%AD%E6%B7%BB%E5%8A%A0%E5%8F%8B%E9%93%BE%E5%8A%9F%E8%83%BD/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E4%B8%AD%E6%B7%BB%E5%8A%A0%E5%8F%8B%E9%93%BE%E5%8A%9F%E8%83%BD/</guid><description>深入分析 Fuwari 博客的友链实现架构，手把手教你如何通过数据层、内容层与渲染层的分离设计，快速构建一个支持暗色模式且易于维 护的友链页面。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在 Fuwari 这种基于 Astro
架构的现代博客主题中，实现一个既美观又易于维护的“友情链接”页面，需要遵循其“数据与表现分离”的设计哲学。本文将
带你拆解其架构，并手把手教你如何完成配置。&lt;/p&gt;
&lt;h2&gt;架构核心概念&lt;/h2&gt;
&lt;p&gt;Fuwari 的友链功能由三个层次组成，这种设计确保了极高的加载性能和代码可维护性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;数据层 (src/friends_data.ts)：使用 TypeScript 数组管理具体的友链名单，确保类型安全。&lt;/li&gt;
&lt;li&gt;内容层 (src/content/spec/friends.md)：利用 Astro 的 Content Collections
管理页面的静态文字（如申请规则）。&lt;/li&gt;
&lt;li&gt;渲染层 (src/pages/friends.astro)：负责将上述两者结合，并应用响应式布局和暗色模式样式。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;实施步骤&lt;/h2&gt;
&lt;h3&gt;第一步：定义友链数据&lt;/h3&gt;
&lt;p&gt;在 src/ 目录下创建或编辑 friends_data.ts。我们将友链信息结构化，以便在页面中循环渲染。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;     // src/friends_data.ts
    
     export interface Friend {
         name: string;        // 博客名称
         url: string;         // 博客链接
         avatar: string;      // 头像图片地址
         description: string; // 博客简短描述
     }
    
    export const friends: Friend[] = [
        {
            name: &quot;示例好友&quot;,
            url: &quot;https://example.com&quot;,
            avatar: &quot;https://api.dicebear.com/7.x/avataaars/svg?seed=1&quot;,
            description: &quot;这是一个非常酷的博客！&quot;,
        },
        // 在此处添加更多好友...
    ];
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第二步：编写页面说明内容&lt;/h3&gt;
&lt;p&gt;为了方便随时修改页面的文字介绍（如友链申请要求），我们使用 Markdown 文件。&lt;/p&gt;
&lt;p&gt;在 src/content/spec/ 目录下创建 friends.md：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;   ---
     title: &quot;友情链接&quot;
     description: &quot;我的朋友们&quot;
     ---
    
     ## 📝 交换说明
    
     - **本站名称**: 你的博客名
     - **本站链接**: `https://yourblog.com`
    - **本站头像**: `https://yourblog.com/avatar.png`
    - **本站描述**: 风过留痕，雁过留声。
   
    &amp;gt; ⚠️ 申请前请先添加本站友链。网站需内容健康，且能够正常访问。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第三步：创建页面渲染模板&lt;/h3&gt;
&lt;p&gt;这是最核心的部分，我们需要创建一个 Astro 页面来读取数据并生成 HTML。&lt;/p&gt;
&lt;p&gt;在 src/pages/ 目录下创建 friends.astro：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    2 import { getEntry, render } from &quot;astro:content&quot;;
    3 import Markdown from &quot;@components/misc/Markdown.astro&quot;;
    4 import MainGridLayout from &quot;@layouts/MainGridLayout.astro&quot;;
    5 import { friends } from &quot;../friends_data&quot;; // 导入友链数据
    6
    7 // 1. 获取 Markdown 说明内容
    8 const friendsPost = await getEntry(&quot;spec&quot;, &quot;friends&quot;);
    9 const { Content } = await render(friendsPost);
   10 ---
   11
   12 &amp;lt;MainGridLayout title=&quot;友情链接&quot;&amp;gt;
   13     &amp;lt;div class=&quot;card-base p-6 md:p-8&quot;&amp;gt;
   14         &amp;lt;!-- 页面大标题装饰 --&amp;gt;
   15         &amp;lt;div class=&quot;friends-bg-text&quot;&amp;gt;FRIENDS&amp;lt;/div&amp;gt;
   16
   17         &amp;lt;!-- 渲染顶部的 Markdown 说明 --&amp;gt;
   18         &amp;lt;div class=&quot;mb-8&quot;&amp;gt;
   19             &amp;lt;Markdown class=&quot;mt-2&quot;&amp;gt;
   20                 &amp;lt;Content /&amp;gt;
   21             &amp;lt;/Markdown&amp;gt;
   22         &amp;lt;/div&amp;gt;
   23
   24         &amp;lt;!-- 友链卡片网格系统 --&amp;gt;
   25         &amp;lt;div class=&quot;grid grid-cols-1 md:grid-cols-2 gap-4&quot;&amp;gt;
   26             {friends.map((friend) =&amp;gt; (
   27                 &amp;lt;a href={friend.url} target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot; class=&quot;friend-card
      group&quot;&amp;gt;
   28                     &amp;lt;div class=&quot;flex items-center gap-3&quot;&amp;gt;
   29                         &amp;lt;img src={friend.avatar} class=&quot;w-10 h-10 rounded-lg transition-transform
      group-hover:rotate-12&quot; alt={friend.name} /&amp;gt;
   30                         &amp;lt;div class=&quot;font-bold text-black dark:text-white&quot;&amp;gt;{friend.name}&amp;lt;/div&amp;gt;
   31                     &amp;lt;/div&amp;gt;
   32                     &amp;lt;div class=&quot;text-sm text-black/50 dark:text-white/50 mt-2 line-clamp-1&quot;&amp;gt;
   33                         {friend.description}
   34                     &amp;lt;/div&amp;gt;
   35                 &amp;lt;/a&amp;gt;
   36             ))}
   37         &amp;lt;/div&amp;gt;
   38     &amp;lt;/div&amp;gt;
   39 &amp;lt;/MainGridLayout&amp;gt;
   40
   41 &amp;lt;style&amp;gt;
   42 /* 标题装饰样式 */
   43 .friends-bg-text {
   44     @apply text-[60px] md:text-[100px] font-black text-center leading-none select-none mb-8;
   45     color: rgba(59, 130, 246, 0.08);
   46 }
   47
   48 /* 友链卡片基础样式 */
   49 .friend-card {
   50     @apply p-4 rounded-xl border border-black/5 dark:border-white/5 transition-all duration-300;
   51     background: linear-gradient(135deg, rgba(156, 163, 175, 0.05) 0%, rgba(209, 213, 219, 0.05) 100%);
   52 }
   53
   54 /* 悬停交互效果 */
   55 .friend-card:hover {
   56     @apply -translate-y-1 shadow-lg border-blue-400/30;
   57     background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, rgba(147, 197, 253, 0.05) 100%);
   58 }
   59 &amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第四步：配置导航栏入口&lt;/h3&gt;
&lt;p&gt;最后，我们需要在博客顶部的导航栏中加入这个页面的入口。&lt;/p&gt;
&lt;p&gt;编辑 src/config.ts：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    1 export const navBarConfig: NavBarConfig = {
    2     links: [
    3         LinkPreset.Home,
    4         LinkPreset.Archive,
    5         {
    6             name: &quot;友链&quot;,
    7             url: &quot;/friends/&quot;, // 路径需与 pages 目录下的文件名对应
    8         },
    9         LinkPreset.About,
   10     ],
   11 };
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;架构优势总结&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;极速加载：友链数据在构建时即被静态化，无需在客户端请求 API，页面秒开。&lt;/li&gt;
&lt;li&gt;样式统一：通过 MainGridLayout 自动继承了博客的侧边栏、背景和暗色模式切换逻辑。&lt;/li&gt;
&lt;li&gt;维护简单：新增友链只需在 friends_data.ts 数组中增加一个对象，修改申请规则只需编辑 friends.md。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;现在，你的 Fuwari 博客已经拥有了一个具备精美悬停动画和响应式布局的友链页面了！🚀&lt;/p&gt;
</content:encoded></item><item><title>为 Fuwari 博客添加 Umami 访问统计卡片</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E6%B7%BB%E5%8A%A0%E8%AE%BF%E9%97%AE%E7%BB%9F%E8%AE%A1%E5%8D%A1%E7%89%87---thws-blog/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BA-fuwari-%E6%B7%BB%E5%8A%A0%E8%AE%BF%E9%97%AE%E7%BB%9F%E8%AE%A1%E5%8D%A1%E7%89%87---thws-blog/</guid><description>本文详细介绍了如何通过 Umami API 获取站点数据，并为 Fuwari 主题自定义开发一个优雅的侧边栏访问统计组件。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;开始&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E5%BC%80%E5%A7%8B&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;搭建好博客网站之后，我们通常都有查看访问数据的需求。作为静态博客，在不自建服务器的情况下通常都是使用类似Umami的外部网站分析工具（Umami确实好用），但是当我们希望向访客展示自己的访问数据时，就只能在网站上挂一个Umami分享的外链，非常的不优雅。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.tianhw.top/_astro/card_Z2bc1IP.webp&quot; alt=&quot;统计信息小卡片&quot; /&gt; 于是我将Umami统计信息做成了小组件放在了页面左侧，效果还是不错的。那么，教程开始。&lt;/p&gt;
&lt;h2&gt;教程&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E6%95%99%E7%A8%8B&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;准备&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E5%87%86%E5%A4%87&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;一个已部署好的fuwari博客&lt;/li&gt;
&lt;li&gt;启用Umami统计的站点（如果你不知道什么是umami，请先自行搜索教程后继续阅读）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;获取数据&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E8%8E%B7%E5%8F%96%E6%95%B0%E6%8D%AE&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;“
&lt;img src=&quot;https://blog.tianhw.top/_astro/umami_ZfGL0Y.webp&quot; alt=&quot;umami页面&quot; /&gt; 为了获取到图中的这些数据，我们需要先首先我们启用Umami统计的分享URL&lt;/p&gt;
&lt;p&gt;你应该会得到一个&lt;code&gt;https://cloud.umami.is/analytics/us/share/EkS4mYbIXLu9vshR&lt;/code&gt;这个样子的URL，以我的这个为例，我们需要的是最后这一串&lt;code&gt;EkS4mYbIXLu9vshR&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;接着我们去浏览器访问&lt;code&gt;https://cloud.umami.is/analytics/us/api/share/EkS4mYbIXLu9vshR&lt;/code&gt;（注意这里的&lt;code&gt;EkS4mYbIXLu9vshR&lt;/code&gt;要替换为上一步中你自己的），就会得到以下数据：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;websiteId&quot;: &quot;42d4c606-856f-4026-906c-65bbcb4c5ac1&quot;,
  &quot;token&quot;: &quot;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3ZWJzaXRlSWQiOiI0MmQ0YzYwNi04NTZmLTQwMjYtOTA2Yy02NWJiY2I0YzVhYzEiLCJpYXQiOjE3NjAzNjczOTJ9.JWtW668hYoeiKTZSkxZ8suW7RZnmzn0Pa0CHN2xpJYU&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;记下来，稍后有用。&lt;/p&gt;
&lt;h3&gt;添加组件&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E6%B7%BB%E5%8A%A0%E7%BB%84%E4%BB%B6&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;创建组件&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E5%88%9B%E5%BB%BA%E7%BB%84%E4%BB%B6&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;在 &lt;code&gt;src/components/widget/&lt;/code&gt; 目录下创建 &lt;code&gt;UmamiStats.astro&lt;/code&gt; 文件，代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import WidgetLayout from &quot;./WidgetLayout.astro&quot;;

interface Props {
  class?: string;
  style?: string;
}
const { class: className, style } = Astro.props;
---

&amp;lt;WidgetLayout name=&quot;统计&quot; id=&quot;umami-stats&quot; class:list={[className]} {style}&amp;gt;
    &amp;lt;div class=&quot;text-center py-2&quot;&amp;gt;
        &amp;lt;div class=&quot;text-3xl font-bold text-neutral-900 dark:text-neutral-100&quot; id=&quot;total-pageviews&quot;&amp;gt;-&amp;lt;/div&amp;gt;
        &amp;lt;div class=&quot;text-sm text-neutral-500 dark:text-neutral-400&quot;&amp;gt;总浏览量&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;grid grid-cols-2 divide-x divide-neutral-200 dark:divide-neutral-700 text-center pt-2&quot;&amp;gt;
        &amp;lt;div class=&quot;px-2&quot;&amp;gt;
            &amp;lt;div class=&quot;text-xl font-bold text-neutral-900 dark:text-neutral-100&quot; id=&quot;total-visits&quot;&amp;gt;-&amp;lt;/div&amp;gt;
            &amp;lt;div class=&quot;text-sm text-neutral-500 dark:text-neutral-400&quot;&amp;gt;访问数&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class=&quot;px-2&quot;&amp;gt;
            &amp;lt;div class=&quot;text-xl font-bold text-neutral-900 dark:text-neutral-100&quot; id=&quot;total-visitors&quot;&amp;gt;-&amp;lt;/div&amp;gt;
            &amp;lt;div class=&quot;text-sm text-neutral-500 dark:text-neutral-400&quot;&amp;gt;游客数&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/WidgetLayout&amp;gt;

&amp;lt;script&amp;gt;
const UMAMI_CONFIG = {
    baseUrl: &apos;https://cloud.umami.is/analytics/us/api&apos;, // 如果你选的区域是欧盟，请改为 https://cloud.umami.is/analytics/eu/api
    websiteId: &apos;上一步获得的websiteId（也就是短的那个）&apos;,
    shareToken: &apos;上一步获得的token（也就是长的那个）&apos;
};

function formatNumber(num: number): string {
    if (num &amp;gt;= 1000000) {
        return (num / 1000000).toFixed(1) + &apos;M&apos;;
    } else if (num &amp;gt;= 1000) {
        return (num / 1000).toFixed(1) + &apos;K&apos;;
    }
    return num.toString();
}

async function fetchUmamiStats() {
    try {
        const endAt = Date.now();
        const startAt = 0;

        const url = `${UMAMI_CONFIG.baseUrl}/websites/${UMAMI_CONFIG.websiteId}/stats?startAt=${startAt}&amp;amp;endAt=${endAt}&amp;amp;unit=hour&amp;amp;timezone=Asia%2FShanghai`;

        const response = await fetch(url, {
            method: &apos;GET&apos;,
            headers: {
                &apos;accept&apos;: &apos;application/json&apos;,
                &apos;x-umami-share-token&apos;: UMAMI_CONFIG.shareToken
            }
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        const pageviewsElement = document.getElementById(&apos;total-pageviews&apos;);
        const visitsElement = document.getElementById(&apos;total-visits&apos;);
        const visitorsElement = document.getElementById(&apos;total-visitors&apos;);

        if (pageviewsElement) {
            pageviewsElement.textContent = formatNumber(data.pageviews || 0);
        }

        if (visitsElement) {
            visitsElement.textContent = formatNumber(data.visits || 0);
        }

        if (visitorsElement) {
            visitorsElement.textContent = formatNumber(data.visitors || 0);
        }

    } catch (error) {
        console.error(&apos;获取Umami统计数据失败:&apos;, error);
        const elements = [&apos;total-pageviews&apos;, &apos;total-visits&apos;, &apos;total-visitors&apos;];
        elements.forEach(id =&amp;gt; {
            const element = document.getElementById(id);
            if (element) {
                element.textContent = &apos;获取失败&apos;;
                element.classList.add(&apos;text-red-500&apos;);
            }
        });
    }
}

document.addEventListener(&apos;DOMContentLoaded&apos;, fetchUmamiStats);

if (window.swup) {
    window.swup.hooks.on(&apos;page:view&apos;, fetchUmamiStats);
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置参数&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;在上面的代码中，记得要替换以下配置：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WARNING&lt;/p&gt;
&lt;p&gt;如果你的 Umami 注册时数据存储区域选择的是 &lt;strong&gt;欧盟&lt;/strong&gt;，请将 &lt;code&gt;baseUrl&lt;/code&gt; 改为 &lt;code&gt;https://cloud.umami.is/analytics/eu/api&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;const UMAMI_CONFIG = {
    baseUrl: &apos;https://cloud.umami.is/analytics/us/api&apos;,
    websiteId: &apos;上一步获得的websiteId（也就是短的那个）&apos;,
    shareToken: &apos;上一步获得的token（也就是长的那个）&apos;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;添加到侧边栏组件&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E6%B7%BB%E5%8A%A0%E5%88%B0%E4%BE%A7%E8%BE%B9%E6%A0%8F%E7%BB%84%E4%BB%B6&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;在 &lt;code&gt;src/components/widget/SideBar.astro&lt;/code&gt; 中导入此组件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
import { Image } from &quot;astro:assets&quot;;
import type { MarkdownHeading } from &quot;astro&quot;;
import { Icon } from &quot;astro-icon/components&quot;;
import Categories from &quot;./Categories.astro&quot;;
import Profile from &quot;./Profile.astro&quot;;
import Sponsors from &quot;./Sponsors.astro&quot;;
import UmamiStats from &quot;./UmamiStats.astro&quot;;
import VisitorIP from &quot;./VisitorIP.astro&quot;;

interface Props {
  class?: string;
  headings?: MarkdownHeading[];
}

const className = Astro.props.class;
---
&amp;lt;div id=&quot;sidebar&quot; class:list={[className, &quot;w-full&quot;]}&amp;gt;
    &amp;lt;div class=&quot;flex flex-col w-full gap-4 mb-4&quot;&amp;gt;
        &amp;lt;Profile&amp;gt;&amp;lt;/Profile&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id=&quot;sidebar-sticky&quot; class=&quot;transition-all duration-700 flex flex-col w-full gap-4 top-4 sticky top-4&quot;&amp;gt;
        &amp;lt;Categories class=&quot;onload-animation&quot; style=&quot;animation-delay: 150ms&quot;&amp;gt;&amp;lt;/Categories&amp;gt;
        &amp;lt;UmamiStats class=&quot;onload-animation&quot; style=&quot;animation-delay: 200ms&quot;&amp;gt;&amp;lt;/UmamiStats&amp;gt;
        &amp;lt;VisitorIP class=&quot;onload-animation&quot; style=&quot;animation-delay: 225ms&quot;&amp;gt;&amp;lt;/VisitorIP&amp;gt;
        &amp;lt;Sponsors class=&quot;onload-animation&quot; style=&quot;animation-delay: 250ms&quot;&amp;gt;&amp;lt;/Sponsors&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自定义&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E8%87%AA%E5%AE%9A%E4%B9%89&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;如果你按照上述的步骤操作，那么你应该就能在页面左侧下方看到你的博客浏览量统计了，下面是自定义的教程：&lt;/p&gt;
&lt;h4&gt;修改统计周期&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E4%BF%AE%E6%94%B9%E7%BB%9F%E8%AE%A1%E5%91%A8%E6%9C%9F&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;默认为 &lt;strong&gt;所有时间&lt;/strong&gt; ，如果你想要调整浏览量统计的时间范围，你需要修改&lt;code&gt;UmamiStats.astro&lt;/code&gt; 文件的 startAt 参数(默认是所有时间)。 例如改为最近30天的数据，也就是30天×24小时×60分钟×60秒×1000毫秒=&lt;code&gt;2592000000&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try {
    const endAt = Date.now();
    const startAt = 0;
    const startAt = Date.now() - 2592000000;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同理，如果你想改为最近90天的数据，只需要减去90天×24小时×60分钟×60秒×1000毫秒即可。&lt;/p&gt;
&lt;h2&gt;结尾&lt;a href=&quot;https://blog.tianhw.top/posts/fuwari-umami-stats/#%E7%BB%93%E5%B0%BE&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;通过以上步骤，你就成功为 Fuwari 添加了基于 Umami 的网站访问统计卡片，同时还支持明/暗模式切换。以后只要有访客查看，统计卡片数据都会自动更新。&lt;/p&gt;
</content:encoded></item><item><title>FUwari 二级导航改造教程</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BAfuwaru%E6%B7%BB%E5%8A%A0%E4%BA%8C%E7%BA%A7%E5%AF%BC%E8%88%AA---pengxings-blog/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E4%B8%BAfuwaru%E6%B7%BB%E5%8A%A0%E4%BA%8C%E7%BA%A7%E5%AF%BC%E8%88%AA---pengxings-blog/</guid><description>为 Fuwari 主题添加二级导航支持，实现桌面端悬停展开与移动端点击切换功能。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;Fuwari 的简约美一直深得我心，但“鱼和熊掌不可兼得”，极简的设计往往意味着功能的取舍。为了在不破坏原主题美感的前提下增加导航深度，我参考了- &lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/&quot;&gt;FUwari 二级导航 - PengXing&apos;s Blog&lt;/a&gt;的方案。这套二级导航方案动画丝滑，完美契合了原主题的 UI 风格。&lt;/p&gt;
&lt;h2&gt;设计架构&lt;/h2&gt;
&lt;h3&gt;1. 数据层 (Data Layer)&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;src/config.ts&lt;/code&gt; 中，导航栏不再是简单的平级数组，而是引入了&lt;strong&gt;嵌套结构&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;父级节点&lt;/strong&gt;：包含 &lt;code&gt;name&lt;/code&gt; 和 &lt;code&gt;url&lt;/code&gt;（通常设为 &lt;code&gt;#&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;子级节点 (&lt;code&gt;children&lt;/code&gt;)&lt;/strong&gt;：一个可选的数组，存放子菜单的对象。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;属性标记&lt;/strong&gt;：通过 &lt;code&gt;external: true&lt;/code&gt; 标记外部链接，以便在渲染时自动添加图标和 &lt;code&gt;_blank&lt;/code&gt; 属性。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 类型层 (Type Layer)&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;src/types/config.ts&lt;/code&gt; 中，通过 &lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/#srctypesconfigts&quot;&gt;TypeScript&lt;/a&gt; 定义了递归或嵌套的接口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;扩展了原有的 &lt;code&gt;NavBarLink&lt;/code&gt; 类型，增加了一个可选属性 &lt;code&gt;children?: NavBarLink[]&lt;/code&gt;。这允许导航项持有与之结构相同的子项。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 渲染层 (Rendering Layer)&lt;/h3&gt;
&lt;p&gt;这一层由两个核心 Astro 组件组成，分别处理不同的终端显示：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;桌面端 (Navbar.astro)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;逻辑控制&lt;/strong&gt;：使用 &lt;code&gt;map&lt;/code&gt; 循环遍历 &lt;code&gt;links&lt;/code&gt;，通过 &lt;code&gt;if (l.children)&lt;/code&gt; 判断是否渲染下拉菜单。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;布局实现&lt;/strong&gt;：父容器设为 &lt;code&gt;relative group&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;显示逻辑&lt;/strong&gt;：利用 Tailwind 的 &lt;code&gt;group-hover&lt;/code&gt; 类（如 &lt;code&gt;group-hover:opacity-100&lt;/code&gt;），实现鼠标悬停时下方 &lt;code&gt;absolute&lt;/code&gt; 定位的菜单面板由隐变现。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;移动端 (NavMenuPanel.astro)&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;垂直布局&lt;/strong&gt;：子菜单不再是悬浮框，而是嵌套在侧边栏列表中的伸缩项。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;状态标识&lt;/strong&gt;：包含一个箭头图标（&lt;code&gt;nav-submenu-arrow&lt;/code&gt;），通过 CSS 类控制旋转角度来暗示展开状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 交互层 (Interaction Layer)&lt;/h3&gt;
&lt;p&gt;由于 Astro 默认不带客户端 JS，作者在 &lt;code&gt;NavMenuPanel.astro&lt;/code&gt; 中注入了 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 脚本来处理移动端点击：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;高度过渡&lt;/strong&gt;：通过监听 &lt;code&gt;click&lt;/code&gt; 事件，动态计算 &lt;code&gt;scrollHeight&lt;/code&gt; 并赋值给 &lt;code&gt;maxHeight&lt;/code&gt;。这种方式比简单的 &lt;code&gt;display: block&lt;/code&gt; 动画效果更丝滑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;旋转动画&lt;/strong&gt;：同步修改箭头图标的 &lt;code&gt;transform&lt;/code&gt; 属性。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;二级菜单配置&lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/#%E4%BA%8C%E7%BA%A7%E8%8F%9C%E5%8D%95%E9%85%8D%E7%BD%AE&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在导航栏配置中支持二级菜单，可以创建下拉菜单结构：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;配置说明：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; - 菜单显示名称&lt;/li&gt;
&lt;li&gt;&lt;code&gt;url&lt;/code&gt; - 链接地址（父级菜单建议使用 &lt;code&gt;#&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;children&lt;/code&gt; - 子菜单数组&lt;/li&gt;
&lt;li&gt;&lt;code&gt;external&lt;/code&gt; - 是否为外部链接&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;功能特性：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;桌面端：鼠标悬停展开二级菜单&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;移动端：点击切换二级菜单显示/隐藏&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持无限层级嵌套&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自动适应内容宽度&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;export const navBarConfig: NavBarConfig = {
  links: [
    LinkPreset.Home,
    LinkPreset.Archive,
    LinkPreset.About,
    LinkPreset.Series,
    LinkPreset.Friends,
    LinkPreset.Donate,
    {
      name: &quot;其他&quot;, // 标题
      url: &quot;#&quot;, // 内部链接不应包含基本路径，因为它是自动添加的
      children: [
        {
          name: &quot;访客统计&quot;,
          url: &quot;https://cloud.umami.is/share/i6f3UwPY4n0w1LJa/pengxing.dpdns.org&quot;, // 内部链接不应包含基本路径，因为它是自动添加的
          external: true, //显示外部链接图标，并将在新选项卡中打开
        },
        {
          name: &quot;网盘资源&quot;,
          url: &quot;https://docs.qq.com/aio/DYmZYVGpFVGxOS3NE&quot;, // 内部链接不应包含基本路径，因为它是自动添加的
          external: true, //显示外部链接图标，并将在新选项卡中打开
        },
      ],
    },
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修改代码&lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/#%E4%BF%AE%E6%94%B9%E4%BB%A3%E7%A0%81&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;src/components/Navbar.astro&lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/#srccomponentsnavbarastro&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;---
import { Icon } from &quot;astro-icon/components&quot;;
import { navBarConfig, siteConfig } from &quot;../config&quot;;
import { LinkPresets } from &quot;../constants/link-presets&quot;;
import { LinkPreset, type NavBarLink } from &quot;../types/config&quot;;
import { url } from &quot;../utils/url-utils&quot;;
import LightDarkSwitch from &quot;./LightDarkSwitch.svelte&quot;;
import Search from &quot;./Search.svelte&quot;;
import DisplaySettings from &quot;./widget/DisplaySettings.svelte&quot;;
import NavMenuPanel from &quot;./widget/NavMenuPanel.astro&quot;;

const className = Astro.props.class;

let links: NavBarLink[] = navBarConfig.links.map(
  (item: NavBarLink | LinkPreset): NavBarLink =&amp;gt; {
    if (typeof item === &quot;number&quot;) {
      return LinkPresets[item];
    }
    return item;
  },
);
---
&amp;lt;div id=&quot;navbar&quot; class=&quot;z-50 onload-animation&quot;&amp;gt;
    &amp;lt;div class=&quot;absolute h-8 left-0 right-0 -top-8 bg-[var(--card-bg)] transition&quot;&amp;gt;&amp;lt;/div&amp;gt; &amp;lt;!-- used for onload animation --&amp;gt;
    &amp;lt;div class:list={[
        className,
        &quot;card-base !overflow-visible max-w-[var(--page-width)] h-[4.5rem] !rounded-t-none mx-auto flex items-center justify-between px-4&quot;]}&amp;gt;
        &amp;lt;a href={url(&apos;/&apos;)} class=&quot;btn-plain scale-animation rounded-lg h-[3.25rem] px-5 font-bold active:scale-95&quot;&amp;gt;
            &amp;lt;div class=&quot;flex flex-row text-[var(--primary)] items-center text-md&quot;&amp;gt;
                &amp;lt;Icon name=&quot;material-symbols:home-outline-rounded&quot; class=&quot;text-[1.75rem] mb-1 mr-2&quot; /&amp;gt;
                {siteConfig.title}
            &amp;lt;/div&amp;gt;
        &amp;lt;/a&amp;gt;
        &amp;lt;div class=&quot;hidden md:flex&quot;&amp;gt;
            {links.map((l) =&amp;gt; {
                // return &amp;lt;a aria-label={l.name} href={l.external ? l.url : url(l.url)} target={l.external ? &quot;_blank&quot; : null}
                //           class=&quot;btn-plain scale-animation rounded-lg h-11 font-bold px-5 active:scale-95&quot;
                // &amp;gt;
                //     &amp;lt;div class=&quot;flex items-center&quot;&amp;gt;
                //         {l.name}
                //         {l.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot; class=&quot;text-[0.875rem] transition -translate-y-[1px] ml-1 text-black/[0.2] dark:text-white/[0.2]&quot;&amp;gt;&amp;lt;/Icon&amp;gt;}
                //     &amp;lt;/div&amp;gt;
                // &amp;lt;/a&amp;gt;;
                if (l.children &amp;amp;&amp;amp; l.children.length &amp;gt; 0) {
                    // 有子菜单的情况
                    return &amp;lt;div class=&quot;relative group&quot;&amp;gt;
                        &amp;lt;button class=&quot;btn-plain scale-animation rounded-lg h-11 font-bold px-5 active:scale-95 flex items-center&quot;&amp;gt;
                            {l.name}
                            &amp;lt;Icon name=&quot;material-symbols:keyboard-arrow-down-rounded&quot; class=&quot;text-[1.25rem] ml-1 transition-transform group-hover:rotate-180&quot;&amp;gt;&amp;lt;/Icon&amp;gt;
                        &amp;lt;/button&amp;gt;
                        &amp;lt;div class=&quot;absolute top-full left-0 mt-2 min-w-max bg-[var(--card-bg)] border border-[var(--line-divider)] rounded-lg shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50 whitespace-nowrap&quot;&amp;gt;
                            {l.children.map((child) =&amp;gt; (
                                 &amp;lt;a href={child.external ? child.url : url(child.url)} target={child.external ? &quot;_blank&quot; : null}
                                    class=&quot;btn-plain scale-animation block px-4 py-3 text-sm font-bold hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] first:rounded-t-lg last:rounded-b-lg transition-all duration-200 active:scale-95 mx-1 my-0.5 rounded-lg&quot;&amp;gt;
                                     &amp;lt;div class=&quot;flex items-center justify-between&quot;&amp;gt;
                                         {child.name}
                                         {child.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot; class=&quot;text-[0.75rem] text-black/[0.2] dark:text-white/[0.2]&quot;&amp;gt;&amp;lt;/Icon&amp;gt;}
                                     &amp;lt;/div&amp;gt;
                                 &amp;lt;/a&amp;gt;
                             ))}
                        &amp;lt;/div&amp;gt;
                    &amp;lt;/div&amp;gt;;
                } else {
                    // 没有子菜单的情况
                    return &amp;lt;a aria-label={l.name} href={l.external ? l.url : url(l.url)} target={l.external ? &quot;_blank&quot; : null}
                              class=&quot;btn-plain scale-animation rounded-lg h-11 font-bold px-5 active:scale-95&quot;
                    &amp;gt;
                        &amp;lt;div class=&quot;flex items-center&quot;&amp;gt;
                            {l.name}
                            {l.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot; class=&quot;text-[0.875rem] transition -translate-y-[1px] ml-1 text-black/[0.2] dark:text-white/[0.2]&quot;&amp;gt;&amp;lt;/Icon&amp;gt;}
                        &amp;lt;/div&amp;gt;
                    &amp;lt;/a&amp;gt;;
                }

            })}
        &amp;lt;/div&amp;gt;
        &amp;lt;div class=&quot;flex&quot;&amp;gt;
            &amp;lt;!--&amp;lt;SearchPanel client:load&amp;gt;--&amp;gt;
            &amp;lt;Search client:only=&quot;svelte&quot;&amp;gt;&amp;lt;/Search&amp;gt;
            {!siteConfig.themeColor.fixed &amp;amp;&amp;amp; (
                    &amp;lt;button aria-label=&quot;Display Settings&quot; class=&quot;btn-plain scale-animation rounded-lg h-11 w-11 active:scale-90&quot; id=&quot;display-settings-switch&quot;&amp;gt;
                        &amp;lt;Icon name=&quot;material-symbols:palette-outline&quot; class=&quot;text-[1.25rem]&quot;&amp;gt;&amp;lt;/Icon&amp;gt;
                    &amp;lt;/button&amp;gt;
            )}
            &amp;lt;LightDarkSwitch client:only=&quot;svelte&quot;&amp;gt;&amp;lt;/LightDarkSwitch&amp;gt;
            &amp;lt;button aria-label=&quot;Menu&quot; name=&quot;Nav Menu&quot; class=&quot;btn-plain scale-animation rounded-lg w-11 h-11 active:scale-90 md:!hidden&quot; id=&quot;nav-menu-switch&quot;&amp;gt;
                &amp;lt;Icon name=&quot;material-symbols:menu-rounded&quot; class=&quot;text-[1.25rem]&quot;&amp;gt;&amp;lt;/Icon&amp;gt;
            &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;NavMenuPanel links={links}&amp;gt;&amp;lt;/NavMenuPanel&amp;gt;
        &amp;lt;DisplaySettings client:only=&quot;svelte&quot;&amp;gt;&amp;lt;/DisplaySettings&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
function switchTheme() {
    if (localStorage.theme === &apos;dark&apos;) {
        document.documentElement.classList.remove(&apos;dark&apos;);
        localStorage.theme = &apos;light&apos;;
    } else {
        document.documentElement.classList.add(&apos;dark&apos;);
        localStorage.theme = &apos;dark&apos;;
    }
}

function loadButtonScript() {
    let switchBtn = document.getElementById(&quot;scheme-switch&quot;);
    if (switchBtn) {
        switchBtn.onclick = function () {
            switchTheme()
        };
    }

    let settingBtn = document.getElementById(&quot;display-settings-switch&quot;);
    if (settingBtn) {
        settingBtn.onclick = function () {
            let settingPanel = document.getElementById(&quot;display-setting&quot;);
            if (settingPanel) {
                settingPanel.classList.toggle(&quot;float-panel-closed&quot;);
            }
        };
    }

    let menuBtn = document.getElementById(&quot;nav-menu-switch&quot;);
    if (menuBtn) {
        menuBtn.onclick = function () {
            let menuPanel = document.getElementById(&quot;nav-menu-panel&quot;);
            if (menuPanel) {
                menuPanel.classList.toggle(&quot;float-panel-closed&quot;);
            }
        };
    }
}

loadButtonScript();
&amp;lt;/script&amp;gt;

{import.meta.env.PROD &amp;amp;&amp;amp; &amp;lt;script is:inline define:vars={{scriptUrl: url(&apos;/pagefind/pagefind.js&apos;)}}&amp;gt;
async function loadPagefind() {
    try {
        const response = await fetch(scriptUrl, { method: &apos;HEAD&apos; });
        if (!response.ok) {
            throw new Error(`Pagefind script not found: ${response.status}`);
        }

        const pagefind = await import(scriptUrl);

        await pagefind.options({
            excerptLength: 20
        });

        window.pagefind = pagefind;

        document.dispatchEvent(new CustomEvent(&apos;pagefindready&apos;));
        console.log(&apos;Pagefind loaded and initialized successfully, event dispatched.&apos;);
    } catch (error) {
        console.error(&apos;Failed to load Pagefind:&apos;, error);
        window.pagefind = {
            search: () =&amp;gt; Promise.resolve({ results: [] }),
            options: () =&amp;gt; Promise.resolve(),
        };
        document.dispatchEvent(new CustomEvent(&apos;pagefindloaderror&apos;));
        console.log(&apos;Pagefind load error, event dispatched.&apos;);
    }
}

if (document.readyState === &apos;loading&apos;) {
    document.addEventListener(&apos;DOMContentLoaded&apos;, loadPagefind);
} else {
    loadPagefind();
}
&amp;lt;/script&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;src/components/widget/NavMenuPanel.astro&lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/#srccomponentswidgetnavmenupanelastro&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;---
import { Icon } from &quot;astro-icon/components&quot;;
import { type NavBarLink } from &quot;../../types/config&quot;;
import { url } from &quot;../../utils/url-utils&quot;;

interface Props {
  links: NavBarLink[];
}

const links = Astro.props.links;
---
&amp;lt;div id=&quot;nav-menu-panel&quot; class:list={[&quot;float-panel float-panel-closed absolute transition-all fixed right-4 px-2 py-2&quot;]}&amp;gt;
    &amp;lt;!-- {links.map((link) =&amp;gt; (
        &amp;lt;a href={link.external ? link.url : url(link.url)} class=&quot;group flex justify-between items-center py-2 pl-3 pr-1 rounded-lg gap-8
            hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] transition
        &quot;
           target={link.external ? &quot;_blank&quot; : null}
        &amp;gt;
            &amp;lt;div class=&quot;transition text-black/75 dark:text-white/75 font-bold group-hover:text-[var(--primary)] group-active:text-[var(--primary)]&quot;&amp;gt;
                {link.name}
            &amp;lt;/div&amp;gt;
            {!link.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;material-symbols:chevron-right-rounded&quot;
                  class=&quot;transition text-[1.25rem] text-[var(--primary)]&quot;
            &amp;gt;
            &amp;lt;/Icon&amp;gt;}
            {link.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot;
                  class=&quot;transition text-[0.75rem] text-black/25 dark:text-white/25 -translate-x-1&quot;
            &amp;gt;
            &amp;lt;/Icon&amp;gt;}
        &amp;lt;/a&amp;gt;
    ))} --&amp;gt;
    {links.map((link) =&amp;gt; {
        if (link.children &amp;amp;&amp;amp; link.children.length &amp;gt; 0) {
            // 有子菜单的情况
            return (
                &amp;lt;div class=&quot;nav-menu-item-with-children&quot;&amp;gt;
                    &amp;lt;button class=&quot;group flex justify-between items-center py-2 pl-3 pr-1 rounded-lg gap-8 w-full
                        hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] transition
                        nav-submenu-toggle&quot;
                    &amp;gt;
                        &amp;lt;div class=&quot;transition text-black/75 dark:text-white/75 font-bold group-hover:text-[var(--primary)] group-active:text-[var(--primary)]&quot;&amp;gt;
                            {link.name}
                        &amp;lt;/div&amp;gt;
                        &amp;lt;Icon name=&quot;material-symbols:keyboard-arrow-down-rounded&quot;
                              class=&quot;transition text-[1.25rem] text-[var(--primary)] nav-submenu-arrow&quot;
                        &amp;gt;
                        &amp;lt;/Icon&amp;gt;
                    &amp;lt;/button&amp;gt;
                    &amp;lt;div class=&quot;nav-submenu pl-4 max-h-0 overflow-hidden transition-all duration-200&quot;&amp;gt;
                        {link.children.map((child) =&amp;gt; (
                            &amp;lt;a href={child.external ? child.url : url(child.url)} class=&quot;group flex justify-between items-center py-2 pl-3 pr-1 rounded-lg gap-8
                                hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] transition
                            &quot;
                               target={child.external ? &quot;_blank&quot; : null}
                            &amp;gt;
                                &amp;lt;div class=&quot;transition text-black/60 dark:text-white/60 text-sm group-hover:text-[var(--primary)] group-active:text-[var(--primary)]&quot;&amp;gt;
                                    {child.name}
                                &amp;lt;/div&amp;gt;
                                {!child.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;material-symbols:chevron-right-rounded&quot;
                                      class=&quot;transition text-[1rem] text-[var(--primary)]&quot;
                                &amp;gt;
                                &amp;lt;/Icon&amp;gt;}
                                {child.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot;
                                      class=&quot;transition text-[0.65rem] text-black/25 dark:text-white/25 -translate-x-1&quot;
                                &amp;gt;
                                &amp;lt;/Icon&amp;gt;}
                            &amp;lt;/a&amp;gt;
                        ))}
                    &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
            );
        } else {
            // 没有子菜单的情况
            return (
                &amp;lt;a href={link.external ? link.url : url(link.url)} class=&quot;group flex justify-between items-center py-2 pl-3 pr-1 rounded-lg gap-8
                    hover:bg-[var(--btn-plain-bg-hover)] active:bg-[var(--btn-plain-bg-active)] transition
                &quot;
                   target={link.external ? &quot;_blank&quot; : null}
                &amp;gt;
                    &amp;lt;div class=&quot;transition text-black/75 dark:text-white/75 font-bold group-hover:text-[var(--primary)] group-active:text-[var(--primary)]&quot;&amp;gt;
                        {link.name}
                    &amp;lt;/div&amp;gt;
                    {!link.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;material-symbols:chevron-right-rounded&quot;
                          class=&quot;transition text-[1.25rem] text-[var(--primary)]&quot;
                    &amp;gt;
                    &amp;lt;/Icon&amp;gt;}
                    {link.external &amp;amp;&amp;amp; &amp;lt;Icon name=&quot;fa6-solid:arrow-up-right-from-square&quot;
                          class=&quot;transition text-[0.75rem] text-black/25 dark:text-white/25 -translate-x-1&quot;
                    &amp;gt;
                    &amp;lt;/Icon&amp;gt;}
                &amp;lt;/a&amp;gt;
            );
        }
    })}
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
    // 移动端二级菜单展开/收起功能
    document.addEventListener(&apos;DOMContentLoaded&apos;, function() {
        const submenuToggles = document.querySelectorAll(&apos;.nav-submenu-toggle&apos;);

        submenuToggles.forEach(toggle =&amp;gt; {
            toggle.addEventListener(&apos;click&apos;, function(this: HTMLElement) {
                const submenu = this.parentElement?.querySelector(&apos;.nav-submenu&apos;) as HTMLElement;
                const arrow = this.querySelector(&apos;.nav-submenu-arrow&apos;) as HTMLElement;

                if (submenu &amp;amp;&amp;amp; arrow) {
                    const isExpanded = submenu.style.maxHeight &amp;amp;&amp;amp; submenu.style.maxHeight !== &apos;0px&apos;;

                    if (isExpanded) {
                        submenu.style.maxHeight = &apos;0px&apos;;
                        arrow.style.transform = &apos;rotate(0deg)&apos;;
                    } else {
                        submenu.style.maxHeight = submenu.scrollHeight + &apos;px&apos;;
                        arrow.style.transform = &apos;rotate(180deg)&apos;;
                    }
                }
            });
        });
    });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;src/types/config.ts&lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/#srctypesconfigts&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// 。。。。只需要修改这一处,其他保存不变

export type NavBarLink = {
  name: string;
  url: string;
  external?: boolean;
  children?: NavBarLink[]; // 支持二级菜单
};


// 。。。。只需要修改这一处,其他保存不变
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;转载说明&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;转载说明：&lt;/strong&gt;
本文转载自 &lt;a href=&quot;https://pengxing.dpdns.org/&quot;&gt;鹏星&lt;/a&gt; 的博客文章 &lt;a href=&quot;https://pengxing.dpdns.org/posts/fuwari_secondary_navigation/&quot;&gt;《FUwari 二级导航》&lt;/a&gt;。内容基于 &lt;a href=&quot;https://creativecommons.org/licenses/by-nc-sa/4.0/&quot;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 协议分享，感谢原作者的硬核教程！&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Fuwari 博客模板综合食用指南</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92fuwari-%E5%8D%9A%E5%AE%A2%E6%A8%A1%E6%9D%BF%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97---moekus-blog/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92fuwari-%E5%8D%9A%E5%AE%A2%E6%A8%A1%E6%9D%BF%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97---moekus-blog/</guid><description>一份关于如何使用 Fuwari 博客模板的简略指南，涵盖文章元数据、Markdown 语法扩展、代码高亮及视频嵌入等功能。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;文章元数据 (Front-matter)&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E6%96%87%E7%AB%A0%E5%85%83%E6%95%B0%E6%8D%AE-front-matter&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;每篇文章顶部的 YAML 代码块用于定义文章的元数据。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 我的第一篇博客文章
published: 2023-09-09
description: 这是我 Astro 新博客的第一篇文章。
image: ./cover.jpg
tags: [Foo, Bar]
category: 前端
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;属性 (Attribute)&lt;/th&gt;
&lt;th&gt;描述 (Description)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;title&lt;/td&gt;
&lt;td&gt;文章的标题。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;published&lt;/td&gt;
&lt;td&gt;文章的发布日期。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;updated&lt;/td&gt;
&lt;td&gt;(可选) 文章的更新日期。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;description&lt;/td&gt;
&lt;td&gt;文章的简短描述，会显示在首页。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;image&lt;/td&gt;
&lt;td&gt;文章的封面图片路径。&amp;lt;br&amp;gt;1. 以 &lt;code&gt;http://&lt;/code&gt; 或 &lt;code&gt;https://&lt;/code&gt; 开头：使用网络图片&amp;lt;br&amp;gt;2. 以 &lt;code&gt;/&lt;/code&gt; 开头：使用 &lt;code&gt;public&lt;/code&gt; 目录下的图片&amp;lt;br&amp;gt;3. 无上述前缀：相对于当前 Markdown 文件的路径&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tags&lt;/td&gt;
&lt;td&gt;文章的标签。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;category&lt;/td&gt;
&lt;td&gt;文章的分类。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;draft&lt;/td&gt;
&lt;td&gt;文章是否为草稿。若为 &lt;code&gt;true&lt;/code&gt;，则文章不会被公开发布和展示。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;草稿示例&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E8%8D%89%E7%A8%BF%E7%A4%BA%E4%BE%8B&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;如果一篇文章仍在撰写中，不希望被公开发布，可以将其 &lt;code&gt;draft&lt;/code&gt; 字段设置为 &lt;code&gt;true&lt;/code&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 草稿示例
published: 2022-07-01
tags: [Markdown, Blogging, Demo]
category: Examples
draft: true
---

# 这篇文章是一篇草稿

这篇文章目前处于草稿状态，不会被发布。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;文章存放位置&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E6%96%87%E7%AB%A0%E5%AD%98%E6%94%BE%E4%BD%8D%E7%BD%AE&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;您的文章文件应放置在 &lt;code&gt;src/content/posts/&lt;/code&gt; 目录下。您也可以创建子目录来更好地组织您的文章和相关资源。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;基础 Markdown 语法&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E5%9F%BA%E7%A1%80-markdown-%E8%AF%AD%E6%B3%95&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;标题&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E6%A0%87%E9%A2%98&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# H1 标题
## H2 标题
### H3 标题
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;文本格式&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E6%96%87%E6%9C%AC%E6%A0%BC%E5%BC%8F&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;段落之间通过一个空行分隔。&lt;/p&gt;
&lt;p&gt;这是第二段。&lt;em&gt;斜体&lt;/em&gt;, &lt;strong&gt;粗体&lt;/strong&gt;, 和 &lt;code&gt;等宽字体&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;列表&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E5%88%97%E8%A1%A8&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;无序列表&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- 列表项一
- 列表项二
- 列表项三
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;有序列表&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. 第一项
2. 第二项
3. 第三项
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;嵌套列表&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. 首先，准备这些食材：
    - 胡萝卜
    - 芹菜
    - 扁豆
2. 烧开一些水。
3. 把所有东西倒进锅里，然后遵循
    这个算法：

        找到木勺
        揭开锅盖
        搅拌
        盖上锅盖
        小心地把木勺平衡在锅柄上
        等待10分钟
        返回第一步（或者完成后关火）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;定义列表&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;苹果
: 做苹果酱的好材料。

橘子
: 柑橘类水果！

西红柿
: Tomatoe 这个词里没有 &quot;e&quot;。```

### 引用块

&amp;gt; 引用块是
&amp;gt; 这么写的。
&amp;gt;
&amp;gt; 如果需要，它们可以
&amp;gt; 跨越多个段落。

### 代码块

使用4个空格缩进或使用三个反引号 ``` 来创建代码块。
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;import time
# 快，数到十！
for i in range(10):
    # (但不要 *太* 快)
    time.sleep(0.5)
    print i
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;其他&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E5%85%B6%E4%BB%96&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;链接&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是一个指向 &lt;a href=&quot;http://foo.bar/&quot;&gt;某个网站&lt;/a&gt; 的链接。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;这是一个指向 [某个网站](http://foo.bar) 的链接。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;脚注&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是一个脚注 &lt;a href=&quot;%E8%84%9A%E6%B3%A8%E6%96%87%E6%9C%AC%E6%94%BE%E5%9C%A8%E8%BF%99%E9%87%8C%E3%80%82&quot;&gt;^1&lt;/a&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;这是一个脚注 [^1]。

[^1]: 脚注文本放在这里。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;水平分割线&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;表格&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;尺寸   材质      颜色
---    ---       ---
9      皮革      棕色
10     麻帆布    自然色
11     玻璃      透明

Table: 鞋子、尺码及其材质
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;数学公式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;行内公式：$\omega = d\phi / dt$&lt;/p&gt;
&lt;p&gt;块级公式： $I = \int \rho R^{2} dV$&lt;/p&gt;
&lt;h3&gt;嵌入视频&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E5%B5%8C%E5%85%A5%E8%A7%86%E9%A2%91&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;只需从 YouTube 或其他平台复制嵌入代码（embed code），然后将其粘贴到 Markdown 文件中即可。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: Include Video in the Post
published: 2023-10-19
// ...
---

&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;YouTube&lt;/h4&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h4&gt;Bilibili&lt;/h4&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=BV1fK4y1s7Qf&amp;amp;p=1&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h3&gt;扩展功能&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E6%89%A9%E5%B1%95%E5%8A%9F%E8%83%BD&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;GitHub 存储库卡片&lt;a href=&quot;https://zrnq.cn/posts/markdown-extended/#github-%E5%AD%98%E5%82%A8%E5%BA%93%E5%8D%A1%E7%89%87&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;::github{repo=&quot;worhllo2/Blog-fuwari&quot;}&lt;/p&gt;
&lt;p&gt;使用代码创建 GitHub 存储库卡片。 &lt;code&gt;::github{repo=&quot;&amp;lt;owner&amp;gt;/&amp;lt;repo&amp;gt;&quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{repo=&quot;saicaca/fuwari&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;警告&lt;a href=&quot;https://zrnq.cn/posts/markdown-extended/#%E8%AD%A6%E5%91%8A&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;支持以下类型的警告: &lt;code&gt;note&lt;/code&gt; &lt;code&gt;tip&lt;/code&gt; &lt;code&gt;important&lt;/code&gt; &lt;code&gt;warning&lt;/code&gt; &lt;code&gt;caution&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note
突出显示用户应该考虑的信息，即使在浏览时也是如此。
:::&lt;/p&gt;
&lt;p&gt;:::tip
帮助用户取得更大成功的可选信息。
:::&lt;/p&gt;
&lt;p&gt;:::important
用户成功所需的关键信息。
:::&lt;/p&gt;
&lt;p&gt;:::warning
由于潜在风险，需要立即用户关注的关键内容。
:::&lt;/p&gt;
&lt;p&gt;:::caution
行动的负面潜在后果。
:::&lt;/p&gt;
&lt;h4&gt;Basic Syntax&lt;a href=&quot;https://zrnq.cn/posts/markdown-extended/#basic-syntax&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;:::note
突出显示用户应该考虑的信息，即使在浏览时也是如此。
:::

:::tip
帮助用户取得更大成功的可选信息。
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自定义标题&lt;a href=&quot;https://zrnq.cn/posts/markdown-extended/#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%87%E9%A2%98&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;警告的标题可以自定义。&lt;/p&gt;
&lt;p&gt;:::note[我的自定义标题]
这是带有自定义标题的注释。
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::note[我的自定义标题]
这是带有自定义标题的注释。
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub 语法&lt;a href=&quot;https://zrnq.cn/posts/markdown-extended/#github-%E8%AF%AD%E6%B3%95&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
GitHub语法也受支持。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; [!NOTE]
&amp;gt; GitHub语法也受支持。

&amp;gt; [!TIP]
&amp;gt; GitHub语法也受支持。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;隐藏内容 (Spoiler)&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E9%9A%90%E8%97%8F%E5%86%85%E5%AE%B9-spoiler&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;您可以在文本中添加隐藏内容，点击后才会显示。内容区域也支持 &lt;strong&gt;Markdown&lt;/strong&gt; 语法。&lt;/p&gt;
&lt;p&gt;这部分内容 :spoiler[是隐藏的 &lt;strong&gt;嘿嘿&lt;/strong&gt;]!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;这部分内容 :spoiler[是隐藏的 **嘿嘿**]!
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;代码块高级功能 (Expressive Code)&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E4%BB%A3%E7%A0%81%E5%9D%97%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD-expressive-code&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本模板使用 &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt; 来增强代码块的显示效果。&lt;/p&gt;
&lt;h3&gt;语法高亮&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E8%AF%AD%E6%B3%95%E9%AB%98%E4%BA%AE&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;常规语法高亮&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1console.log(&apos;这段代码被语法高亮了！&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;渲染 ANSI 转义序列&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ANSI colors:
- Regular: Red Green Yellow Blue Magenta Cyan
- Bold:    Red Green Yellow Blue Magenta Cyan
- Dimmed:  Red Green Yellow Blue Magenta Cyan

256 colors (showing colors 160-177):
160 161 162 163 164 165
166 167 168 169 170 171
172 173 174 175 176 177

Full RGB colors:
ForestGreen - RGB(34, 139, 34)

Text formatting: Bold Dimmed Italic Underline
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;编辑器与终端窗口边框&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E7%BC%96%E8%BE%91%E5%99%A8%E4%B8%8E%E7%BB%88%E7%AB%AF%E7%AA%97%E5%8F%A3%E8%BE%B9%E6%A1%86&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;代码编辑器边框&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;使用 title 属性的例子&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;终端窗口边框&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;这个终端窗口没有标题&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;文本与行标记&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E6%96%87%E6%9C%AC%E4%B8%8E%E8%A1%8C%E6%A0%87%E8%AE%B0&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;标记整行与行范围&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 第 1 行 - 通过行号标记
// 第 2 行
// 第 3 行
// 第 4 行 - 通过行号标记
// 第 5 行
// 第 6 行
// 第 7 行 - 通过范围 &quot;7-8&quot; 标记
// 第 8 行 - 通过范围 &quot;7-8&quot; 标记
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;选择标记类型 (mark, ins, del)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;这行被标记为删除&apos;)
  // 这行和下一行被标记为插入
  console.log(&apos;这是第二行插入的内容&apos;)

  return &apos;这行使用默认的中性标记类型&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;使用类似 diff 的语法&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;这行将被标记为插入
这行将被标记为删除
这是一行常规文本
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;标记行内指定文本&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  // 标记行内的任何指定文本
  return &apos;支持对指定文本的多个匹配项进行标记&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;使用正则表达式&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;单词 yes 和 yep 会被标记。&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自动换行&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E8%87%AA%E5%8A%A8%E6%8D%A2%E8%A1%8C&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;为代码块配置自动换行&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 自动换行的例子
function getLongString() {
  return &apos;这是一个非常非常长的字符串，除非容器特别宽，否则很可能无法在可用空间内完全显示&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;可折叠区域&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E5%8F%AF%E6%8A%98%E5%8F%A0%E5%8C%BA%E5%9F%9F&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;通过 &lt;code&gt;collapse&lt;/code&gt; 属性可以折叠指定的代码行。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 这部分样板代码将被折叠
import { someBoilerplateEngine } from &apos;@example/some-boilerplate&apos;
import { evenMoreBoilerplate } from &apos;@example/even-more-boilerplate&apos;

const engine = someBoilerplateEngine(evenMoreBoilerplate())

// 这部分代码默认可见
engine.doSomething(1, 2, 3)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;行号&lt;a href=&quot;https://blog.moeku.org/posts/guide/#%E8%A1%8C%E5%8F%B7&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;显示行号&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 这个代码块会显示行号
console.log(&apos;来自第 2 行的问候！&apos;)
console.log(&apos;我在第 3 行&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;更改起始行号&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;来自第 5 行的问候！&apos;)
console.log(&apos;我在第 6 行&apos;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>为Fuwari博客添加文章置顶与置底功能</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E6%96%87%E7%AB%A0%E7%BD%AE%E9%A1%B6%E4%B8%8E%E7%BD%AE%E5%BA%95/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E6%96%87%E7%AB%A0%E7%BD%AE%E9%A1%B6%E4%B8%8E%E7%BD%AE%E5%BA%95/</guid><description>本文将逐步说明如何通过修改 src/content/config.ts 和 src/utils/content-utils.ts 实现 Fuwari 博客的文章置顶（Top）与置底（Bottom）功能。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在内容密集的博客中，某些文章可能需要更高的曝光度（如公告、指南）或更低的优先级（如归档、旧闻）。为此，我们为 &lt;strong&gt;Fuwari 博客&lt;/strong&gt; 新增了 &lt;strong&gt;文章置顶（Top）与置底（Bottom）&lt;/strong&gt; 功能。本文将逐步说明如何通过修改主题配置实现这一能力。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;架构&lt;/h2&gt;
&lt;p&gt;基于你正在浏览的 &lt;a href=&quot;https://www.google.com/search?q=http://localhost:4321/posts/fuwari%25E5%258D%259A%25E5%25AE%25A2%25E6%2594%25B9%25E9%2580%25A0%25E8%25AE%25A1%25E5%2588%2592%25E6%2596%2587%25E7%25AB%25A0%25E7%25BD%25AE%25E9%25A1%25B6%25E4%25B8%258E%25E7%25BD%25AE%25E5%25BA%2595/&quot;&gt;Fuwari 博客改造计划：文章置顶与置底&lt;/a&gt;，该功能的项目架构可以拆解为&lt;strong&gt;元数据定义、逻辑处理、内容应用&lt;/strong&gt;三个层面。&lt;/p&gt;
&lt;p&gt;这种架构的核心思想是：&lt;strong&gt;通过在 Markdown 的 Frontmatter 中注入权重因子，改变静态生成的排序算法。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;1. 数据结构层 (Data Schema)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;位置&lt;/strong&gt;：&lt;code&gt;src/content.config.ts&lt;/code&gt; (或旧版的 &lt;code&gt;src/content/config.ts&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;这是架构的“地基”。通过 Zod 模式为文章增加一个可选的优先级字段。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;新增字段&lt;/strong&gt;：&lt;code&gt;order&lt;/code&gt; (类型: &lt;code&gt;number&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;语义约定&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1&lt;/code&gt;：置顶 (Top)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt;：默认 (Normal)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-1&lt;/code&gt;：置底 (Bottom)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 逻辑处理层 (Logic Layer)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;位置&lt;/strong&gt;：&lt;code&gt;src/utils/content-utils.ts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这是架构的“大脑”，负责重写 &lt;code&gt;getSortedPosts&lt;/code&gt; 函数。排序逻辑由单一的“时间维度”变为**“权重 + 时间”的双重维度**。&lt;/p&gt;
&lt;h4&gt;排序算法伪代码：&lt;/h4&gt;
&lt;p&gt;$$Score = (Order \times \infty) + Timestamp$$&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;第一优先级&lt;/strong&gt;：比较 &lt;code&gt;order&lt;/code&gt; 字段。数值大的（置顶）排在前面。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第二优先级&lt;/strong&gt;：当 &lt;code&gt;order&lt;/code&gt; 相同时，比较 &lt;code&gt;published&lt;/code&gt; 日期。最近发布的排在前面。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3. 内容声明层 (Content Layer)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;位置&lt;/strong&gt;：&lt;code&gt;src/content/posts/*.md&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这是架构的“输入端”。开发者在编写文章时，通过 YAML 语法声明权重。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: &quot;我的置顶公告&quot;
published: 2024-01-01
order: 1  # 显式声明置顶
---
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;架构流程图&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;读取阶段&lt;/strong&gt;：Astro 调用 &lt;code&gt;getCollection(&apos;posts&apos;)&lt;/code&gt; 获取所有原始 Markdown 数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;计算阶段&lt;/strong&gt;：&lt;code&gt;content-utils.ts&lt;/code&gt; 执行 &lt;code&gt;sort()&lt;/code&gt; 插件。
&lt;ul&gt;
&lt;li&gt;如果 $A.order &amp;gt; B.order$，则 A 排在 B 前。&lt;/li&gt;
&lt;li&gt;如果 $A.order == B.order$，比较 $Date(A)$ 与 $Date(B)$。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;渲染阶段&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;首页/列表页&lt;/strong&gt;：按计算后的顺序循环渲染卡片。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;上下文导航&lt;/strong&gt;：由于排序已变，文章底部的“上一篇/下一篇”链接也会自动根据新顺序重新绑定，确保阅读体验连贯。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;实操&lt;/h2&gt;
&lt;h3&gt;第一步：扩展内容配置字段&lt;a href=&quot;https://blog.7003410.xyz/posts/post-pinning-feature/#%E7%AC%AC%E4%B8%80%E6%AD%A5%E6%89%A9%E5%B1%95%E5%86%85%E5%AE%B9%E9%85%8D%E7%BD%AE%E5%AD%97%E6%AE%B5&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;首先，在 &lt;code&gt;src/content/config.ts&lt;/code&gt; 中为文章元数据添加 &lt;code&gt;order&lt;/code&gt; 字段，用于标识文章的显示优先级：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { defineCollection, z } from &quot;astro:content&quot;;

const postsCollection = defineCollection({
  schema: z.object({
    title: z.string(),
    published: z.date(),
    updated: z.date().optional(),
    draft: z.boolean().optional().default(false),
    description: z.string().optional().default(&quot;&quot;),
    image: z.string().optional().default(&quot;&quot;),
    tags: z.array(z.string()).optional().default([]),
    category: z.string().optional().nullable().default(&quot;&quot;),
    lang: z.string().optional().default(&quot;&quot;),
    order: z.number().default(0), // 新增字段：0=默认, 1=置顶, -1=置底
    /* For internal use */
    prevTitle: z.string().default(&quot;&quot;),
    prevSlug: z.string().default(&quot;&quot;),
    nextTitle: z.string().default(&quot;&quot;),
    nextSlug: z.string().default(&quot;&quot;),
  }),
});

export const collections = {
  posts: postsCollection,
};
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;说明&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;order: 1&lt;/code&gt; 表示该文章将被置顶；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;order: -1&lt;/code&gt; 表示置底；&lt;/li&gt;
&lt;li&gt;默认值 &lt;code&gt;0&lt;/code&gt; 保持原有排序行为。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h3&gt;第二步：调整文章排序逻辑&lt;a href=&quot;https://blog.7003410.xyz/posts/post-pinning-feature/#%E7%AC%AC%E4%BA%8C%E6%AD%A5%E8%B0%83%E6%95%B4%E6%96%87%E7%AB%A0%E6%8E%92%E5%BA%8F%E9%80%BB%E8%BE%91&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;接下来，修改 &lt;code&gt;src/utils/content-utils.ts&lt;/code&gt; 中的排序函数，使文章按 &lt;code&gt;order&lt;/code&gt; 优先级排序，再按发布时间降序排列：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async function getRawSortedPosts() {
  const allBlogPosts = await getCollection(&quot;posts&quot;, ({ data }) =&amp;gt; {
    return import.meta.env.PROD ? data.draft !== true : true;
  });

  // 自定义排序逻辑
  const sorted = allBlogPosts.sort((a, b) =&amp;gt; {
    // 第一优先级：按 order 字段排序（1 &amp;gt; 0 &amp;gt; -1）
    if (a.data.order !== b.data.order) {
      return b.data.order - a.data.order; // 降序：置顶(1)在前，置底(-1)在后
    }

    // 第二优先级：order 相同时，按发布日期倒序（新文章在前）
    const dateA = new Date(a.data.published);
    const dateB = new Date(b.data.published);
    return dateA &amp;gt; dateB ? -1 : 1;
  });

  return sorted;
}

export async function getSortedPosts() {
  const sorted = await getRawSortedPosts();

  // 保持原有的前后文章链接逻辑不变
  for (let i = 1; i &amp;lt; sorted.length; i++) {
    sorted[i].data.nextSlug = sorted[i - 1].slug;
    sorted[i].data.nextTitle = sorted[i - 1].data.title;
  }
  for (let i = 0; i &amp;lt; sorted.length - 1; i++) {
    sorted[i].data.prevSlug = sorted[i + 1].slug;
    sorted[i].data.prevTitle = sorted[i + 1].data.title;
  }

  return sorted;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第三步 ： 添加置顶图标提示&lt;/h3&gt;
&lt;p&gt;在 src/components/PostCard.astro 中，插入置顶图标的代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{entry.data.order === 1 &amp;amp;&amp;amp; &amp;lt;Icon class=&quot;inline text-[var(--primary)] mr-2 -translate-y-1&quot; name=&quot;material-symbols:keep-outline-rounded&quot; /&amp;gt;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它是如何实现置顶符号提示的？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;条件渲染：
在渲染文章标题之前，程序会检查 entry.data.order 的值。如果其值恰好等于 1，就会渲染一个图标。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;图标选择：
使用的是 material-symbols:keep-outline-rounded 图标，这通常是一个类似“图钉”或“书签”的图标（在 Material
Symbols 中 keep 对应的是图钉）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;注意事项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目前代码中的逻辑是 entry.data.order === 1。这意味着：
&lt;ul&gt;
&lt;li&gt;如果 order: 1，会显示图标。&lt;/li&gt;
&lt;li&gt;如果 order: 2 或更大，虽然文章排在更前面，但不会显示这个图标。&lt;/li&gt;
&lt;li&gt;如果 order: -1 (置底)，自然也不会显示图标。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你希望所有大于 0 的 order 都显示置顶图标，可以将该条件改为 entry.data.order &amp;gt; 0。&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;使用方式&lt;a href=&quot;https://blog.7003410.xyz/posts/post-pinning-feature/#%E4%BD%BF%E7%94%A8%E6%96%B9%E5%BC%8F&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;在任意 Markdown 文章的 Frontmatter 中添加 &lt;code&gt;order&lt;/code&gt; 字段即可：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 重要公告
order: 1  # 置顶
published: 2025-11-01
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: 旧版使用说明
order: -1  # 置底
published: 2023-05-20
---
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;本文转载说明&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;原文标题：&lt;/strong&gt; &lt;a href=&quot;https://blog.7003410.xyz/posts/post-pinning-feature/&quot;&gt;文章置顶与置底：Fuwari博客的功能增强（一）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原文作者：&lt;/strong&gt; &lt;a href=&quot;https://blog.7003410.xyz/posts/post-pinning-feature/&quot;&gt;晓正杨&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;发布日期：&lt;/strong&gt; 2025-11-01&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;许可协议：&lt;/strong&gt; &lt;a href=&quot;https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans&quot;&gt;CC BY-NC-SA 4.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;转载备注：&lt;/strong&gt; 本文出于技术交流目的进行转载，转载请遵循原作者指定的授权协议。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
</content:encoded></item><item><title>如何实现 Word 添加页码且首页不显示</title><link>https://fuwari.vercel.app/posts/word-%E6%B7%BB%E5%8A%A0%E9%A1%B5%E7%A0%81%E6%93%8D%E4%BD%9C%E6%95%99%E7%A8%8B/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/word-%E6%B7%BB%E5%8A%A0%E9%A1%B5%E7%A0%81%E6%93%8D%E4%BD%9C%E6%95%99%E7%A8%8B/</guid><description>办公必备技巧：教你如何在 Word 中设置“首页不同”，实现封面无页码、正文从第一页开始计数的专业排版效果。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;首先，打开文档，点击顶部菜单栏的【插入】选项卡，在 “页眉和页脚” 功能区找到【页码】按钮（图标是一个小书本加数字）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击【页码】下拉菜单，根据需求选择页码的位置，比如 “页面底端”“页面顶端” 或 “页边距”。这里以 “页面底端” 为例，选择一个你喜欢的页码样式（比如普通数字居中、外侧等）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;此时，所有页面（包括首页）都会显示页码，但我们需要让首页不显示，接着看下一步！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在【设计】选项卡的 “选项” 功能区，找到【首页不同】复选框，勾选它！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果希望从第二页开始页码为 “1”（即首页无页码，第二页是第 1 页）。则在【页眉和页脚工具 - 设计】选项卡中，点击【页码】下拉菜单，选择【设置页码格式】。在弹出的对话框中，勾选【起始页码】，并确保数值为 “0”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击【确定】，此时第二页会显示 “1”，后续页面依次递增。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;设置完成后，点击【页眉和页脚工具 - 设计】选项卡中的【关闭页眉和页脚】按钮，或直接双击文档正文区域，回到正常编辑状态。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>DevSidecar 开发者边车工具：GitHub 加速与网络优化指南</title><link>https://fuwari.vercel.app/posts/github%E8%BF%9E%E6%8E%A5%E7%A5%9E%E5%99%A8dev-sidrcar/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/github%E8%BF%9E%E6%8E%A5%E7%A5%9E%E5%99%A8dev-sidrcar/</guid><description>解决 GitHub 访问难、下载慢的利器。本文详细介绍了 DevSidecar 的核心特性、安装步骤、运行模式对比，并包含开启隐藏“增强模式”的进阶技巧。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;DevSidecar&lt;/strong&gt; 是一款为开发者设计的辅助工具，通过本地代理将 HTTPS 请求重定向到国内加速通道，核心目标是解决 &lt;strong&gt;GitHub&lt;/strong&gt; 等开发相关网站访问难的问题。&lt;/p&gt;
&lt;h2&gt;1. 核心特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GitHub 全方位加速&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;支持 Release 包、源码、Zip 文件下载加速。&lt;/li&gt;
&lt;li&gt;支持 &lt;code&gt;git clone&lt;/code&gt;、&lt;code&gt;git push&lt;/code&gt; 加速及头像显示。&lt;/li&gt;
&lt;li&gt;解决 README 中图片无法加载的问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DNS 优选&lt;/strong&gt;：智能解析最佳 IP 地址，绕过 DNS 污染，提升访问速度。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;请求拦截&lt;/strong&gt;：自动将打不开的网站代理到镜像站点，具备失败自动切换机制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stack Overflow 加速&lt;/strong&gt;：代理 Google CDN 资源，解决验证码（recaptcha）加载慢的问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm 加速&lt;/strong&gt;：支持一键切换淘宝镜像或开启 npm 代理，解决插件安装失败问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 快速开始&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;第一步：下载与安装&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;根据您的操作系统选择对应的安装包：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Windows&lt;/strong&gt;: 下载 &lt;code&gt;DevSidecar-x.x.x-windows-universal.exe&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;macOS&lt;/strong&gt;: 下载 &lt;code&gt;DevSidecar-x.x.x-macos-universal.dmg&lt;/code&gt;（需在安全隐私设置中允许安装）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Linux&lt;/strong&gt;: 提供 &lt;code&gt;.deb&lt;/code&gt; 和 &lt;code&gt;.AppImage&lt;/code&gt; 格式。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;第二步：安装根证书（关键）&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;首次启动时，程序会提示安装&lt;strong&gt;根证书&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：由于 DS 需要拦截 HTTPS 请求进行重定向，必须信任其本地生成的证书。证书为本地随机生成，不经过云端，安全性较高。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;strong&gt;第三步：开始加速&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;直接在浏览器中访问 &lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;、&lt;a href=&quot;https://huggingface.co&quot;&gt;HuggingFace&lt;/a&gt; 或 &lt;a href=&quot;https://hub.docker.com&quot;&gt;Docker Hub&lt;/a&gt; 即可感受速度提升。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 运行模式对比&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;安全模式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;仅开启 DNS 优选，无需安装证书。&lt;/td&gt;
&lt;td&gt;仅需基础防污染，对安全性要求极高。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;默认模式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;开启拦截与 SNI 直连，需安装证书。&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;推荐模式&lt;/strong&gt;，可流畅访问 GitHub 大部分资源。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;增强模式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;修改配置文件开启隐藏功能。&lt;/td&gt;
&lt;td&gt;进阶开发者，需访问更多受限资源。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 避坑指南与注意事项 ⚠️&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;异常断网处理&lt;/strong&gt;：如果 DS 在开启状态下随电脑强制关机/重启，可能会导致系统代理未重置而无法上网。&lt;strong&gt;解决方法&lt;/strong&gt;：手动重新打开一次 DS 即可恢复。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;软件冲突&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Watt Toolkit (Steam++)&lt;/strong&gt;：若共用，请将 Watt Toolkit 设为 &lt;code&gt;Hosts&lt;/code&gt; 模式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VPN/梯子&lt;/strong&gt;：DS 旨在为没有代理工具的用户提供“自行车”。如果你已有成熟的代理环境，建议关闭 DS 以免冲突。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;浏览器兼容性&lt;/strong&gt;：FireFox（火狐）浏览器通常不走系统证书库，可能需要手动导入 DS 的根证书。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;DevSidecar 增强模式（彩蛋）开启指南&lt;/h2&gt;
&lt;p&gt;“增强模式”是 DevSidecar 隐藏的进阶功能，本质上是一个简单的网络加速辅助工具。由于敏感原因，官方在界面上默认隐藏了开关，需要通过修改本地配置文件来手动激活。&lt;/p&gt;
&lt;h3&gt;核心步骤：解谜与配置修改&lt;/h3&gt;
&lt;h4&gt;1. 查找配置文件路径&lt;/h4&gt;
&lt;p&gt;提示在软件首页左下角，即去dev-sidecar项目源码里面搜索“//TODO”，最终分会到达packages/core/index.js这个文件中，看到以下提示&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;module.exports = require(&apos;./src&apos;)
// TODO  这是一个解谜游戏 ↓ ↓ ↓ ↓ ↓ ↓ ，如果你破解了它，请不要公开，好好用它来学习和查资料吧（特别注意：为了你的人身安全，请不要用它来查看和发表不当言论，你懂得）。
/**
\u0061\u0048\u0052\u0030\u0063\u0044\u006f\u0076\u004c\u0032\u0052\u006c\u0064\u0069\u0031\u007a\u0061\u0057\u0052\u006c\u0059\u0032\u0046\u0079\u004c\u006d\u0052\u0076\u0059\u0032\u0031\u0070\u0063\u006e\u004a\u0076\u0063\u0069\u0035\u006a\u0062\u0069\u0039\u0035\u0062\u0033\u0056\u006d\u0061\u0057\u0035\u006b\u0061\u0058\u0051\u0076\u0061\u0057\u0035\u006b\u005a\u0058\u0067\u0075\u0061\u0048\u0052\u0074\u0062\u0041\u003d\u003d
*/
// 这个项目里有一点点解谜提示： https://github.com/fast-crud/fast-crud  （DevSidecar解谜提示
谜题共三层，前两层是两种不同的编码方式，第三层这里就不剧透了，留一点小乐趣。）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;复制文中的编码，进行&lt;a href=&quot;https://www.toolhelper.cn/EncodeDecode/UnicodeChinese&quot;&gt;Unicode与中文 编码/解码&lt;/a&gt;，会得到&lt;strong&gt;aHR0cDovL2Rldi1zaWRlY2FyLmRvY21pcnJvci5jbi95b3VmaW5kaXQvaW5kZXguaHRtbA==&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再对得到的字符进行&lt;a href=&quot;https://www.toolhelper.cn/EncodeDecode/Base64&quot;&gt;Base64 编码/解码&lt;/a&gt;，会得到&lt;strong&gt;http://dev-sidecar.docmirror.cn/youfindit/index.html&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在搜索框输入得到的链接，下拉点击左下角，会发现有一张透明图片，将该图片保存!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在图片浏览器打开就会出现二维码，手机扫描后就会得到最终答案&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2. 修改配置参数（核心操作）&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;确保 &lt;strong&gt;DevSidecar 软件已完全退出&lt;/strong&gt;（建议在任务栏托盘处右键退出）。&lt;/li&gt;
&lt;li&gt;使用文本编辑器（如 记事本、VS Code 或 TextEdit）打开上述的 &lt;code&gt;setting.json5&lt;/code&gt; 文件。&lt;/li&gt;
&lt;li&gt;在代码中找到以下字段：&lt;pre&gt;&lt;code&gt;&quot;overwall&quot;: false
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;将该值由 &lt;code&gt;false&lt;/code&gt; 修改为 &lt;code&gt;true&lt;/code&gt;：&lt;pre&gt;&lt;code&gt;&quot;overwall&quot;: true
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保存文件&lt;/strong&gt;并关闭编辑器。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h4&gt;3. 重启并验证&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;重新启动 &lt;strong&gt;DevSidecar&lt;/strong&gt; 桌面客户端。&lt;/li&gt;
&lt;li&gt;观察软件界面左侧菜单栏，此时会出现一个新的选项：&lt;strong&gt;“增强功能”&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;在该菜单内，您可以根据提示进一步配置加速节点或使用相关增强服务。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Markdown 语法全解析：从基础到高级进阶</title><link>https://fuwari.vercel.app/posts/markdown%E7%B3%BB%E5%88%97markdown%E8%AF%AD%E6%B3%95%E4%BB%8B%E7%BB%8D/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/markdown%E7%B3%BB%E5%88%97markdown%E8%AF%AD%E6%B3%95%E4%BB%8B%E7%BB%8D/</guid><description>一份详尽的 Markdown 语法参考手册，涵盖基础格式、代码块、数学公式、Mermaid 流程图及 HTML 原生增强样式。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;一、标题&lt;/h2&gt;
&lt;h3&gt;三号&lt;/h3&gt;
&lt;h4&gt;四号&lt;/h4&gt;
&lt;h5&gt;五号标题&lt;/h5&gt;
&lt;h6&gt;六号标题【最低】&lt;/h6&gt;
&lt;h2&gt;二、分割线&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;*号分割线
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;-分割线
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;三、粗体斜体&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;斜体&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;粗体&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;s&gt;删除线&lt;/s&gt;&lt;/p&gt;
&lt;h2&gt;四、超链接和图片&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.baidu.com&quot;&gt;超链接,方法1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.baidu.com&quot;&gt;超链接,方法2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img2.artron.net/artist/A0261635/brt026163505145.jpg&quot; alt=&quot;图片显示的文字&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;五、无序列表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;a
&lt;ul&gt;
&lt;li&gt;b&lt;/li&gt;
&lt;li&gt;b
&lt;ul&gt;
&lt;li&gt;C
&lt;ul&gt;
&lt;li&gt;V&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;B&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;六、有序列表&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;a&lt;/li&gt;
&lt;li&gt;b
&lt;ol&gt;
&lt;li&gt;c&lt;/li&gt;
&lt;li&gt;c&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;七、文字引用&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;使用 &amp;gt; 表示，可以有多个 &amp;gt; 表示层级更深
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;第一层&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第二层
这样跳不下去&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;还可更深&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;这样就跳出去了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;八、行内代码&lt;/h2&gt;
&lt;p&gt;其实上边已经用过很多次，即使用 ` 表示&lt;/p&gt;
&lt;p&gt;&lt;code&gt;这是行内代码 中间可以换行&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;九、代码块&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;​```代码段```
import os
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;十、表格&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;商品name&lt;/th&gt;
&lt;th&gt;price&lt;/th&gt;
&lt;th&gt;num&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;靠左&lt;/td&gt;
&lt;td&gt;靠右&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;十一、流程图&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;解释一下这个例子：&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;mermaid&lt;/code&gt;是Mermaid语言的标记。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;graph TD;&lt;/code&gt;指定了图的类型和方向，这里是从上到下（Top Down）的有向图（Directed Graph）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;A--&amp;gt;B;&lt;/code&gt;和&lt;code&gt;A--&amp;gt;C;&lt;/code&gt;表示两个箭头从A出发分别指向B和C。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;B--&amp;gt;D;&lt;/code&gt;和&lt;code&gt;C--&amp;gt;D;&lt;/code&gt;表示两个箭头从B和C出发分别指向D。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;mermaid
graph TD
A(工业用地效率)--&amp;gt;B1(土地利用强度)
A--&amp;gt;B2(土地经济效益)
B1--&amp;gt;C1(容积率)
B1--&amp;gt;C2(建筑系数)
B1--&amp;gt;C3(亩均固定资本投入)
B2--&amp;gt;D1(亩均工业产值)
B2--&amp;gt;D2(亩均税收)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h1&gt;高级语法&lt;/h1&gt;
&lt;h2&gt;数学公式&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;$\ce{Hg^2+ -&amp;gt;[I-] HgI2 -&amp;gt;[I-] [Hg^{II}I4]^2-}$&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$H(D_2) = -\left(\frac{2}{4}\log_2 \frac{2}{4} + \frac{2}{4}\log_2 \frac{2}{4}\right) = 1$&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  \begin{pmatrix}
  1 &amp;amp; a_1 &amp;amp; a_1^2 &amp;amp; \cdots &amp;amp; a_1^n \\
  1 &amp;amp; a_2 &amp;amp; a_2^2 &amp;amp; \cdots &amp;amp; a_2^n \\
  \vdots &amp;amp; \vdots &amp;amp; \vdots &amp;amp; \ddots &amp;amp; \vdots \\
  1 &amp;amp; a_m &amp;amp; a_m^2 &amp;amp; \cdots &amp;amp; a_m^n \\
  \end{pmatrix}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;目录&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;@[toc] 或 [toc]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;HTML原生语句&lt;/h2&gt;
&lt;p&gt;&amp;lt;span style=&quot;display:block; text-align:right; color:orangered;&quot;&amp;gt;橙色居右&amp;lt;/span&amp;gt; &amp;lt;span style=&quot;display:block; text-align:center; color:orangered;&quot;&amp;gt;橙色居中&amp;lt;/span&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;font face=&quot;黑体&quot;&amp;gt;我是黑体字&amp;lt;/font&amp;gt; &amp;lt;font face=&quot;微软雅黑&quot;&amp;gt;我是微软雅黑&amp;lt;/font&amp;gt; &amp;lt;font face=&quot;STCAIYUN&quot;&amp;gt;我是华文彩云&amp;lt;/font&amp;gt; &amp;lt;font color=&quot;#0099ff&quot; size=&quot;7&quot; face=&quot;黑体&quot;&amp;gt;color=#0099ff size=72 face=&quot;黑体&quot;&amp;lt;/font&amp;gt; &amp;lt;font color=&quot;#00ffff&quot; size=&quot;72&quot;&amp;gt;color=#00ffff&amp;lt;/font&amp;gt; &amp;lt;font color=&quot;gray&quot; size=&quot;72&quot;&amp;gt;color=gray&amp;lt;/font&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;颜色的英文单词：&lt;/p&gt;
&lt;p&gt;red（赤）
orange（橙）
yellow（黄）
green（绿）
cyan（青）
blue（蓝）
purple（紫）
字体的英文单词：&lt;/p&gt;
&lt;p&gt;rm（罗马字体）
it （意大利字体）
bf（黑体）
sl （斜体）
sf （等线体）
sc （小体大写字母）
tt （打字机字体）
mit （数学斜体）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;转义&lt;/h2&gt;
&lt;p&gt;在 Markdown 编辑器里面使用了很多特殊符号来表示特定的意义，该特殊符号将不再显示，这个时候就需要转义字符——反斜杠，如下：&lt;/p&gt;
&lt;p&gt;**转义特殊符号正常显示**&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;无转义特殊符号无法正常显示&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>为项目添加一键部署按钮</title><link>https://fuwari.vercel.app/posts/%E4%B8%BA%E9%A1%B9%E7%9B%AE%E6%B7%BB%E5%8A%A0%E4%B8%80%E9%94%AE%E9%83%A8%E7%BD%B2%E6%8C%89%E9%92%AE---thws-blog/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E4%B8%BA%E9%A1%B9%E7%9B%AE%E6%B7%BB%E5%8A%A0%E4%B8%80%E9%94%AE%E9%83%A8%E7%BD%B2%E6%8C%89%E9%92%AE---thws-blog/</guid><description>本文介绍了如何利用 Markdown 语法在 GitHub 仓库中集成一键部署按钮，重点讲解了 EdgeOne Pages、Vercel 及 Netlify 的配置方法，旨在降低项目使用门槛。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;你一定在 GitHub 上见过不少项目都带有这样的一键部署按钮： &lt;img src=&quot;https://vercel.com/button&quot; alt=&quot;vercel&quot; /&gt; &lt;img src=&quot;https://www.netlify.com/img/deploy/button.svg&quot; alt=&quot;netlify&quot; /&gt; &lt;img src=&quot;https://cdnstatic.tencentcs.com/edgeone/pages/deploy.svg&quot; alt=&quot;edgeone&quot; /&gt; &lt;img src=&quot;https://deploy.workers.cloudflare.com/button&quot; alt=&quot;cloudflare&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这些按钮不仅视觉炫酷美观，更重要的是——&lt;strong&gt;只需点击一下，就能直接跳转到对应云平台的部署页面&lt;/strong&gt;，省去了手动 fork、clone、配置等繁琐步骤，极大降低了项目的使用门槛。&lt;/p&gt;
&lt;p&gt;这类功能最常用于静态网站、前端应用类项目，但也不限于此。例如雨云也提供了类似的一键部署按钮&lt;img src=&quot;https://rainyun-apps.cn-nb1.rains3.com/materials/deploy-on-rainyun-cn.svg&quot; alt=&quot;通过雨云一键部署&quot; /&gt;不过需要先上架至其应用商店。相比之下，Vercel、Netlify、EdgeOne Pages这几大平台则更加开放：&lt;strong&gt;你只需将部署链接中的仓库参数替换为自己的 GitHub 地址，即可立即启用一键部署能力&lt;/strong&gt;，让你的项目在几分钟内部署到云端。&lt;/p&gt;
&lt;h2&gt;原理&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#%E5%8E%9F%E7%90%86&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;这些一键部署按钮本质上是一种通过Markdown语法实现的链接，当用户点击该按钮时，会跳转到目标云服务提供商的部署界面。 这种按钮的通用语法格式为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[![ Deploy Button Text ](SVG Image URL)](Deployment URL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;其中，SVG图片由云服务提供商提供，就是我们外观上看到的按钮样式&lt;/strong&gt;。 部署链接则指向云服务提供商的部署页面，并可能包含一些查询参数，用于指定要部署的GitHub仓库地址，甚至还能包含构建命令、输出目录等信息。&lt;/p&gt;
&lt;h2&gt;添加&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#%E6%B7%BB%E5%8A%A0&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;EdgeOne Pages&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#edgeone-pages&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;基础用法&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;只需将以下 Markdown 代码添加到你 GitHub 仓库的 &lt;code&gt;README.md&lt;/code&gt; 文件中，把&lt;code&gt;YOUR_REPO_URL&lt;/code&gt;替换为你的项目地址即可为项目启用 &lt;strong&gt;EdgeOne Pages 一键部署&lt;/strong&gt; 功能：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[![使用 EdgeOne Pages 部署](https://cdnstatic.tencentcs.com/edgeone/pages/deploy.svg)](https://edgeone.ai/pages/new?repository-url=YOUR_REPO_URL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以 &lt;a href=&quot;https://github.com/H2O-ME/EdgeOne-Random-Picture&quot;&gt;EdgeOne-Random-Picture&lt;/a&gt; 项目为例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[![使用 EdgeOne Pages 部署](https://cdnstatic.tencentcs.com/edgeone/pages/deploy.svg)](https://edgeone.ai/pages/new?repository-url=https://github.com/H2O-ME/EdgeOne-Random-Picture)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;高级用法：带构建参数&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95%E5%B8%A6%E6%9E%84%E5%BB%BA%E5%8F%82%E6%95%B0&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;EdgeOne Pages 支持通过 URL 参数精细控制部署行为：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Search 参数名称&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;template&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;通过 Pages 官方模板来部署的模板名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;repository-name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Github 仓库名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;repository-url&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;通过其他 GitHub 仓库来部署的仓库地址&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;project-name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;项目名称&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;build-command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;构建命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;install-command&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安装命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;output-directory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;构建后产物的输出目录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;root-directory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;构建根目录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;仓库必要的环境变量，如需多个可用英文逗号连接，如：KEY1,KEY2,KEY3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env-description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;跟环境变量相关的描述&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;env-link&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;跟环境变量相关的链接&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;以 &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;saicaca/fuwari&lt;/a&gt;（基于 Astro 的静态博客模板）为例：&lt;/p&gt;
&lt;p&gt;我在该链接指定了以下参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装命令：&lt;code&gt;pnpm install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;构建命令：&lt;code&gt;pnpm run build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;输出目录：&lt;code&gt;dist&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[![使用 EdgeOne Pages 部署](https://cdnstatic.tencentcs.com/edgeone/pages/deploy.svg)](https://edgeone.ai/pages/new?repository-url=https%3A%2F%2Fgithub.com%2Fsaicaca%2Ffuwari&amp;amp;install-command=pnpm%20install&amp;amp;build-command=pnpm%20run%20build&amp;amp;output-directory=dist)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：URL 中的特殊字符（如 &lt;code&gt;/&lt;/code&gt;、空格）需进行 &lt;strong&gt;URL 编码&lt;/strong&gt;（例如 &lt;code&gt;%2F&lt;/code&gt; 代表 &lt;code&gt;/&lt;/code&gt;）&lt;/p&gt;
&lt;h3&gt;Vercel&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#vercel&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;基础用法&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#%E5%9F%BA%E7%A1%80%E7%94%A8%E6%B3%95-1&quot;&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/username/repository)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Vercel 的一键部署按钮也可以直接通过其官方部署链接生成器生成&lt;/strong&gt;，因此如果你需要添加更多的部署参数可以前往&lt;a href=&quot;https://vercel.com/docs/deploy-button&quot;&gt;使用部署按钮&lt;/a&gt;自行生成，无需考虑markdown语法等问题，这里不重新造轮子了。&lt;/p&gt;
&lt;h3&gt;Netlify&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/#netlify&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Netlify 的部署按钮不支持提供 URL 参数控制构建参数，需通过项目的 &lt;code&gt;netlify.toml&lt;/code&gt; 文件配置构建行为。 &lt;strong&gt;Netlify的一键部署按钮链接格式为&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/your-username/your-repo)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;具体示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/H2O-ME/IPFS-img-host)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;转载说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.tianhw.top/posts/one-click-deploy-button/&quot;&gt;为项目添加一键部署按钮 - THW&apos;s Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>给fuwari博客添加AI摘要</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E7%BB%99fuwari%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0ai%E6%91%98%E8%A6%81/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E7%BB%99fuwari%E5%8D%9A%E5%AE%A2%E6%B7%BB%E5%8A%A0ai%E6%91%98%E8%A6%81/</guid><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;现在教程开始！&lt;/h2&gt;
&lt;p&gt;修改文件前请注意备份，防止修改失败无法回退&lt;/p&gt;
&lt;p&gt;新建src/components/misc/AISummary.astro文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
export interface Props {
  content: string;
}

const { content } = Astro.props;

// 如果没有内容，不渲染组件
if (!content || content.trim() === &apos;&apos;) {
  return null;
}
---

{content &amp;amp;&amp;amp; (
  &amp;lt;div class=&quot;ai-summary&quot;&amp;gt;
    &amp;lt;div class=&quot;ai-title&quot;&amp;gt;
      &amp;lt;div class=&quot;ai-title-left&quot;&amp;gt;
        &amp;lt;i&amp;gt;🤖&amp;lt;/i&amp;gt;
        &amp;lt;span class=&quot;ai-title-text&quot;&amp;gt;AI 摘要&amp;lt;/span&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;div class=&quot;ai-tag&quot;&amp;gt;fishcpy AI&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;ai-explanation&quot; data-content={content}&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
)}

&amp;lt;script&amp;gt;
  // 检查当前页面路径是否包含 &quot;posts&quot;
  function isPostsPage() {
    return window.location.pathname.includes(&apos;/posts/&apos;);
  }

  // 全局函数，用于初始化AI打字效果
  function initAITyping() {
    // 只在包含 &quot;posts&quot; 的页面才执行AI总结功能
    if (!isPostsPage()) {
      return;
    }

    // 查找所有AI摘要容器
    const aiSummaryContainers = document.querySelectorAll(&apos;.ai-summary&apos;);
    
    aiSummaryContainers.forEach(container =&amp;gt; {
      const textElement = container.querySelector(&apos;.ai-explanation&apos;);
      
      if (!textElement) {
        return;
      }

      // 检查是否已经初始化过
      if (textElement.hasAttribute(&apos;data-initialized&apos;)) {
        return;
      }

      const content = textElement.getAttribute(&apos;data-content&apos;);
      if (!content) {
        return;
      }

      // 标记为已初始化
      textElement.setAttribute(&apos;data-initialized&apos;, &apos;true&apos;);
      
      // 清空文本内容，准备打字效果
      textElement.textContent = &apos;&apos;;
      textElement.classList.remove(&apos;typing-complete&apos;);
      
      let index = 0;
      const typeSpeed = 30; // 打字速度（毫秒）
      
      function typeWriter() {
        if (index &amp;lt; content.length) {
          textElement.textContent += content.charAt(index);
          index++;
          setTimeout(typeWriter, typeSpeed);
        } else {
          // 打字完成后隐藏光标（通过CSS控制）
          textElement.classList.add(&apos;typing-complete&apos;);
        }
      }
      
      // 延迟开始打字效果
      setTimeout(typeWriter, 800);
    });
  }

  // 页面加载完成时初始化
  function handlePageLoad() {
    setTimeout(initAITyping, 100);
  }

  // 监听页面导航事件（适用于Astro的客户端路由）
  function setupNavigationListeners() {
    // DOMContentLoaded事件
    if (document.readyState === &apos;loading&apos;) {
      document.addEventListener(&apos;DOMContentLoaded&apos;, handlePageLoad);
    } else {
      handlePageLoad();
    }

    // 监听Astro的页面导航事件
    document.addEventListener(&apos;astro:page-load&apos;, handlePageLoad);
    
    // 监听浏览器的popstate事件（后退/前进按钮）
    window.addEventListener(&apos;popstate&apos;, handlePageLoad);
    
    // 监听pushstate和replacestate事件
    const originalPushState = history.pushState;
    const originalReplaceState = history.replaceState;
    
    history.pushState = function() {
      originalPushState.apply(history, arguments);
      setTimeout(handlePageLoad, 100);
    };
    
    history.replaceState = function() {
      originalReplaceState.apply(history, arguments);
      setTimeout(handlePageLoad, 100);
    };
  }

  // 立即设置监听器
  setupNavigationListeners();
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在src/content/config.ts插入下方代码，13行下左右，注意+号要删除&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tags: z.array(z.string()).optional().default([]),
category: z.string().optional().nullable().default(&quot;&quot;),
lang: z.string().optional().default(&quot;&quot;),
+       ai: z.string().optional().default(&quot;&quot;),

/* For internal use */
prevTitle: z.string().default(&quot;&quot;),
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在src/pages/posts/...slug.astro插入下方代码，注意+号要删除&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { profileConfig, siteConfig } from &quot;../../config&quot;;
import { formatDateToYYYYMMDD } from &quot;../../utils/date-utils&quot;;
import Comment from &quot;@components/comment/index.astro&quot;;
+ import AISummary from &quot;@components/misc/AISummary.astro&quot;;

export async function getStaticPaths() {
    const blogEntries = await getSortedPosts();
@@ -84,6 +85,9 @@ const jsonLd = {
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

+            &amp;lt;!-- AI Summary --&amp;gt;
+            {entry.data.description &amp;amp;&amp;amp; &amp;lt;AISummary content={entry.data.description} class=&quot;onload-animation&quot; /&amp;gt;}

&amp;lt;!-- metadata --&amp;gt;
&amp;lt;div class=&quot;onload-animation&quot;&amp;gt;
&amp;lt;PostMetadata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在src/styles/main.css底部添加下方代码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* =================== */
/* 📘 AI 摘要模块样式 */
/* =================== */

.ai-summary {
    background: var(--card-bg);
    border: 1px solid var(--line-divider);
    border-radius: 12px;
    padding: 8px 8px 12px 8px;
    line-height: 1.3;
    flex-direction: column;
    margin-bottom: 16px;
    display: flex;
    gap: 5px;
    position: relative;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    transition: all 0.3s;
}

.ai-summary:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    transform: translateY(-1px);
}

.ai-summary .ai-explanation {
    z-index: 10;
    padding: 8px 12px;
    font-size: 15px;
    line-height: 1.4;
    @apply text-90;
    text-align: justify;
}

/* ✅ 打字机光标动画 */
.ai-summary .ai-explanation::after {
    content: &apos;&apos;;
    display: inline-block;
    width: 8px;
    height: 2px;
    margin-left: 2px;
    @apply bg-black/90 dark:bg-white/90;
    vertical-align: bottom;
    animation: blink-underline 1s ease-in-out infinite;
    transition: all 0.3s;
    position: relative;
    bottom: 3px;
}

/* 打字完成后隐藏光标 */
.ai-summary .ai-explanation.typing-complete::after {
    display: none;
}

.ai-summary .ai-title {
    z-index: 10;
    font-size: 14px;
    display: flex;
    border-radius: 8px;
    align-items: center;
    position: relative;
    padding: 0 12px;
    cursor: default;
    user-select: none;
}

.ai-summary .ai-title .ai-title-left {
    display: flex;
    align-items: center;
    color: var(--primary);
}

.ai-summary .ai-title .ai-title-left i {
    margin-right: 3px;
    display: flex;
    color: var(--primary);
    border-radius: 20px;
    justify-content: center;
    align-items: center;
}

.ai-summary .ai-title .ai-title-left .ai-title-text {
    font-weight: 500;
}

.ai-summary .ai-title .ai-tag {
    color: var(--btn-content);
    font-weight: 300;
    margin-left: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: 0.3s;
}

/* ✅ 打字机光标闪烁动画 */
@keyframes blink-underline {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后在src/styles/variables.styl 大约19行后面添加下方代码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  --page-bg: oklch(0.95 0.01 var(--hue)) oklch(0.16 0.014 var(--hue))
  --card-bg: white oklch(0.23 0.015 var(--hue))

+  // AI Summary 相关变量
+  --ai-title-font-color: #0883b7 #0883b7
+  --ai-maskbg: rgba(255, 255, 255, 0.85) rgba(0, 0, 0, 0.85)
+  --ai-bg: conic-gradient(from 1.5708rad at 50% 50%, #d6b300 0%, #42A2FF 54%, #d6b300 100%) conic-gradient(from 1.5708rad at 50% 50%, rgba(214, 178, 0, 0.46) 0%, rgba(66, 161, 255, 0.53) 54%, rgba(214, 178, 0, 0.49) 100%)
+  --ai-card-secondbg: #f1f3f8 #3e3f41
+  --ai-text: #4c4948 #ffffffb3
+  --ai-secondtext: #3c3c43cc #a1a2b8

  --btn-content: oklch(0.55 0.12 var(--hue)) oklch(0.75 0.1 var(--hue))
  --btn-regular-bg: oklch(0.95 0.025 var(--hue)) oklch(0.33 0.035 var(--hue))
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>使用 CF Workers 搭建 Vless/Trojan 节点并优化</title><link>https://fuwari.vercel.app/posts/%E4%BD%BF%E7%94%A8-cf-workers-%E6%90%AD%E5%BB%BA-vlesstrojan-%E8%8A%82%E7%82%B9%E5%B9%B6%E4%BC%98%E5%8C%96---ad_closenn-%E7%9A%84%E5%B0%8F%E7%AB%99/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E4%BD%BF%E7%94%A8-cf-workers-%E6%90%AD%E5%BB%BA-vlesstrojan-%E8%8A%82%E7%82%B9%E5%B9%B6%E4%BC%98%E5%8C%96---ad_closenn-%E7%9A%84%E5%B0%8F%E7%AB%99/</guid><description>本教程详细介绍了如何利用 Cloudflare Workers 部署 Vless 与 Trojan 协议节点，包含域名绑定、UUID 配置及优选 IP 提速优化方案。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;:::warning&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;本教程仅供学习交流，请在当地法律允许的情况下使用。&lt;/li&gt;
&lt;li&gt;Cloudflare 已在其 &lt;a href=&quot;https://www.cloudflare.com/terms/&quot;&gt;Self-Serve Subscription Agreement | Cloudflare&lt;/a&gt; 中规定：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;(j) use the Services to provide a virtual private network or other similar proxy services.
--- Google Translate:
(j) 使用服务提供虚拟专用网络或其他类似的代理服务。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;h2&gt;前提准备&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;一个域名（免费/付费）&lt;/li&gt;
&lt;li&gt;一个 &lt;a href=&quot;https://dash.cloudflare.com/&quot;&gt;Cloudflare&lt;/a&gt; 账号&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;搭建节点&lt;/h2&gt;
&lt;p&gt;:::important
这里介绍 Vless 版节点搭建。
Vless 版的节点和 Trojan 版的节点部署方法类似，只是换了一个 &lt;code&gt;_worker.js&lt;/code&gt; 文件。需要使用 Trojan 版的可以去勇哥仓库 &lt;a href=&quot;https://github.com/yonggekkk/Cloudflare-vless-trojan/tree/main/Trojan_workers_pages&quot;&gt;https://github.com/yonggekkk/Cloudflare-vless-trojan/tree/main/Trojan_workers_pages&lt;/a&gt; 找到 Trojan 版 Worker 代码。
:::&lt;/p&gt;
&lt;h2&gt;创建 Worker&lt;/h2&gt;
&lt;p&gt;打开 &lt;a href=&quot;https://dash.cloudflare.com/&quot;&gt;Cloudflare Dashboard&lt;/a&gt;，点击右下角的 &lt;strong&gt;计算 (Workers)&lt;/strong&gt;，在新的页面点击 &lt;strong&gt;创建应用程序&lt;/strong&gt;。 &lt;img src=&quot;https://blog.adclosenn.top/_astro/cf-workers-menu.CMt5uhqJ_tmgKn.webp&quot; alt=&quot;cf-workers-menu&quot; /&gt;&lt;/p&gt;
&lt;p&gt;选择 &lt;strong&gt;从 Hello World! 开始&lt;/strong&gt; 右边的 &lt;strong&gt;开始使用&lt;/strong&gt; 按钮：&lt;img src=&quot;https://blog.adclosenn.top/_astro/cf-worker-template-from-helloworld.BQWvZVEN_Z1ipJSv.webp&quot; alt=&quot;cf-worker-template-from-helloworld&quot; /&gt;&lt;/p&gt;
&lt;p&gt;随便取一个 Worker 名字，但是最好不要包括下面的关键词，否则可能会报错 1101。&lt;strong&gt;一般以默认分配的名称作为 Worker 名称即可&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vpn&lt;/li&gt;
&lt;li&gt;vless&lt;/li&gt;
&lt;li&gt;trojan&lt;/li&gt;
&lt;li&gt;edgetunnel&lt;/li&gt;
&lt;li&gt;bpb&lt;/li&gt;
&lt;li&gt;proxy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;点击 &lt;strong&gt;部署&lt;/strong&gt; 按钮。&lt;/p&gt;
&lt;h2&gt;编辑 Worker&lt;/h2&gt;
&lt;p&gt;访问 &lt;a href=&quot;https://raw.githubusercontent.com/yonggekkk/Cloudflare-vless-trojan/refs/heads/main/Vless_workers_pages/_worker%E6%B7%B7%E6%B7%86.js&quot;&gt;https://raw.githubusercontent.com/yonggekkk/Cloudflare-vless-trojan/refs/heads/main/Vless_workers_pages/_worker%E6%B7%B7%E6%B7%86.js&lt;/a&gt; 并复制整个内容。&lt;/p&gt;
&lt;p&gt;返回 Cloudflare Dashboard，点击刚刚创建的 Worker，在控制面板中点击 &lt;strong&gt;编辑代码&lt;/strong&gt;： &lt;img src=&quot;https://blog.adclosenn.top/_astro/cf-workers-editcode-visit-botton.BFWbKkb3_Z1a9jOP.webp&quot; alt=&quot;cf-workers-editcode-visit-botton&quot; /&gt;&lt;/p&gt;
&lt;p&gt;把从上面链接复制来的内容粘贴到 Worker 代码编辑器中。&lt;/p&gt;
&lt;p&gt;访问 &lt;a href=&quot;https://www.uuidgenerator.net/version4&quot;&gt;Online UUID Generator Tool&lt;/a&gt;，点击 &lt;strong&gt;Copy&lt;/strong&gt; 按钮，把你的 UUID v4 复制下来。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;原本部分 worker.js&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let userID = &quot;86c50e3a-5b87-49dd-bd20-03c7f2735e40&quot;; //可以把86c50e3a-5b87-49dd-bd20-03c7f2735e40改为你自定义的uuid
const proxyIPs = [&quot;&quot;]; //&quot;&quot;之间填写proxyip，留空将无法访问CF网站
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;把这个代码中的 &lt;code&gt;86c50e3a-5b87-49dd-bd20-03c7f2735e40&lt;/code&gt; 替换为你的 UUID&lt;br /&gt;
&lt;code&gt;proxyIPs&lt;/code&gt; 可从 &lt;a href=&quot;https://t.me/CMLiussss_channel/84&quot;&gt;https://t.me/CMLiussss_channel/84&lt;/a&gt; 中随便选一个使用。推荐使用 &lt;code&gt;ProxyIP.US.CMLiussss.net&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;配置完成后大概类似于这样&lt;/p&gt;
&lt;p&gt;worker.js&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let userID = &quot;20a4537b-8da9-4bd4-b666-6e29a62345f7&quot;;
const proxyIPs = [&quot;ProxyIP.US.CMLiussss.net&quot;];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.adclosenn.top/_astro/cf-worker-proxy-editor-edited.W5GpThZO_1zBw0A.webp&quot; alt=&quot;cf-worker-proxy-editor-edited&quot; /&gt;&lt;/p&gt;
&lt;p&gt;确认无误后就点击右上角 &lt;strong&gt;部署&lt;/strong&gt; 按钮部署你的 Worker 代码。&lt;br /&gt;
显示 &lt;strong&gt;版本已保存&lt;/strong&gt; 说明部署成功。&lt;/p&gt;
&lt;p&gt;关于 &lt;strong&gt;域和路由-自定义域&lt;/strong&gt; 绑定自定义域名，这里不赘述了。&lt;/p&gt;
&lt;h2&gt;访问 Worker&lt;/h2&gt;
&lt;p&gt;如果是自定义域名，使用 &lt;code&gt;https://自定义域名/你的UUID&lt;/code&gt; 访问你的 Worker。&lt;br /&gt;
如果未绑定域名，点击 Worker Dashboard 的 &lt;strong&gt;访问&lt;/strong&gt; 按钮后在地址栏加入 &lt;code&gt;/你的UUID&lt;/code&gt; 回车进入后台。&lt;br /&gt;
在后台可以查看节点地址。&lt;/p&gt;
&lt;p&gt;如果你使用 V2rayN，可点击 &lt;strong&gt;点击复制链接&lt;/strong&gt;，然后 Ctrl+V 粘贴到 V2rayN 中。&lt;br /&gt;
为了追求速度、延迟、IP地区，可以使用优选后的 Cloudflare Anycast IP 地址。具体方法就是将 &lt;strong&gt;地址 (address)&lt;/strong&gt; 一行从 &lt;code&gt;www.visa.sg&lt;/code&gt; 改为 &lt;code&gt;cf.090227.xyz&lt;/code&gt;。这样IP的地区就会为&lt;strong&gt;新加坡&lt;/strong&gt;或&lt;strong&gt;日本&lt;/strong&gt;，而且真连接延迟会降低： &lt;img src=&quot;https://blog.adclosenn.top/_astro/v2rayn-cf-workers-proxy.0pbV4oiG_Z22tOjM.webp&quot; alt=&quot;v2rayn-cf-workers-proxy&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;编写 Clash 规则&lt;/h2&gt;
&lt;p&gt;:::tip
编写 Clash YAML 配置文件，应用分流规则。**使用 V2rayN 代理工具的可以跳过了。
:::&lt;/p&gt;
&lt;p&gt;如果你要使用优选IP，如 &lt;code&gt;cf.090227.xyz&lt;/code&gt;，需要先编辑一下 vless 链接：&lt;/p&gt;
&lt;p&gt;原版&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vless://20a4537b-8da9-4bd4-b666-6e29a62345f7@www.visa.com.sg:8443?encryption=none&amp;amp;security=tls&amp;amp;type=ws&amp;amp;host=xxx.dpdns.org&amp;amp;sni=xxx.dpdns.org&amp;amp;fp=random&amp;amp;path=%2F%3Fed%3D2560#xxx.dpdns.org
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;改为&lt;/p&gt;
&lt;p&gt;优选&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vless://20a4537b-8da9-4bd4-b666-6e29a62345f7@cf.090227.xyz:8443?encryption=none&amp;amp;security=tls&amp;amp;type=ws&amp;amp;host=xxx.dpdns.org&amp;amp;sni=xxx.dpdns.org&amp;amp;fp=random&amp;amp;path=%2F%3Fed%3D2560#xxx.dpdns.org
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后访问 &lt;a href=&quot;https://sub.cmliussss.com/&quot;&gt;https://sub.cmliussss.com&lt;/a&gt; 填上你的 Vless 单链接（如果优选请填改后的 Vless 单链接），然后点击 &lt;strong&gt;生成订阅链接&lt;/strong&gt;。之后导入生成好的链接进 Clash Verge 等客户端使用即可。&lt;/p&gt;
&lt;p&gt;如果你需要防止 DNS 泄露，这里有一些资料，但不保证一定能用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://linux.do/t/topic/155075&quot;&gt;【究极体！】真正防止 DNS 泄露的 Clash 小白式完美配置文件，安全+自由+流畅！ - 开发调优, Lv1 - LINUX DO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=50iVDmqzDW8&quot;&gt;【进阶•DNS代理篇】最完美的DNS解决方案？通过代理DNS请求获取正确的ip，杜绝DNS泄露和DNS污染，解决透明代理下fake-ip存在的问题，开启sniffing流量嗅探亦可解决污染问题 - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=fqREM6b25SY&quot;&gt;【进阶•DNS泄漏篇】竟能提速降延迟！再也不用担心DNS污染了！90%以上的人都存在DNS泄露！会有什么安全问题？如何解决代理中的DNS泄漏问题？以及WebRTC绕过代理泄漏本机真实IP，看完就知道了 - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过自己更改的防泄漏 DNS 配置，如果不是部署在直链环境下，就不要通过链接更新了，防止你的订阅链接将你更改的配置文件覆盖。推荐把更改后的配置文件上传到 Cloudflare R2 存储桶，然后获得一个公开的直链给 Clash 用。&lt;/p&gt;
&lt;p&gt;根据您提供的页面内容，这篇博客文章采用了 &lt;strong&gt;CC BY-NC-SA 4.0&lt;/strong&gt;（署名-非商业性使用-相同方式共享）许可协议。为了符合原作者 &lt;strong&gt;Ad_closeNN&lt;/strong&gt; 的要求，建议您在转载文末使用以下格式：&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;转载说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;本文转载自：&lt;/strong&gt; &lt;a href=&quot;https://blog.adclosenn.top/posts/cloudflare-workers-proxy/&quot;&gt;Ad_closeNN 的小站&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章标题：&lt;/strong&gt; 《使用 CF Workers 搭建 Vless/Trojan 节点并优化》&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文章作者：&lt;/strong&gt; &lt;a href=&quot;https://blog.adclosenn.top/posts/cloudflare-workers-proxy/&quot;&gt;Ad_closeNN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原始链接：&lt;/strong&gt; &lt;a href=&quot;https://blog.adclosenn.top/posts/cloudflare-workers-proxy/&quot;&gt;https://blog.adclosenn.top/posts/cloudflare-workers-proxy/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;许可协议：&lt;/strong&gt; 本文采用 &lt;a href=&quot;https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans&quot;&gt;CC BY-NC-SA 4.0&lt;/a&gt; 许可协议，转载请保留此说明。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
</content:encoded></item><item><title>告别手动传图：利用 Bing 官方 API 打造“零维护”随机图接口</title><link>https://fuwari.vercel.app/posts/%E4%BD%BF%E7%94%A8cloudflare-workerspages%E5%88%B6%E4%BD%9C%E6%B0%B8%E4%B9%85%E5%85%8D%E8%B4%B9%E7%9A%84%E9%9A%8F%E6%9C%BA%E5%9B%BEapi/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E4%BD%BF%E7%94%A8cloudflare-workerspages%E5%88%B6%E4%BD%9C%E6%B0%B8%E4%B9%85%E5%85%8D%E8%B4%B9%E7%9A%84%E9%9A%8F%E6%9C%BA%E5%9B%BEapi/</guid><description>觉得手动上传图片到 Cloudflare Pages 太麻烦？教你利用 Cloudflare Workers 实时抓取 Bing 每日壁纸，实现一个高清、自动更新且完全免费的随机图 API。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;原方案&lt;/h1&gt;
&lt;p&gt;转载说明：&lt;a href=&quot;https://blog.wudarensheng.top/posts/random-pages/&quot;&gt;使用Cloudflare Workers+Pages制作永久免费的随机图API! - Wudarensheng blog&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;准备工作&lt;a href=&quot;https://blog.wudarensheng.top/posts/random-pages/#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1.你的图片&lt;/p&gt;
&lt;p&gt;2.一个Cloudflare账号&lt;/p&gt;
&lt;p&gt;3.一个域名（必须托管在Cloudflare上）&lt;/p&gt;
&lt;h2&gt;正式开始&lt;a href=&quot;https://blog.wudarensheng.top/posts/random-pages/#%E6%AD%A3%E5%BC%8F%E5%BC%80%E5%A7%8B&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1.将你的图片**（格式必须统一）**放在单独的一个文件夹中，并创建一个用于批量重命名的bat脚本（&lt;strong&gt;不要以管理员权限运行！！！）&lt;/strong&gt;，代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@echo off
setlocal enabledelayedexpansion

:: Check if running as administrator
net session &amp;gt;nul 2&amp;gt;&amp;amp;1
if !errorlevel! equ 0 (
    echo Error: This script should not be run as administrator.
    echo Please run without administrator privileges.
    pause
    exit /b 1
)

set &quot;script_name=%~nx0&quot;
set /a counter=1

echo Renaming files...
echo.

:: First, create a temporary directory to avoid naming conflicts
set &quot;temp_dir=temp_rename_%random%&quot;
mkdir &quot;%temp_dir%&quot;

:: Move all files (except script) to temp directory first
for %%f in (*) do (
    if /i not &quot;%%f&quot;==&quot;%script_name%&quot; (
        if not &quot;%%f&quot;==&quot;%temp_dir%&quot; (
            move &quot;%%f&quot; &quot;%temp_dir%\%%f&quot; &amp;gt;nul
        )
    )
)

:: Rename files from temp directory back with new names
for %%f in (&quot;%temp_dir%\*&quot;) do (
    set &quot;filename=%%~nxf&quot;
    set &quot;ext=%%~xf&quot;
    if &quot;!ext!&quot;==&quot;&quot; set &quot;ext=&quot;
    set &quot;new_name=!counter!!ext!&quot;

    move &quot;%%f&quot; &quot;!new_name!&quot; &amp;gt;nul
    if !errorlevel! equ 0 (
        echo Renamed: &quot;!filename!&quot; --^&amp;gt; &quot;!new_name!&quot;
        set /a counter+=1
    ) else (
        echo Error: Cannot rename &quot;!filename!&quot;
    )
)

:: Remove temporary directory
rmdir &quot;%temp_dir%&quot; /s /q &amp;gt;nul 2&amp;gt;&amp;amp;1

echo.
echo Operation completed. Total files processed: %counter%
pause
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存脚本并运行，就完成了图片的重命名。接着将你的图片添加到压缩包。&lt;/p&gt;
&lt;p&gt;2.登录Cloudflare账号，找到侧边栏的Worker，创建一个pages，选择“上传资产”。将压缩包上传，点击部署，复制类似 {你的pages名称}.pages.dev的域名，备用。&lt;/p&gt;
&lt;p&gt;3.再创建一个worker，选择从helloworld开始，名称随意。部署完成后选择右上角编辑代码，将里面的内容删完，接着粘贴以下代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addEventListener(&apos;fetch&apos;, event =&amp;gt; {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const randomNumber = Math.floor(Math.random() * 9) + 1;  //9改为实际的图片数量
  const imageUrl = `https://wdrs-page.pages.dev/${randomNumber}.png`;  //png改为实际的图片格式

  try {
    const response = await fetch(imageUrl);
    if (response.ok) {
      return new Response(response.body, {
        headers: { &apos;Content-Type&apos;: &apos;image/png&apos; }  //这里一样的，改为实际的图片格式
      });
    }
    return new Response(&apos;Image not found&apos;, { status: 404 });
  } catch (error) {
    return new Response(&apos;Service unavailable&apos;, { status: 503 });
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按照代码右边的注释改完后，点击部署&lt;/p&gt;
&lt;p&gt;4.给worker绑定一个自定义域名，地址栏输入分配的域名就可以访问了！&lt;/p&gt;
&lt;h1&gt;简单方案（&lt;strong&gt;使用 Bing 官方 API&lt;/strong&gt;）&lt;/h1&gt;
&lt;p&gt;这种方法你不需要上传图片，不需要 GitHub 仓库，甚至不需要每天更新，因为 Bing 会帮你更新。&lt;/p&gt;
&lt;h2&gt;获取当日图片&lt;/h2&gt;
&lt;p&gt;在你的 Workers 编辑器中，直接替换为以下代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async function handleRequest(request) {
  const BING_API = &quot;https://www.bing.com/HPImageArchive.aspx?format=js&amp;amp;idx=0&amp;amp;n=1&quot;;

  try {
    // 1. 请求 Bing 官方接口获取图片数据
    const response = await fetch(BING_API);
    const data = await response.json();

    // 2. 提取图片路径并拼接完整 URL
    // data.images[0].url 通常是 /th?id=OHR.XXX.jpg
    const imgRelativePath = data.images[0].url;
    const fullImgUrl = `https://www.bing.com${imgRelativePath}`;

    // 3. 策略选择：
    // 方案 A: 直接 302 重定向到 Bing 图片（速度快，节省 Workers 资源）
    return Response.redirect(fullImgUrl, 302);

    /* // 方案 B: 代理读取图片并输出（隐藏真实地址，看起来更像本地 API）
    const imageResponse = await fetch(fullImgUrl);
    return new Response(imageResponse.body, {
      headers: { &apos;Content-Type&apos;: &apos;image/jpeg&apos; }
    });
    */

  } catch (e) {
    return new Response(&quot;抓取 Bing 图片失败&quot;, { status: 500 });
  }
}

addEventListener(&apos;fetch&apos;, event =&amp;gt; {
  event.respondWith(handleRequest(event.request));
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;随机获取最近的 8 张 图片&lt;/h2&gt;
&lt;p&gt;在你的 Workers 编辑器中，直接替换为以下代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;async function handleRequest(request) {
  // 1. 生成随机索引：0 代表今天，1-7 代表过去 7 天
  const randomIndex = Math.floor(Math.random() * 8);
  
  // 2. 构造 Bing 官方接口 URL (n=8 表示获取最近 8 张的数据)
  const BING_API = `https://www.bing.com/HPImageArchive.aspx?format=js&amp;amp;idx=${randomIndex}&amp;amp;n=1`;

  try {
    // 3. 抓取 Bing 接口数据
    const response = await fetch(BING_API);
    const data = await response.json();
    
    // 4. 提取图片路径
    if (data.images &amp;amp;&amp;amp; data.images.length &amp;gt; 0) {
      const imgRelativePath = data.images[0].url;
      const fullImgUrl = `https://www.bing.com${imgRelativePath}`;

      // 5. 302 重定向到真实的图片地址
      return Response.redirect(fullImgUrl, 302);
    } else {
      throw new Error(&quot;Invalid Bing API response&quot;);
    }

  } catch (error) {
    return new Response(&quot;抓取随机 Bing 图片失败: &quot; + error.message, { status: 500 });
  }
}

addEventListener(&apos;fetch&apos;, event =&amp;gt; {
  event.respondWith(handleRequest(event.request));
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;方案对比&lt;/h1&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;旧方案 (手动 Pages 存储)&lt;/th&gt;
&lt;th&gt;新方案 (Bing 官方 API)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;图片来源&lt;/td&gt;
&lt;td&gt;需自行搜集、重命名、打包&lt;/td&gt;
&lt;td&gt;官方源：自动获取 Bing 每日壁纸&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;维护成本&lt;/td&gt;
&lt;td&gt;高：增加新图需重新上传部署&lt;/td&gt;
&lt;td&gt;零维护：自动同步，永久更新&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;存储压力&lt;/td&gt;
&lt;td&gt;占用 Cloudflare Pages 配额&lt;/td&gt;
&lt;td&gt;不占空间：仅做请求中转与重定向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;加载速度&lt;/td&gt;
&lt;td&gt;取决于 Pages 节点的全球分发&lt;/td&gt;
&lt;td&gt;极速：利用微软官方 CDN 节点加速&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;图片质量&lt;/td&gt;
&lt;td&gt;取决于本地素材质量&lt;/td&gt;
&lt;td&gt;高清原图：固定提供 1080P/4K 图像&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;实现难度&lt;/td&gt;
&lt;td&gt;涉及脚本运行、压缩、多步部署&lt;/td&gt;
&lt;td&gt;极简：一行 Workers 代码即可搞定&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>如何彻底修改 Windows 用户文件夹名（中文改英文）</title><link>https://fuwari.vercel.app/posts/%E5%A6%82%E4%BD%95%E4%BF%AE%E6%94%B9windows%E7%94%A8%E6%88%B7%E5%90%8D---betsy-blog/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%A6%82%E4%BD%95%E4%BF%AE%E6%94%B9windows%E7%94%A8%E6%88%B7%E5%90%8D---betsy-blog/</guid><description>本教程详细介绍了通过启用超级管理员账户、修改注册表 ProfileImagePath 及手动重命名用户文件夹，解决 Windows 用户名包含中文导致软件运行异常的方法。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;1.首先你需要打开你的命令提示符（管理员权限），然后输入以下命令来开启超级用户去修改你的用户名：&lt;a href=&quot;https://www.micostar.cc/posts/userz-e/#1%E9%A6%96%E5%85%88%E4%BD%A0%E9%9C%80%E8%A6%81%E6%89%93%E5%BC%80%E4%BD%A0%E7%9A%84%E5%91%BD%E4%BB%A4%E6%8F%90%E7%A4%BA%E7%AC%A6%E7%AE%A1%E7%90%86%E5%91%98%E6%9D%83%E9%99%90%E7%84%B6%E5%90%8E%E8%BE%93%E5%85%A5%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%E6%9D%A5%E5%BC%80%E5%90%AF%E8%B6%85%E7%BA%A7%E7%94%A8%E6%88%B7%E5%8E%BB%E4%BF%AE%E6%94%B9%E4%BD%A0%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://www.micostar.cc/images/ML.webp&quot; alt=&quot;打开管理员命令提示符&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Terminal window&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1net user administrator /active:yes
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.然后按下Alt+F4，选择切换用户，切换到管理员账户（Administrator）&lt;a href=&quot;https://www.micostar.cc/posts/userz-e/#2%E7%84%B6%E5%90%8E%E6%8C%89%E4%B8%8Baltf4%E9%80%89%E6%8B%A9%E5%88%87%E6%8D%A2%E7%94%A8%E6%88%B7%E5%88%87%E6%8D%A2%E5%88%B0%E7%AE%A1%E7%90%86%E5%91%98%E8%B4%A6%E6%88%B7administrator&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;h3&gt;3.在任务管理器（Ctrl+Shift+Esc）关闭之前的用户所有进程&lt;a href=&quot;https://www.micostar.cc/posts/userz-e/#3%E5%9C%A8%E4%BB%BB%E5%8A%A1%E7%AE%A1%E7%90%86%E5%99%A8ctrlshiftesc%E5%85%B3%E9%97%AD%E4%B9%8B%E5%89%8D%E7%9A%84%E7%94%A8%E6%88%B7%E6%89%80%E6%9C%89%E8%BF%9B%E7%A8%8B&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://www.micostar.cc/images/UserM.webp&quot; alt=&quot;任务管理器关闭用户进程&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4.先重命名用户文件夹（C:\Users\原中文用户名）为（C:\Users\新英文用户名）&lt;a href=&quot;https://www.micostar.cc/posts/userz-e/#4%E5%85%88%E9%87%8D%E5%91%BD%E5%90%8D%E7%94%A8%E6%88%B7%E6%96%87%E4%BB%B6%E5%A4%B9cusers%E5%8E%9F%E4%B8%AD%E6%96%87%E7%94%A8%E6%88%B7%E5%90%8D%E4%B8%BAcusers%E6%96%B0%E8%8B%B1%E6%96%87%E7%94%A8%E6%88%B7%E5%90%8D&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://www.micostar.cc/images/Users.webp&quot; alt=&quot;用户文件夹重命名&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果存在仍有进程在运行问题，则开启你的资源监视器（Ctrl+Shift+Esc下的性能页面右上角的“打开资源监视器”） &lt;img src=&quot;https://www.micostar.cc/images/ZYGL.webp&quot; alt=&quot;资源监视器&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然后在资源监视器的CPU页面的关联句柄搜索框中输入你的用户名，找到相关进程并结束它们（需要重启则重启，后续仍选择超级管理员，误进入原来的用户导致错乱后果自负！！！） &lt;img src=&quot;https://www.micostar.cc/images/ZYJ.webp&quot; alt=&quot;资源监视器搜索关联句柄&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5.然后打开注册表编辑器（Win+R，输入regedit回车），定位到以下路径：&lt;a href=&quot;https://www.micostar.cc/posts/userz-e/#5%E7%84%B6%E5%90%8E%E6%89%93%E5%BC%80%E6%B3%A8%E5%86%8C%E8%A1%A8%E7%BC%96%E8%BE%91%E5%99%A8winr%E8%BE%93%E5%85%A5regedit%E5%9B%9E%E8%BD%A6%E5%AE%9A%E4%BD%8D%E5%88%B0%E4%BB%A5%E4%B8%8B%E8%B7%AF%E5%BE%84&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;1HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-1144158939-3632170427-3967875196-1001（一般是第三个，选中有你用户名的即可）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改&amp;lt;ins&amp;gt;&amp;lt;strong&amp;gt;ProfileImagePath&amp;lt;/strong&amp;gt;&amp;lt;/ins&amp;gt; &lt;img src=&quot;https://www.micostar.cc/images/eng11.webp&quot; alt=&quot;修改注册表ProfileImagePath&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;6.更改完成注册表后，按下Alt+F4，选择切换用户，切换到你的新英文用户名即可&lt;a href=&quot;https://www.micostar.cc/posts/userz-e/#6%E6%9B%B4%E6%94%B9%E5%AE%8C%E6%88%90%E6%B3%A8%E5%86%8C%E8%A1%A8%E5%90%8E%E6%8C%89%E4%B8%8Baltf4%E9%80%89%E6%8B%A9%E5%88%87%E6%8D%A2%E7%94%A8%E6%88%B7%E5%88%87%E6%8D%A2%E5%88%B0%E4%BD%A0%E7%9A%84%E6%96%B0%E8%8B%B1%E6%96%87%E7%94%A8%E6%88%B7%E5%90%8D%E5%8D%B3%E5%8F%AF&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;然后打开任务管理器（Ctrl+Shift+Esc）关闭管理员账户所有进程；再打开命令提示符（管理员权限），然后输入以下命令来关闭超级用户：&lt;/p&gt;
&lt;p&gt;Terminal window&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1net user administrator /active:no
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;7.配置文件看的是你C盘根目录下的Users文件夹下的用户名文件夹，并非是设置里的用户名&lt;a href=&quot;https://www.micostar.cc/posts/userz-e/#7%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9C%8B%E7%9A%84%E6%98%AF%E4%BD%A0c%E7%9B%98%E6%A0%B9%E7%9B%AE%E5%BD%95%E4%B8%8B%E7%9A%84users%E6%96%87%E4%BB%B6%E5%A4%B9%E4%B8%8B%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E6%96%87%E4%BB%B6%E5%A4%B9%E5%B9%B6%E9%9D%9E%E6%98%AF%E8%AE%BE%E7%BD%AE%E9%87%8C%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
</content:encoded></item><item><title>拒绝庸碌：如何通过隔离无关事物重获生活掌控权</title><link>https://fuwari.vercel.app/posts/%E6%96%87%E6%91%98%E4%B8%8D%E8%A6%81%E8%AE%A9%E6%97%A0%E5%85%B3%E7%9A%84%E4%BA%8B%E6%83%85%E5%8D%A0%E6%8D%AE%E4%BD%A0%E7%9A%84%E7%94%9F%E6%B4%BB---%E8%BF%B7%E9%9B%BE%E7%AC%94%E8%AE%B0/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%96%87%E6%91%98%E4%B8%8D%E8%A6%81%E8%AE%A9%E6%97%A0%E5%85%B3%E7%9A%84%E4%BA%8B%E6%83%85%E5%8D%A0%E6%8D%AE%E4%BD%A0%E7%9A%84%E7%94%9F%E6%B4%BB---%E8%BF%B7%E9%9B%BE%E7%AC%94%E8%AE%B0/</guid><description>本文探讨了在AI与短视频时代，如何通过建立“不帮原则”、卸载成瘾性应用及坚持系统性学习，从迷茫状态中脱离，找回思考能力。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;随着科技越来越发达，很多事情AI就帮你很快完成，短视频、抖音、新闻等占据了很多业余的时间，导致没有办法静下心来思考问题，每天如同提线木偶般浑浑噩噩,时间一长感觉对任何事情都提不起兴趣。&lt;br /&gt;
创建这个blog初衷是让自己改变目前的状态，让自己有更多的时间思考、学习、记录、复盘每日在学习和工作中遇到的各种问题，顺便隔离与自己生活无关的事情&lt;/p&gt;
&lt;h2&gt;帮人会过度占用你时间&lt;a href=&quot;https://fogce.com/posts/quiet-life/#%E5%B8%AE%E4%BA%BA%E4%BC%9A%E8%BF%87%E5%BA%A6%E5%8D%A0%E7%94%A8%E4%BD%A0%E6%97%B6%E9%97%B4&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;小时候，父母总是说要与人和善，别人的事情能帮就帮一下，就以为帮别是头等大事；出来工作后别人的事情能帮就会帮，但是时间长了之后发现帮别人，自己想要做的事情没时间做了，有人提醒‘我不要别人让你帮忙就立即帮，庶判断哪些是真的需要帮的，不要总处理别人抛过来的&lt;code&gt;急事&lt;/code&gt;’。所以后来就给自己定了三个不帮原则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;和自己职责无关的事情不帮&lt;/strong&gt;: 避免过度跨职责引起不必要的麻烦&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;需求不明确的事情不帮&lt;/strong&gt;: 需求不明确说明他自己也不知道想要什么，不要介入过多&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解决需要话很长时间的不帮&lt;/strong&gt;: 说到底是别人的事情，你花了时间自己的事情可能没有办法按期完成。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;他自己花时间可搞定事不帮&lt;/strong&gt;: “授人以鱼”不如”授人以渔”，避免他人长期懒惰依赖性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;违背公序良俗的事情不帮&lt;/strong&gt;: 保持专业距离，不介入复杂人际关系纠纷或情感纠葛&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;不必要的应酬&lt;a href=&quot;https://fogce.com/posts/quiet-life/#%E4%B8%8D%E5%BF%85%E8%A6%81%E7%9A%84%E5%BA%94%E9%85%AC&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在生活中人避免不了与其他人接触，也少不了相关的应酬，如聚会、吃饭等；这些会大量占用你的时间，人到中年会 发现这些很多都是无关紧要的，真正能带给你帮助的少之又少。&lt;/p&gt;
&lt;h2&gt;卸载你的抖音短视频平台&lt;a href=&quot;https://fogce.com/posts/quiet-life/#%E5%8D%B8%E8%BD%BD%E4%BD%A0%E7%9A%84%E6%8A%96%E9%9F%B3%E7%9F%AD%E8%A7%86%E9%A2%91%E5%B9%B3%E5%8F%B0&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;短视频精准的抓住了我们当代人碎片时间的注意力，让人越看越想看。很多时间自己明明已经很累了，但是打开了抖音之后自己的注意力全部都被抖音吸引了，然后刷了一条又一条，让人不断成瘾看下去，一晃就到了凌晨了。然后一天又一天的重复。&lt;br /&gt;
当想要改变晚睡的习惯，想要在这个状态下脱离出来，每次只要一打开短时频又会被内容所吸引，又在这个事情上不段的重复。&lt;br /&gt;
短视频大部分都是无效且片面的，根本就没有办法让你系统化掌握一门知识与应用; 你感觉看了一个比较好的视频，当时你觉得说的挺有道理的，又刷了另外一个视频也觉得挺有道理的，然后不断的刷到新的视频佐证你的想法，实际上已经陷入了短视频算法的精心陷阱中，他让你看到你只想看到的内容，让你的思考层面越来越偏激化，你以为视频的想法就是你的想法了。&lt;br /&gt;
小时候听到&lt;code&gt;洗脑&lt;/code&gt;这个词时，我以为是把人的脑子打开，然后灌水进去洗，当时我都害怕了很久，生怕别人把我带去&lt;code&gt;洗脑&lt;/code&gt;。后来步入社会后&lt;code&gt;洗脑&lt;/code&gt;这个词就听到多了，慢慢这就是别人的思想强加到你的思想里，你误以为别人就是对的。现在的短视频何尝不是一个洗脑中心呢，不管你是看短视频还是听短视频都是一样&lt;br /&gt;
所以我们要保持足够的警惕，不让要短视频干涉到你的生活，从而影响了你，戒掉短视频，给自己多一些时间去思考和观察世界的变化。&lt;/p&gt;
&lt;h3&gt;戒掉短视频有几种方法&lt;a href=&quot;https://fogce.com/posts/quiet-life/#%E6%88%92%E6%8E%89%E7%9F%AD%E8%A7%86%E9%A2%91%E6%9C%89%E5%87%A0%E7%A7%8D%E6%96%B9%E6%B3%95&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;直接卸载掉抖音和其他的视频平台&lt;/li&gt;
&lt;li&gt;培养自己一项兴趣爱好&lt;/li&gt;
&lt;li&gt;减少看手机时间，&lt;/li&gt;
&lt;li&gt;多运动、出门散步&lt;/li&gt;
&lt;li&gt;坚持学习、复盘、做笔记，系统性学习你想要学习的内容&lt;/li&gt;
&lt;li&gt;把这些事情变成你的习惯。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;走出迷茫&lt;a href=&quot;https://fogce.com/posts/quiet-life/#%E8%B5%B0%E5%87%BA%E8%BF%B7%E8%8C%AB&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;建立这个博客之前我每天都感觉很迷茫，像是有一团迷雾看不清未来的方向，每天上班感觉都浑浑噩噩的，不知道做什么，未来应该做什么。&lt;br /&gt;
我觉得应该让自己多一些时间思考，而不是将时间浪费在短视频、游戏、朋友圈等地方，然后把相关的状态记录下来，让自己了解自己的状态，脱离迷茫。&lt;br /&gt;
所以创建了现在的博客，不去考虑流量，只记录自己学习与生活，锻炼自己的写作复盘能力。&lt;br /&gt;
2024年1月到4月时，每天早起去炼目跟着太阳的时间起床，那时每天都是清醒的，后来太阳升起来太早没有办法起来，早起的习惯就搁置了。 今天又早起，感觉一天都是有精神的。&lt;br /&gt;
&lt;strong&gt;生活本该属于你自己，除去生死其他都无关紧要&lt;/strong&gt;，或许未来某天能像庄子一样悟透生死，&lt;code&gt;生死也无关紧要了&lt;/code&gt;。&lt;/p&gt;
</content:encoded></item><item><title>驴得水：一场关于人性的悲剧</title><link>https://fuwari.vercel.app/posts/%E6%96%87%E6%91%98%E6%B5%85%E8%B0%88%E9%A9%B4%E5%BE%97%E6%B0%B4/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%96%87%E6%91%98%E6%B5%85%E8%B0%88%E9%A9%B4%E5%BE%97%E6%B0%B4/</guid><description>“给你讲个笑话，你可别哭啊。”深度剖析电影《驴得水》中的人物群像，探讨在极端环境下理想如何崩塌、人性如何异化。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;有感&lt;/h1&gt;
&lt;blockquote&gt;
&lt;h2&gt;“给你讲个笑话，你可别哭啊！”&lt;/h2&gt;
&lt;p&gt;民国时期，在一个远离喧嚣和战乱的偏远山区，伫立着一所简陋平凡的学校。校长孙恒海带着女儿孙佳以及裴魁山、张一曼、周铁男这几个教师栖身于此。在校长的建议下，把院子里的一头驴起了名字“吕得水”当作教员报了上去，以吃空饷。可就在某天，教育部要派专员来访，偶然来到学校的铜匠如同救命稻草出现在众人面前，他们央求铜匠伪装成吕老师，可是一切真能顺利蒙混过关吗？一段荒诞，观完令人无言的故事就此上演。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;前30分钟，哈哈哈喜剧啊，这些人真逗。&lt;br /&gt;
又30分钟，嗯，有关于取舍、关于底线的哲学思考。&lt;br /&gt;
后60分钟，忍不住暗骂所有人都有病，所有人！骂着骂着，眼睛泛起酸来。&lt;/p&gt;
&lt;h2&gt;人物塑造&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;校长&lt;br /&gt;
近乎偏执地，近乎不择手段地，想要实现自己教育理想！为了达到目的，依靠威信和自以为的大格局，戴着所谓的大局为重的冠冕堂皇的面具，让自己虚伪的面目越来越严重。&lt;br /&gt;
亲自给张一曼剪发；&lt;br /&gt;
亲自劝说女儿扮演吕得水的未婚妻 ；&lt;br /&gt;
在魁山对一曼实施暴行的时候出来制止 ；&lt;br /&gt;
在周铁男被枪指住的时候挡在铁男身前阻挡对方开枪 ；&lt;br /&gt;
在嘴边总挂着口头禅“干大事不拘小节” ；&lt;br /&gt;
就为了所谓的“教育建设”，一次次让张一曼走在被侮辱的第一线。使得这句口头禅越往后就越成了一个笑话。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;裴魁山&lt;br /&gt;
一身中山装也掩饰不住内心的肮脏龌龊，后半段的貂绒才是他脱掉面具之后的真正嘴脸；&lt;br /&gt;
曾经与铁男交谈自己对教育的看法，但那是建立在对铜匠获得教育家称号之后的嫉妒与不满之上的；&lt;br /&gt;
对张一曼拒绝了自己而与铜匠翻云覆雨怒不可遏。从此对一曼恶语相向，屡屡把一曼推向绝境；&lt;br /&gt;
杀驴之后几个人之中只有他吃了驴肉，与特派员推杯换盏，完全是一条任人使唤的走狗；&lt;br /&gt;
不管是片头的建立奖学金，还是片末的建新教室，都不愿用自己的工资与奖金出一份力，在婚礼大乱时先拿钱跑路。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;周铁男&lt;br /&gt;
同样也是一个带着面具的人，正是佳佳闯入教室后发生的一切，才使他慢慢地揭下了面具；&lt;br /&gt;
在转变之前，他充满了正义感，充满血性，保护弱者，捍卫自己的尊严。转变之后，却是向黑恶势力磕头，直至头破血流。天壤之别的转变，往往就是一瞬间；&lt;br /&gt;
在转变之前，挺身而出，为一曼打抱不平。转变之后，在有人要强奸一曼的时，他放下了举在手里的武器，畏缩在角落；&lt;br /&gt;
在转变之前，他是唯一个敢道出真相的人，他无法忍受大家一个接一个的谎言，对包括自己在内的所有人破口大骂。转变之后，却自欺欺人，说自己只有卧薪尝胆，变强大了之后才能打败他们；&lt;br /&gt;
转变之前对特派员的行为嗤之以鼻，甚至有几次直接冲撞特派员，转变之后成了特派员的走狗，督促大家完成特派员的计划，甚至可以去劝说自己喜欢的姑娘扮演别人的未婚妻。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;铜匠&lt;br /&gt;
在别人给他戴上虚假的身份面具之后，在欲望脱离压制后无知而又自私的人。这世上最恶毒的事也许就是本性朴实善良之人变得阴鸷恐怖之后的背后一刀；&lt;br /&gt;
他从不接受知识到向往知识，连相都不敢照的人却有模有样的泡起茶来；&lt;br /&gt;
从躲避性欲到向往爱情，看着一曼离去的背影唱起歌。但当他发现自己只不过是被人玩弄的牲口，开始变得暴戾。被母夜叉一般的妻子压抑的欲望，在释放之后令人不寒而栗；&lt;br /&gt;
他自私又胆小，有权在手时残暴，被人揭穿时猥琐。最后差点用“吕得水”的身份在众目睽睽之下得到一切，还是还是逃不过妻子的魔爪。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cloudflare-imgbed-9xb.pages.dev/file/1732362759679_fdfad.jpg&quot; alt=&quot;fdfad.jpg&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;张一曼&lt;br /&gt;
一个从大城市来到小乡村，美其名曰这里没人管着我，喜欢自由，但其实大概率是在城里因放荡自由而出名的；&lt;br /&gt;
一个对待生活充满乐观的人，在剥蒜的时候唱起歌，在点上灯放着音乐的夜晚翩翩起舞的人；&lt;br /&gt;
一个机敏伶俐，善于观察的人，看出特派员只是一个不会英语、用品茶来附庸风雅的文盲，带领大家度过危机的人；&lt;br /&gt;
一个一方面享受自由的美好和不羁，一方面又真的在乎别人的评价的高自尊的人。外面的人骂她骚浪贱，但那些是外人，她不在乎。可是，家里人在她毫不设防的时候，突然对她进行荡妇羞辱，于是她病发了，她彻底崩溃了。除了孙佳，所有人都背叛了她。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;场景片段&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;开始的开始&lt;/strong&gt;&lt;br /&gt;
睡服铁匠的主意就是出自一曼本人 ，尽管此时，她没意识到她将吃下那颗由自己信仰所结出来的苦果，而从铜匠媳妇找来开始，她就像陷进沼泽里，一点一点的往下沉，直到泥浆没过头顶。尽管此时，她也没意识周围的大多数人，都在推波助澜地将其推进黑暗；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;驴得水老婆出场后&lt;/strong&gt;&lt;br /&gt;
虽然一直嚷嚷着让她站出来承认的是裴魁山，但她也看的出校长默许了这层意思，直到裴魁山说出那句“当初要不是校长帮你，你TM现在在哪儿呢！”她决定站出来，虽然看得出她有点失望，但应该算是报校长收留之恩吧；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;教室内&lt;/strong&gt;&lt;br /&gt;
她再次震惊于裴魁山对自己的侮辱，在她眼里，就算不再跟裴魁山发生关系，他们仍然是好朋友，好同事，甚至是一家人。她没想到，自己竟然是以这种形象烙印在自己的同事，自己的朋友心中；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;还是在教室内&lt;/strong&gt;&lt;br /&gt;
面对铜匠极尽手段地羞辱，她同样是心碎的，但她伤害人家在先，所以她也始终选择默默忍受。但是，校长竟忍心剪下她的头发，被剪发之后的一曼从梦境中醒来，脸上还挂着微笑。但是这种满足马上就被恐惧和羞辱取代了。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;窑屋内&lt;/strong&gt;&lt;br /&gt;
在特派员的保镖要欲行不轨之时，铁男却见死不救，缩在一旁没敢吱声。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在一切都即将尘埃落定后&lt;/strong&gt;&lt;br /&gt;
没有一个人提供哪怕一句嘘寒问暖的关心。人往往不是突然崩溃的，而是一件件事把她击垮。从教室事件发生的一刻起，现实的罪恶嘴脸最终显露无疑，因此，为了维持内心最后的纯净，只得“疯了”。只有疯了，她才不会被关注，不会被在乎，也没有理由再牵扯其中；万念俱灰之下，她只好走了绝路。片尾的一声枪响，枪口对着的，不仅仅是一曼本人，更是观后无言的所有人。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;后话&lt;/h2&gt;
&lt;p&gt;整剧完结，一曼用教堂拾来的枪告别世间，佳佳坐着驴车离开黄土高坡。余下的男人们，他们离开或者留下，愧疚或者麻木，已无需深究。他们尚且真实粗鄙地活着，为梦想为生存为利益；也已在尘封着热血的昨日死去，无可怀缅不值一提。在我看来，《驴得水》已经从不同角度阐释了人性的阴暗。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在这里，人性是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人性，是孙校长的偏执和不择手段，为了完成自己的宏图远景，不惜把他人推向无底深渊；&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人性，是铜匠在欲望和权力被不断放大之后，由本性朴实善良变得阴鸷恐怖；&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人性是物极必反，是裴魁山的因爱生恨——把爱说得再冠冕堂皇，也不过是“占有”的借口，当占有不遂，爱就成了恨，化作毁灭对方的匕首；&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人性，是周铁男面对枪口时的恐惧与妥协；&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人性，是孙佳越来越孱弱无力的坚持；&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这就是人性，我们永远不可能站在上帝的视角，只是嘘唏感叹，回归现实社会，在经历人性的至昏至暗之后，我们就要明白，张一曼想要告诉我们的真谛，她告诉我们，&lt;strong&gt;对一个人而言，当某一样事物成为其唯一的认定，变作独一无二的执着甚至是贪著，其实是一种不幸。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这种事物就像是一个定时炸弹，随时会把你炸得粉身碎骨——就看什么时候引线会在不经意间被点燃而已。当然不只是张一曼的“性与美好”，还有现实生活中的所有人事物：如事业、财富、爱情；如你明知不可能还贪恋纠缠的谁谁谁。&lt;/p&gt;
&lt;p&gt;花无百日红。如果你只贪恋它的盛放，却不肯接受它的凋零，这已经是 一场悲剧。正如张一曼，不过是一头长发，即使剪了，还会长回来是不是？而且，短发也可以很美。而她，却把一头长发变成自己无法割舍的美，又把美当作了生命的全部。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要把任何外物，作为你与世界的唯一的链接，否则，你就会成为两脚悬空，挂在悬崖上的可怜的傀儡。而这唯一的链接会成为那命悬的一线，它将随着时光的流转而变得越来越纤细，越来越无力，待有朝一日崩断时，你便粉身碎骨。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这样，你就永远见不到尘埃落定的那一天了……&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果活着真的需要理由，请给自己N+1个。那个1，会在关键时刻，阻止你步张一曼的后尘。&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>GitHub 个人主页自定义与美化教程</title><link>https://fuwari.vercel.app/posts/%E5%AE%9A%E5%88%B6%E5%B1%9E%E4%BA%8E%E8%87%AA%E5%B7%B1%E7%9A%84github%E4%B8%BB%E9%A1%B5/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E5%AE%9A%E5%88%B6%E5%B1%9E%E4%BA%8E%E8%87%AA%E5%B7%B1%E7%9A%84github%E4%B8%BB%E9%A1%B5/</guid><description>手把手教你通过特殊仓库 README 定制酷炫的 GitHub Profile，涵盖统计卡片、打卡记录、贪吃蛇动画及博客自动同步等进阶玩法。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Guthub 个人主页 （官方称呼是 profile）可以展示很多有用的信息，例如添加一个首页被访问次数的计数器，一个被 Star 与 Commit 的概览信息，以及各种技能标签，设备标签等，还可以利用 wakatime 显示你最近编码各类语言的使用时长，以及你最近 Steam 游戏游玩排行榜。&lt;/p&gt;
&lt;h2&gt;默认主页&lt;/h2&gt;
&lt;p&gt;默认情况下，GitHub 个人主页会显示其仓库信息、提交信息，例如 Linux 之父 Linus 的 &lt;a href=&quot;https://github.com/torvalds&quot;&gt;GitHub 主页&lt;/a&gt; 长这样：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608249-1320927684.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608249-1320927684.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但是，这个主页是可以定制的。GitHub 支持这个功能，并且有相关的文档说明：&lt;a href=&quot;https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile&quot;&gt;Setting up and managing your GitHub profile - GitHub Docs&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;例如有的长这样：&lt;a href=&quot;https://github.com/foru17&quot;&gt;Luo Lei&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608648-1549229925.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608648-1549229925.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这就远比默认主页好看不少，令人印象深刻。&lt;/p&gt;
&lt;h2&gt;原理&lt;/h2&gt;
&lt;p&gt;自定义主页很简单。我们首先在 GitHub 上新建一个仓库，仓库名和自己 Github 用户名相同，然后添加一个 README.md 自述文件，在该文件里添加信息即可。&lt;/p&gt;
&lt;p&gt;例如，我创建的仓库：&lt;a href=&quot;https://github.com/Peter-JXL/Peter-JXL&quot;&gt;github.com/Peter-JXL/Peter-JXL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609079-1256998123.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609079-1256998123.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;可以看到右上角有个提示：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Peter-JXL/Peter-JXL&lt;/strong&gt; is a special repository.&lt;/p&gt;
&lt;p&gt;Its &lt;code&gt;README.md&lt;/code&gt; will appear on your public profile.&lt;/p&gt;
&lt;p&gt;翻译：&lt;/p&gt;
&lt;p&gt;这是一个特殊的仓库。&lt;/p&gt;
&lt;p&gt;它的 &lt;code&gt;README.md&lt;/code&gt; 会出现在你的首页中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;侧边栏&lt;/h2&gt;
&lt;p&gt;在讲解如何定制之前，我们先关注下左侧也有个人信息展示：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608327-1090425598.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608327-1090425598.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个可以直接在个人首页上，点击左侧的 Edit profile 进行编辑：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609036-1256782953.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609036-1256782953.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;可以修改名字、签名（Bio）、公司、地点、邮箱、网站.......... 按需修改即可。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101719856-1541374132.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101719856-1541374132.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;接下来讲讲如何定制右侧。&lt;/p&gt;
&lt;h2&gt;新建仓库&lt;/h2&gt;
&lt;p&gt;新建一个同名仓库，并添加一个自述文件（README.md），确认：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608096-1191518163.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608096-1191518163.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;GitHub 默认为此文件添加了一行字：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607923-405831706.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607923-405831706.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;此时我们的首页也会跟着变：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101744170-402346270.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101744170-402346270.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;如何定制&lt;/h2&gt;
&lt;p&gt;接下来，你就可以通过修改 README.md 来定制主页了。由于是 Markdown 文件，扩展性很高，并且全面支持 emoji。&lt;/p&gt;
&lt;p&gt;此外，人的创造力有限，如何短时间内拥有一个酷炫的个人主页呢？&lt;/p&gt;
&lt;p&gt;答案是 &lt;code&gt;ctrl+c&lt;/code&gt;，&lt;code&gt;ctrl+v&lt;/code&gt;。看到好看的模板，可以直接 fork，修改下相关变量即可。&lt;/p&gt;
&lt;p&gt;此外 GitHub 上也有不少人收集优秀案例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/abhisheknaiidu/awesome-github-profile-readme&quot;&gt;awesome-github-profile-readme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/EddieHubCommunity/awesome-github-profiles&quot;&gt;awesome-github-profiles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rzashakeri/beautify-github-profile&quot;&gt;beautify-github-profile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接下来讲讲一些常见的信息展示。&lt;/p&gt;
&lt;h3&gt;GitHub 统计卡片&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/anuraghazra/github-readme-stats&quot;&gt;github.com/anuraghazra/github-readme-stats&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101707878-941962266.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101707878-941962266.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法很简单，将如下代码复制到你的 markdown 文件中，更改 &lt;code&gt;?username=&lt;/code&gt; 的值为你的 GitHub 用户名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Anurag&apos;s GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个是默认样式，很简陋，可以配置显示图标、主题样式等，具体请看官网文档。&lt;/p&gt;
&lt;h3&gt;GitHub 使用语言统计&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/anuraghazra/github-readme-stats&quot;&gt;github.com/anuraghazra/github-readme-stats&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608762-188973005.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608762-188973005.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法同上，复制如下代码，更改 &lt;code&gt;?username=&lt;/code&gt; 的值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同理，这个也可以配置主题和布局（参考文档）。&lt;/p&gt;
&lt;h3&gt;Metrics 统计信息&lt;/h3&gt;
&lt;p&gt;会展示 GitHub 上的一些统计信息，效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608412-1311638171.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608412-1311638171.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们可以去官网演示下：输入你的 GitHub 用户名，然后点击按钮：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608449-804005404.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608449-804005404.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PS：这个项目也是开源在 GitHub 上的：&lt;a href=&quot;https://github.com/lowlighter/metrics&quot;&gt;github.com/lowlighter/metrics&lt;/a&gt;，并且还有其他的功能（后续会讲到）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;就能看到效果如下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101722385-725670568.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101722385-725670568.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个配置起来稍微复杂一点点。根据&lt;a href=&quot;https://github.com/lowlighter/metrics/blob/master/.github/readme/partials/documentation/setup/action.md&quot;&gt;官网文档&lt;/a&gt;，使用该功能的方式之一是使用 GitHub Action。&lt;/p&gt;
&lt;p&gt;首先我们得创建一个 GitHub personal token，位置：右上角个人头像 → settings → Developer settings → Personal access tokens：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607461-1522764764.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607461-1522764764.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;接下来就是勾选 scopes（可以理解为权限，这个就根据不同插件的要求来勾选了，具体得看文档）：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607979-411925127.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607979-411925127.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后会生成 token，只展示一次，注意好好保管：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607843-281038661.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607843-281038661.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后去到个人项目里的 settings 页面，将刚刚生成的 token 作为一个密钥（先创建一个环境，名字为 production；然后再创建一个名字为 METRICS_TOKEN 的 secret，值为刚刚生成的 token）：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607831-1629851952.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607831-1629851952.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第三步，生成一个 Action，其实 metrics 已经帮我们生成了一个 Action：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607035-203280444.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607035-203280444.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;内容如下（建议自行核对下，例如我这边在第 9 行加了个 environment 变量）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Metrics
on:
  # Schedule updates (each hour)
  schedule: [{cron: &quot;0 * * * *&quot;}]
  # Lines below let you run workflow manually and on each commit
  workflow_dispatch:
  push: {branches: [&quot;master&quot;, &quot;main&quot;]}
jobs:
  github-metrics:
    runs-on: ubuntu-latest
    environment: 
      name: production
    permissions:
      contents: write
    steps:
      - uses: lowlighter/metrics@latest
        with:
          # Your GitHub token
          # The following scopes are required:
          #  - public_access (default scope)
          # The following additional scopes may be required:
          #  - read:org      (for organization related metrics)
          #  - read:user     (for user related data)
          #  - read:packages (for some packages related data)
          #  - repo          (optional, if you want to include private repositories)
          token: ${{ secrets.METRICS_TOKEN }}

          # Options
          user: Peter-JXL
          template: classic
          base: header, activity, community, repositories, metadata
          config_timezone: Asia/Shanghai
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;等我们提交后，就会自动生成一个 svg 文件：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607545-501989452.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607545-501989452.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后我们在自述文件里添加这个图片，例如 Markdown 格式如下（其实也可以用 HTML 格式，更灵活）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Metrics](/github-metrics.svg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此时的首页效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101735825-1579669032.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101735825-1579669032.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;GitHub 资料奖杯&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/ryo-ma/github-profile-trophy&quot;&gt;github.com/ryo-ma/github-profile-trophy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609350-744398729.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609350-744398729.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法同上，复制如下代码，更改 &lt;code&gt;?username=&lt;/code&gt; 的值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![trophy](https://github-profile-trophy.vercel.app/?username=ryo-ma)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同理，这个也可以配置主题。&lt;/p&gt;
&lt;h3&gt;GitHub 徽章&lt;/h3&gt;
&lt;p&gt;为你的开源项目生成高质量小徽章图标，直接复制链接使用。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://shields.io/&quot;&gt;Shields.io&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608312-1084523721.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608312-1084523721.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;示例代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;img src=&quot;https://img.shields.io/badge/-HTML5-E34F26?style=flat-square&amp;amp;logo=html5&amp;amp;logoColor=white&quot; /&amp;gt; 
&amp;lt;img src=&quot;https://img.shields.io/badge/-CSS3-1572B6?style=flat-square&amp;amp;logo=css3&quot; /&amp;gt; 
&amp;lt;img src=&quot;https://img.shields.io/badge/-JavaScript-oringe?style=flat-square&amp;amp;logo=javascript&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub 访客徽章&lt;/h3&gt;
&lt;p&gt;这个徽章会实时改变，记录此页面被访问的次数。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://visitor-badge.glitch.me/&quot;&gt;visitor-badge.glitch.me&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607327-1957868961.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607327-1957868961.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法：复制如下代码到 Markdown 并替换 &lt;code&gt;page_id&lt;/code&gt; 的值为用户名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![visitors](https://visitor-badge.glitch.me/badge?page_id=page.id&amp;amp;left_color=green&amp;amp;right_color=red)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以配置颜色，参数为：left_color，right_color&lt;/p&gt;
&lt;h3&gt;GitHub 活动统计图&lt;/h3&gt;
&lt;p&gt;动态生成的活动图，用于显示您过去 31 天的 GitHub 活动。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/Ashutosh00710/github-readme-activity-graph/&quot;&gt;github.com/Ashutosh00710/github-readme-activity-graph&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608680-1116378345.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608680-1116378345.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法同上，复制如下代码，更改 &lt;code&gt;?username=&lt;/code&gt; 的值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Ashutosh&apos;s github activity graph](https://github-readme-activity-graph.vercel.app/graph?username=Ashutosh00710)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以配置主题。&lt;/p&gt;
&lt;h3&gt;修仙系列统计卡片&lt;/h3&gt;
&lt;p&gt;一个以凡人修仙传境界为基础的 Github 统计卡片。等级分为：[&apos;道祖&apos;, &apos;大罗&apos;, &apos;太乙&apos;, &apos;金仙&apos;, &apos;真仙&apos;, &apos;大乘&apos;, &apos;合体&apos;, &apos;炼虚&apos;, &apos;化神&apos;, &apos;元婴&apos;, &apos;金丹&apos;, &apos;筑基&apos;, &apos;练气&apos;]，对应区间：[1, 5, 10, 15, 20, 30,40,50,60, 70, 80, 90, 100]。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/IceEnd/github-immortality&quot;&gt;IceEnd/github-immortality&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609441-686162446.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609441-686162446.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法同上，复制如下代码，更改 &lt;code&gt;?username=&lt;/code&gt; 的值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![IceEnd&apos;s GitHub stats](https://github-immortality.vercel.app/api?username=iceend)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub 连续打卡&lt;/h3&gt;
&lt;p&gt;在 README 中展示您连续提交代码的次数。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/DenverCoder1/github-readme-streak-stats&quot;&gt;github.com/DenverCoder1/github-readme-streak-stats&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101742066-699078718.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101742066-699078718.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法同上，复制如下代码，更改 &lt;code&gt;?username=&lt;/code&gt; 的值：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![GitHub Streak](https://streak-stats.demolab.com/?user=DenverCoder1)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同理，支持主题、样式等配置。&lt;/p&gt;
&lt;h3&gt;社交统计&lt;/h3&gt;
&lt;p&gt;在 README 中展示你在一些流行的网站的数据，例如知乎，GitHub，B 站，LeetCode，掘金，CSDN，牛客。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/songquanpeng/stats-cards&quot;&gt;github.com/songquanpeng/stats-cards&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608430-1064011465.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608430-1064011465.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法：复制代码到 Markdown 并替换 username 的值为那个网站的用户名&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![](https://stats.justsong.cn/api/leetcode?username=quanpeng&amp;amp;cn=true)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;star 趋势&lt;/h3&gt;
&lt;p&gt;如果想要统计和展示自己某个项目的 star 趋势，可以使用下面这两个工具。&lt;/p&gt;
&lt;h4&gt;Star History&lt;/h4&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://star-history.t9t.io/&quot;&gt;https://star-history.t9t.io&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;输入仓库名，就能自动生成 star 增长曲线。还能输入多个仓库查看项目对比：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608916-1036793162.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608916-1036793162.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;GitHub Star History&lt;/h4&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://codetabs.com/github-stars/github-star-history.html&quot;&gt;https://codetabs.com/github-stars/github-star-history.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;用法和上一个工具完全一样，就是样式有点不同：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609581-1712981499.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609581-1712981499.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;GitHub Corners：分享角标&lt;/h3&gt;
&lt;p&gt;如果你的 GitHub 项目有一个对应的网站，并且想要用户通过网站跳转到 GitHub 项目页从而得到 star，不防试试这个。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://tholman.com/github-corners&quot;&gt;https://tholman.com/github-corners&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;它可以帮你生成给网站添加 GitHub 角标的代码，只需要选择一个风格，复制代码到自己的项目主页文件中，将超链接替换为自己的仓库地址即可。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101749621-381427328.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101749621-381427328.png&quot; alt=&quot;image&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;打字特效&lt;/h3&gt;
&lt;p&gt;让内容通过打字的特效来展示，炫酷。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/DenverCoder1/readme-typing-svg&quot;&gt;github.com/DenverCoder1/readme-typing-svg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608895-596016728.svg&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608895-596016728.svg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法：复制代码到 Markdown 并替换 &lt;code&gt;?lines=&lt;/code&gt; 的值为你想要的内容，字与字之间用分号隔开&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Typing SVG](https://readme-typing-svg.demolab.com/?lines=First+line+of+text;Second+line+of+text)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更多配置参考官网文档。还可以去 &lt;a href=&quot;https://readme-typing-svg.demolab.com/demo/&quot;&gt;demo&lt;/a&gt; 站里自行调试：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608931-1806432447.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608931-1806432447.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;贪吃蛇&lt;/h3&gt;
&lt;p&gt;默认的提交信息是这样子的：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928102438867-288768880.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928102438867-288768880.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;而我们可以将其变成一个动画：一只贪吃蛇挨个吃掉图里的绿点：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607400-2109400644.svg&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607400-2109400644.svg&quot; alt=&quot;github-contribution-grid-snake&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用起来也不难，先新建一个 workflow 文件（名字随意），不需要任何改动，然后提交：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: generate animation

on:
  # run automatically every 2 hours
  schedule:
    - cron: &quot;0 */2 * * *&quot; 
  
  # allows to manually run the job at any time
  workflow_dispatch:
  
  # run on every push on the master branch
  push:
    branches:
    - master
  

jobs:
  generate:
    permissions: 
      contents: write
    runs-on: ubuntu-latest
    timeout-minutes: 5
  
    steps:
      # generates a snake game from a github user (&amp;lt;github_user_name&amp;gt;) contributions graph, output a svg animation at &amp;lt;svg_out_path&amp;gt;
      - name: generate github-contribution-grid-snake.svg
        uses: Platane/snk/svg-only@v3
        with:
          github_user_name: ${{ github.repository_owner }}
          outputs: |
            dist/github-contribution-grid-snake.svg
            dist/github-contribution-grid-snake-dark.svg?palette=github-dark
  
  
      # push the content of &amp;lt;build_dir&amp;gt; to a branch
      # the content will be available at https://raw.githubusercontent.com/&amp;lt;github_user&amp;gt;/&amp;lt;repository&amp;gt;/&amp;lt;target_branch&amp;gt;/&amp;lt;file&amp;gt; , or as github page
      - name: push github-contribution-grid-snake.svg to the output branch
        uses: crazy-max/ghaction-github-pages@v3.1.0
        with:
          target_branch: output
          build_dir: dist
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将下列代码复制到 Markdown 内，将用户名部分替换成你自己的，并提交。&lt;/p&gt;
&lt;p&gt;这段代码的目的是：加载贪吃蛇动画，且贪吃蛇的暗亮风格与你的 Github 的暗亮风格进行自动适配。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;picture&amp;gt;
  &amp;lt;source media=&quot;(prefers-color-scheme: dark)&quot; srcset=&quot;https://raw.githubusercontent.com/Peter-JXL/Peter-JXL/output/github-contribution-grid-snake-dark.svg&quot;&amp;gt;
  &amp;lt;source media=&quot;(prefers-color-scheme: light)&quot; srcset=&quot;https://raw.githubusercontent.com/Peter-JXL/Peter-JXL/output/github-contribution-grid-snake.svg&quot;&amp;gt;
  &amp;lt;img alt=&quot;github contribution grid snake animation&quot; src=&quot;https://raw.githubusercontent.com/Peter-JXL/Peter-JXL/output/github-contribution-grid-snake.svg&quot;&amp;gt;
&amp;lt;/picture&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之前我们设置的是每隔 2 小时更新一次，我们可以先手动跑一次。点击 &lt;code&gt;generate animation&lt;/code&gt;，点击 &lt;code&gt;Run workflow&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609277-1413288135.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101609277-1413288135.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;稍等片刻，显示运行成功，再次回到仓库主页就会看到贪吃蛇动画已被加载：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608452-625477041.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608452-625477041.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;博客文章同步&lt;/h3&gt;
&lt;p&gt;如果你有博客网站，且网站带有 RSS 功能，就可以配置此功能，它能在你的 GitHub 首页上显示最近更新的博客&lt;/p&gt;
&lt;p&gt;原理：利用 &lt;a href=&quot;https://github.com/gautamkrishnar/blog-post-workflow&quot;&gt;blog-post-workflow&lt;/a&gt; 在自述文件上展示最近几篇博客文章。&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101717443-837051867.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101717443-837051867.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用起来也很简单。首先创建一个 workflow（例如 &lt;code&gt;blog-post-workflow.yml&lt;/code&gt; ），需要改动最后一行的 &lt;code&gt;feed_list&lt;/code&gt; 的内容为你自己网站的 RSS 链接。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Latest blog post workflow
on:
  schedule: # Run workflow automatically
    - cron: &apos;0 */2 * * *&apos; # Runs every hour, on the hour
  workflow_dispatch: # Run workflow manually (without waiting for the cron to be called), through the GitHub Actions Workflow page directly
permissions:
  contents: write # To write the generated contents to the readme

jobs:
  update-readme-with-blog:
    name: Update this repo&apos;s README with latest blog posts
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Pull in blog&apos;s posts
        uses: gautamkrishnar/blog-post-workflow@v1
        with:
          feed_list: &quot;https://www.peterjxl.com/rss.xml&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更多构建参数请参考 🔗 &lt;a href=&quot;https://github.com/gautamkrishnar/blog-post-workflow?tab=readme-ov-file#options&quot;&gt;github.com/gautamkrishnar/blog-post-workflow&lt;/a&gt;，包括显示文章数量、显示主题等等。&lt;/p&gt;
&lt;p&gt;然后在自述文件输入这些内容，程序会自动抓取文章标题、链接等并替换这两个注释：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;📕 &amp;amp;nbsp;**Latest Blog Posts**
&amp;lt;!-- BLOG-POST-LIST:START --&amp;gt;
&amp;lt;!-- BLOG-POST-LIST:END --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同理，此时是看不到文章列表的，我们得先手工运行一次 action：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608651-808338005.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608651-808338005.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;你的 GitHub 故事&lt;/h3&gt;
&lt;p&gt;GitHub 已经内置了年度提交数统计，方便我们回顾：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607541-1341325803.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607541-1341325803.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但我们可以更炫酷地用 3D 模型来展示：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101715533-583270384.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101715533-583270384.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://skyline.github.com/&quot;&gt;https://skyline.github.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;用法：输入自己的 GitHub 用户名，和想要查看的年份，i就可以自动生成炫酷的 3D 模型。&lt;/p&gt;
&lt;p&gt;PS：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个功能是 GitHub 官方在 2021 年推出的，但是后续又下线了，暂时不知道什么时候回归。&lt;/li&gt;
&lt;li&gt;该网站可以生成 STL 文件，这是用于 3D 立体光刻的文件格式。&lt;/li&gt;
&lt;li&gt;GitHub 本身也是支持查看 &lt;a href=&quot;https://docs.github.com/zh/repositories/working-with-files/using-files/working-with-non-code-files&quot;&gt;3D 文件&lt;/a&gt;的，也就是可以托管和渲染 .stl 的 3D 文件&lt;/li&gt;
&lt;li&gt;如果你有 3D 打印机的话，可以通过该文件自己打印出来。或者用线上打印服务 &lt;a href=&quot;https://www.shapeways.com/&quot;&gt;shapeways.com&lt;/a&gt;：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101613661-1941367915.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101613661-1941367915.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;也有不少开发者拿到了打印后的纪念品：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608509-1642752248.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608509-1642752248.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;GitHub 3D 统计&lt;/h3&gt;
&lt;p&gt;使用 3D 图来展示信息。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://github.com/yoshi389111/github-profile-3d-contrib&quot;&gt;github.com/yoshi389111/github-profile-3d-contrib&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101733424-1461202365.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101733424-1461202365.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用方法是用 GitHub Action。首先创建文件 &lt;code&gt;.github/workflows/profile-3d.yml&lt;/code&gt;，内容如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: GitHub-Profile-3D-Contrib

on:
  schedule: # 03:00 JST == 18:00 UTC
    - cron: &quot;0 18 * * *&quot;
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    name: generate-github-profile-3d-contrib
    steps:
      - uses: actions/checkout@v3
      - uses: yoshi389111/github-profile-3d-contrib@0.7.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          USERNAME: ${{ github.repository_owner }}
      - name: Commit &amp;amp; Push
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add -A .
          git commit -m &quot;generated&quot;
          git push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后手动执行一次 action：&lt;code&gt;Actions&lt;/code&gt; -&amp;gt; &lt;code&gt;GitHub-Profile-3D-Contrib&lt;/code&gt; -&amp;gt; &lt;code&gt;Run workflow&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;然后会生成这些文件（带路径，各种主题的都有）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-green-animate.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-green.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-season-animate.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-season.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-south-season-animate.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-south-season.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-night-view.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-night-green.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-night-rainbow.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;profile-3d-contrib/profile-gitblock.svg&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后在 Markdown 里添加即可。&lt;/p&gt;
&lt;p&gt;PS，如果遇到了这样的报错：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;remote: Permission to mthsBelloni/mthsBelloni.git denied to github-actions[bot].
fatal: unable to access &apos;https://github.com/Peter-JXL/Peter-JXL/&apos;: The requested URL returned error: 403
Error: Process completed with exit code 128.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;大概率是因为没有配置 actions 的写权限，导致无法写入 svg 文件。解决办法：加上权限&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608018-1075866667.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608018-1075866667.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;感谢参与者&lt;/h3&gt;
&lt;p&gt;每位开源项目的参与者都值得记录和感谢，传统方式是手工编辑，项目负责人一个一个地把参与者的名字记录到 README.md，非常低效。&lt;/p&gt;
&lt;p&gt;可以使用一种更高效、自动化的方式来添加项目贡献者：&lt;/p&gt;
&lt;p&gt;项目名：All Contributors&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://allcontributors.org/&quot;&gt;https://allcontributors.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;可以用命令行或者机器人的方式自动将项目的贡献者补充到项目文档中，并且生成排版精美的表格，效果如下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101732315-1280251704.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101732315-1280251704.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Profile 编辑器&lt;/h2&gt;
&lt;p&gt;这个项目是一个是一个可视化 profile 生成工具，使用者无需学习 Markdown 语法，仅需要在对应窗口中输入或者选择相应的内容，工具会自动生成 Markdown 脚本。脚本编辑完成以后，直接复制粘贴到自己的 Github 即可。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href=&quot;https://profilinator.rishav.dev/&quot;&gt;profilinator.rishav.dev&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101611907-836613337.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101611907-836613337.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;关于 Gitee&lt;/h2&gt;
&lt;p&gt;很遗憾，Gitee，号称国内版的 GitHub，并没有提供类似的功能。但我们可以完善下个人信息部分：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607611-409520292.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607611-409520292.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;方法：在个人主页里打开个人设置&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607777-339368842.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101607777-339368842.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;打开个人资料，可以修改公司，职务，微信，QQ，领英，微博，博客，所在地，自我介绍等信息，多多少少能优化下个人主页：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101730191-1986093419.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101730191-1986093419.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;例如鱼皮的长这样：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608249-2008145442.png&quot;&gt;&lt;img src=&quot;https://img2024.cnblogs.com/blog/1139407/202409/1139407-20240928101608249-2008145442.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;最后&lt;/h2&gt;
&lt;p&gt;本文仅仅列出一些常见的功能，感兴趣的同学可以自行搜索更多功能，甚至自定义。&lt;/p&gt;
&lt;p&gt;这是我的 GitHub 主页，大家可以抄抄作业（如果能点个 star 就更好了😏）：&lt;a href=&quot;https://github.com/Peter-JXL&quot;&gt;https://github.com/Peter-JXL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;特别注意：由于 GFW 的原因，可能需要魔法上网后才能看到一些内容。&lt;/p&gt;
&lt;p&gt;最后，祝你玩得开心！&lt;/p&gt;
&lt;h2&gt;参考&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/454597068&quot;&gt;Github 首页美化教程（一）：打造个性化的 GitHub 首页 - 知乎&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://realyujie.xlog.app/Beautify-your-GitHub-personal-homepage&quot;&gt;美化自己的 GitHub 个人主页 - 0x5E&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/a2360051431/article/details/130945944&quot;&gt;Github 自定义个人首页_github 主页搭建-CSDN 博客&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>提高效率的四大好方法：启动、发呆、散步、节律</title><link>https://fuwari.vercel.app/posts/%E6%96%87%E6%91%98%E6%8F%90%E9%AB%9850%E5%AD%A6%E4%B9%A0%E5%92%8C%E5%B7%A5%E4%BD%9C%E6%95%88%E7%8E%87%E7%9A%84%E5%A5%BD%E6%96%B9%E6%B3%95/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E6%96%87%E6%91%98%E6%8F%90%E9%AB%9850%E5%AD%A6%E4%B9%A0%E5%92%8C%E5%B7%A5%E4%BD%9C%E6%95%88%E7%8E%87%E7%9A%84%E5%A5%BD%E6%96%B9%E6%B3%95/</guid><description>拒绝盲目勤奋！本文分享了四个简单易行的心理与生理调节技巧：用有效任务启动、靠发呆巩固记忆、通过散步激发灵感，以及顺应精力节律，助你轻松提升效率。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;前言&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;它们都非常简单，毫不费力，只需要你对生活做出一些小小的调整，就能立竿见影地提高你工作、学习和思考的效率。&lt;/p&gt;
&lt;p&gt;希望今天的文章，能够为你注入动力。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;一、用「有效的事情」来启动任务&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;你一定有过这样的经历：想要开始一项任务，但坐到电脑前，却总是随手打开了其他网页，或者刷起了手机、看起社交媒体。一边刷，一边在心里告诉自己：先随便溜达一下，一会再做吧。&lt;/p&gt;
&lt;p&gt;而这「一会」是多久呢？也许就在你毫不留意的时候，就过去了20分钟、30分钟……&lt;/p&gt;
&lt;p&gt;其实，如果观察一下自己，你也许会发现：很多时候，真正影响我们工作效率的，其实就是「如何启动」。一旦我们启动了，进入工作状态了，往往就能持续地做下去。&lt;/p&gt;
&lt;p&gt;这背后，其实就是大脑追求稳定的原理在作祟：我们总是不愿意改变现在的状态。当我们休息时，我们经常不愿意启动。而当我们工作时，我们往往又忘了停下来休息。&lt;/p&gt;
&lt;p&gt;所以，如果我们能尽可能减少启动的心理障碍和阻力，就能为每天省下大量被不知不觉消耗掉的时间。&lt;/p&gt;
&lt;p&gt;怎么减少阻力呢？我给自己定的规则是：一旦我坐下来了，打开了电脑，我就一定要先开始做一点「有效的事情」。做完之后，再去干别的，比如刷网页、看消息、上网闲逛……&lt;/p&gt;
&lt;p&gt;什么叫「有效的事情」呢？它可以是工作的一部分，可以是我手头上正在做的项目，也可以是一些细小而琐碎、但是能一劳永逸提高效率的事情——比如：整理自己近几天的日志、把文件资料分门别类整理好……诸如此类。&lt;/p&gt;
&lt;p&gt;总而言之，就是能够对成果有所助益的事情。&lt;/p&gt;
&lt;p&gt;不妨找一个时间，把这些事情罗列出来，形成一个清单，这就是你的「启动清单」。&lt;/p&gt;
&lt;p&gt;当你准备开始工作时，不要下意识去漫无目的地闲逛，而是先打开这张清单，从里面随便找一件事情（按照心情来就好），开始去做。&lt;/p&gt;
&lt;p&gt;做完之后，把它划掉，然后，想休息一下，想上网闲逛，或是继续工作下去，都可以。&lt;/p&gt;
&lt;p&gt;你可能会发现，许多时候，经过这么一件事情的启动，你很快就能进入工作状态，可以开始着手去做其他重要的任务了。&lt;/p&gt;
&lt;p&gt;这就是它的作用：让你快速热身，保持手感，同时，又能为你提供立等可用的成就感和反馈，让你能够有动力立刻开始行动。
&lt;img src=&quot;https://xiangce-1251040110.file.myqcloud.com/images/81/agressor/2025/07/WwihJOOXTzXvQo36AicOCpW3poW6UM.png&quot; alt=&quot;图片&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;二、 用「发呆时间」来巩固学习&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;许多人对「效率」的理解可能就是：我要在尽量短的时间内尽可能做更多的事情。因此，许多人每天都恨不得把每一秒掰成两半来用，仿佛把时间利用得越多，就占了越大的便宜。&lt;/p&gt;
&lt;p&gt;但实际上，我想告诉你的是：有时候，「什么都不做」，比起你不断地去做事情，效率反而要更高。&lt;/p&gt;
&lt;p&gt;什么意思呢？不妨考虑下面这个问题：&lt;/p&gt;
&lt;p&gt;1）在2小时的时间里，你可以看书，上网，聊天，自由地做任何你想做的事情，学习任何东西。&lt;/p&gt;
&lt;p&gt;2）在2小时的时间里，前1个小时你可以看书、上网、学习，后1个小时，切断你所有的信息输入，你只能安静地坐着发呆，什么都做不了。&lt;/p&gt;
&lt;p&gt;在上面两种情境中，哪一种情境下，你的学习效果会更好？&lt;/p&gt;
&lt;p&gt;可能很多人会选择第一种。但实际上，专门研究记忆的心理学家 Nelson Cowan 发现：后者的效果比前者要好得多。&lt;/p&gt;
&lt;p&gt;2004 年和 2012 年，Cowan 做了两个实验，结果发现：学习之后有一段时间进行休息、什么也不做的参与者，对学到的知识记得更牢，甚至在经过7天之后，遗忘率也更低。&lt;/p&gt;
&lt;p&gt;为什么呢？原因在于：当我们学习之后安静待着什么也不做时，大脑后台其实在忙碌地做一件事：对我们学到的知识进行「回放」。&lt;/p&gt;
&lt;p&gt;这种回放是无意识的、快速的，因此你觉察不到它。但是，通过对大脑的扫描，能够发现参与者的海马体有节奏地产生高频脑波，这就是大脑在努力巩固刚刚学到的知识。&lt;/p&gt;
&lt;p&gt;研究人员发现：大脑每天都会清理掉一部分当天获取的新信息。而被回放得越多的信息，就越不容易被清理。反之，回放得越少的信息，就越容易被清理掉。&lt;/p&gt;
&lt;p&gt;所以，如果你想最大化学习成果，那么请不要把自己的时间排得太紧，而是容许自己发呆和放空。这能够极大提升学习和思考的效率。
&lt;img src=&quot;https://xiangce-1251040110.file.myqcloud.com/images/81/agressor/2025/07/vrR237r3R2vf6rqRU7EE7R7E3pvcV7.png&quot; alt=&quot;图片&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;三、 用「散步思考」来激发大脑的创造力&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;如果你是从事创意工作的，比如设计、文案、策划、新媒体……那么你一定会经历过这样的需求：怎样才能提升自己的创造力？&lt;/p&gt;
&lt;p&gt;又或者，你面临工作上的瓶颈，需要想到别出心裁的方式，那么，你也一定会有这样的需求。&lt;/p&gt;
&lt;p&gt;其实，有一个非常简单且非常有效的办法：从办公桌前站起来，走出去，去散步。&lt;/p&gt;
&lt;p&gt;2014 年一个研究发现：散步可以在短时间内快速提升创造力，并且这种效应在结束散步之后，还能维持15分钟以上。&lt;/p&gt;
&lt;p&gt;原因在于：散步是一种高效的放松和休憩。它能够让我们从注意力的牢笼中挣脱出来，让我们疲惫不堪的注意力得到放松和喘息，从而重新恢复精力。&lt;/p&gt;
&lt;p&gt;当你的思维彻底放松下来时，你会暂时关闭外界的信息输入，而任由思绪在后台随机地、踊跃地激活各种不同的节点。这时，就有几率产生「远距联系」，把原本无关的节点联系起来。反映在外，就是产生创意或灵感。&lt;/p&gt;
&lt;p&gt;并且，当我们步行时，脚步对身体的反作用力会在血管中形成细微的湍流。它可以让更多的血液和氧气进入大脑，从而提高大脑的工作能力。&lt;/p&gt;
&lt;p&gt;再比如，散步这种高度有节奏感、韵律感的活动，能够让大脑处于一种平衡的、舒适的状态里，对脑波活动进行调谐，让各个脑区之间的协作更紧密高效。&lt;/p&gt;
&lt;p&gt;同时：散步可以促进BNDF（脑源形神经营养因子）的释放，提高突触的可塑性，从而让我们对知识记得更牢、思维更清晰。&lt;/p&gt;
&lt;p&gt;所以，如果你感到思维和工作遇到了瓶颈，那么不妨试一试，走出门，离开办公桌，到外面走一走。&lt;/p&gt;
&lt;p&gt;很有可能：走着走着，问题可能就突然迎刃而解了。又或者，脑海里会涌现出一些奇思妙想的点子，想到一些全新的思路和可能性……
&lt;img src=&quot;https://xiangce-1251040110.file.myqcloud.com/images/81/agressor/2025/07/B6EURu850o7R650mo7FsZsU6Ac8vM6.png&quot; alt=&quot;图片&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;四、用「场景线索」来帮助自己改变行为&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;我们的选择和行动是受什么影响的呢？答案可能让你意外：绝大多数时候，其实都是受环境影响的。&lt;/p&gt;
&lt;p&gt;举个例子：两家咖啡店，前者大家都在玩游戏、刷视频，后者大家都在认真工作、看书、学习，那么，你在前者里面一定更容易开小差，而在后者里面一定会更专注。&lt;/p&gt;
&lt;p&gt;我们的大脑无时无刻不在关注周围环境中的信息，这些信息加总起来，会形成一种非常强的势能，推动我们去做出选择、决策和行动。&lt;/p&gt;
&lt;p&gt;所以，很多时候我们以为自己的选择是自主做出的，其实都是被环境推动和影响的。&lt;/p&gt;
&lt;p&gt;应用到这里，一个非常有用的方法就是：想办法设计一个有助于行动的环境。&lt;/p&gt;
&lt;p&gt;你想更多地去做什么事情，就设计更多的环境线索来强调它、突出它、方便它；你想减少什么事情，就把它藏起来，让自己看不到它，需要花精力去找它。&lt;/p&gt;
&lt;p&gt;工作的时候，你把手机放在抽屉里，就能有效减少玩手机的行为。哪怕只是「打开抽屉，拿出手机」这么一个简单的行为，也足以减少你许多次下意识想玩手机的冲动。&lt;/p&gt;
&lt;p&gt;你想经常浏览某个网站，就把它放在浏览器的首页，一打开浏览器就能看到。或者设置成固定标签页，置顶在标签栏里，不需要从书签收藏里面去找。&lt;/p&gt;
&lt;p&gt;你想记住一个事情，最好的方法是什么？不是在脑海中不断回忆它，这很难做到，而是把它写到便签上，贴在一转眼就能看见的地方，让它更容易进入你的注意力范围。&lt;/p&gt;
&lt;p&gt;你想多在书桌上看看书、干点活，就平时多清洁书桌，不要在上面摆东西，让它随时随地处于一个「随时都能坐下来开工」的状态。&lt;/p&gt;
&lt;p&gt;你想养成运动的习惯，那就把运动的装备准备好，放在触手可及的地方，让自己毫不费力就能开始运动。&lt;/p&gt;
&lt;p&gt;你想让自己有空时多读点书，那就把书放在沙发旁边，而不是放在书架上。这样，当你处理好一天的事情，坐在沙发上时，就更容易随手拿起书、翻上几页……&lt;/p&gt;
&lt;p&gt;通过有意识的设计，让你处在一个良好的环境之中，让周围的一切成为你的助力，引导你去做出行动。这就是改变行为的秘诀。
&lt;img src=&quot;https://xiangce-1251040110.file.myqcloud.com/images/81/agressor/2025/07/LffuJ4tvzhHtEG26G2M2ht6utZNNlj.png&quot; alt=&quot;图片&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;&lt;strong&gt;五、用「精力节律」来安排自己一天的工作&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;什么叫节律？简单来说，就是你一天里面，精力和状态的波动情况。有些人白天精力十足，有些人下午状态最好，有些人晚上大脑特别活跃……这些，都是专属于自己的节律。&lt;/p&gt;
&lt;p&gt;在波峰期去做最重要、最需要聚精会神的工作，会事半功倍。反之，如果在波谷期强迫自己全神贯注去工作，那就很容易疲惫、分心、走神。&lt;/p&gt;
&lt;p&gt;所以，一个非常重要的事情是：找到自己的节律。&lt;/p&gt;
&lt;p&gt;不妨试着每天做一做日记，写一下今天在什么时间段处理了什么事情，以及自己处理事情时感受到的状态。如果长期来看，某个时间段你的思维特别活跃，精力似乎很旺盛，总是能把事情很快做完，那么它很可能就是你的「波峰时间」。&lt;/p&gt;
&lt;p&gt;像有些人，最佳的工作时间可能是下午到傍晚，那么更适合他们的工作习惯就是：早上起来之后先处理一些简单、琐碎的工作，减轻大脑负担；等到了一天里面状态最好的时间段，再集中精力去做最重要的任务。&lt;/p&gt;
&lt;p&gt;而有些人最佳的时间可能在晚上，那么就需要尽量留出晚上的时间，减少不必要的娱乐和消遣，用来学习、思考和处理一些自己感兴趣的项目。&lt;/p&gt;
&lt;p&gt;一旦你找到自己的「波峰时间」，那么对应的，你也可以找到自己的「波谷时间」和「正常时间」。那么不妨按照这个节奏，来安排自己的任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;最琐碎的、最不重要的、不需要耗脑子的（一般是整理和操作性事务），以及可以快速得到反馈的，安排在「波谷时间」；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;日常的事务，沟通，协作，信息回复，安排在「正常时间」；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最重要的工作，包括跟自己业绩目标紧密挂钩，需要做出亮点和成果的，又或者需要投入精力去学习的，安排在「波峰时间」。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样，才能做到真正的事半功倍。
&lt;img src=&quot;https://xiangce-1251040110.file.myqcloud.com/images/81/agressor/2025/07/Z8M32JV1VM38K0UkV19dD1HvV2zu8g.png&quot; alt=&quot;图片&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;转载说明&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;原文出处：[微信公众号/L先生生说]
原文链接：[&lt;a href=&quot;https://mp.weixin.qq.com/s/8as12gNdggWJ0ASNTiRLDA&quot;&gt;能帮你提高50%学习和工作效率的好方法&lt;/a&gt;]&lt;/p&gt;
</content:encoded></item><item><title>快速部署指南：搭建一个 Fuwari 博客</title><link>https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA-fuwari-%E5%8D%9A%E5%AE%A2/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%BF%AB%E9%80%9F%E9%83%A8%E7%BD%B2%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA-fuwari-%E5%8D%9A%E5%AE%A2/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA-fuwari-%E5%8D%9A%E5%AE%A2/fuwari%E5%8D%9A%E5%AE%A2%E6%94%B9%E9%80%A0%E8%AE%A1%E5%88%92%E5%BF%AB%E9%80%9F%E9%83%A8%E7%BD%B2%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA-fuwari-%E5%8D%9A%E5%AE%A2/</guid><description>手把手教你如何使用 Astro 与 Fuwari 模板快速构建一个极简且优雅的静态博客，并实现 Netlify 一键部署。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;一、准备工作&lt;/h2&gt;
&lt;p&gt;在开始之前，请确保你的开发环境已安装以下工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Node.js&lt;/strong&gt;（建议使用最新 LTS 版本，如 v18 或 v20）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;包管理工具&lt;/strong&gt;（推荐使用 &lt;code&gt;pnpm&lt;/code&gt;，本文将基于它进行操作）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码编辑器&lt;/strong&gt;（推荐使用 &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git&lt;/strong&gt;（可选）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以通过以下命令检查是否已安装 Node.js 和 npm：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;node -v
npm -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果尚未安装，请前往 &lt;a href=&quot;https://nodejs.org&quot;&gt;Node.js 官网&lt;/a&gt; 下载并安装。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;二、创建你的 Fuwari 博客&lt;/h2&gt;
&lt;p&gt;打开终端（命令行工具），选择一个工作目录，执行以下命令来全局安装 &lt;code&gt;pnpm&lt;/code&gt; 和 &lt;code&gt;Netlify CLI&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -g pnpm
npm install -g netlify-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 提示：&lt;code&gt;-g&lt;/code&gt; 表示全局安装，确保命令可在任意目录下使用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;接下来，使用 Astro 的官方创建工具初始化一个 Fuwari 博客项目：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm create fuwari@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;系统会提示你输入项目名称，然后自动拉取模板并安装依赖。&lt;/p&gt;
&lt;p&gt;进入项目目录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd my-fuwari-blog
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动本地开发服务器：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;浏览器会自动打开 &lt;code&gt;http://localhost:4321&lt;/code&gt;，你将看到一个简洁优雅的博客首页，说明项目已成功运行。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;三、自定义你的博客&lt;/h2&gt;
&lt;p&gt;Fuwari 的配置文件位于根目录下的 &lt;code&gt;src/config.ts&lt;/code&gt;，你可以在这里修改：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;博客标题（title）&lt;/li&gt;
&lt;li&gt;博客副标题（subtitle）&lt;/li&gt;
&lt;li&gt;语言(lang)&lt;/li&gt;
&lt;li&gt;博客横幅（banner）&lt;/li&gt;
&lt;li&gt;站点 URL 等&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const siteConfig: SiteConfig = {
	title: &quot;晓正杨博客&quot;,
	subtitle: &quot;&quot;,
	lang: &quot;zh_CN&quot;, // &apos;en&apos;, &apos;zh_CN&apos;, &apos;zh_TW&apos;, &apos;ja&apos;, &apos;ko&apos;, &apos;es&apos;, &apos;th&apos;
	themeColor: {
		hue: 250, // Default hue for the theme color, from 0 to 360. e.g. red: 0, teal: 200, cyan: 250, pink: 345
		fixed: false, // Hide the theme color picker for visitors
	},
	banner: {
		enable: false,
		src: &quot;https://cn.cravatar.com/avatar/422d385af346ddd0b23f81d704ecf1c6&quot;, // Relative to the /src directory. Relative to the /public directory if it starts with &apos;/&apos;
		position: &quot;center&quot;, // Equivalent to object-position, only supports &apos;top&apos;, &apos;center&apos;, &apos;bottom&apos;. &apos;center&apos; by default
		credit: {
			enable: false, // Display the credit text of the banner image
			text: &quot;&quot;, // Credit text to be displayed
			url: &quot;&quot;, // (Optional) URL link to the original artwork or artist&apos;s page
		},
	},
	toc: {
		enable: true, // Display the table of contents on the right side of the post
		depth: 2, // Maximum heading depth to show in the table, from 1 to 3
	},
	favicon: [
		// Leave this array empty to use the default favicon
		// {
		//   src: &apos;/favicon/icon.png&apos;,    // Path of the favicon, relative to the /public directory
		//   theme: &apos;light&apos;,              // (Optional) Either &apos;light&apos; or &apos;dark&apos;, set only if you have different favicons for light and dark mode
		//   sizes: &apos;32x32&apos;,              // (Optional) Size of the favicon, set only if you have favicons of different sizes
		// }
	],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;文章内容位于 &lt;code&gt;src/content/posts/&lt;/code&gt; 目录中，使用 Markdown 编写。你可以复制示例文章并新建自己的 &lt;code&gt;.md&lt;/code&gt; 文件。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;✅ 命名规范：建议使用小写字母、连字符命名，如 &lt;code&gt;how-to-build-a-blog.md&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;四、构建静态文件&lt;/h2&gt;
&lt;p&gt;当你完成内容编辑后，使用以下命令生成静态页面：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;构建完成后，会在项目根目录生成 &lt;code&gt;dist/&lt;/code&gt; 文件夹，其中包含所有可供部署的 HTML、CSS 和 JavaScript 文件。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;五、将本地项目上传至Github&lt;/h2&gt;
&lt;p&gt;如果你是通过 HTTPS 克隆的可以通过 &lt;code&gt;git set-url origin git@github.com:[你的仓库名称]&lt;/code&gt; 改成 SSH&lt;/p&gt;
&lt;p&gt;然后，正常的提交推送就好啦~（依次运行下面的代码）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git add .
git commit -m &quot;[对提交的描述]&quot;
git push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样你的文章就推送到远程仓库啦~&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;六、部署到CloudFlare&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在 Cloudflare - Workers - Workers 和 Pages - 创建，创建一个 Page&lt;/li&gt;
&lt;li&gt;关联你之前 Fork 来的 Github 仓库。&lt;/li&gt;
&lt;li&gt;设置 &lt;strong&gt;构建指令&lt;/strong&gt; 为 &lt;code&gt;pnpm build&lt;/code&gt;，&lt;strong&gt;构建输出目录&lt;/strong&gt; 为 `dist&lt;/li&gt;
&lt;li&gt;绑定自定义域名(可选)，这样访问你绑定的域名就可以访问你的博客啦！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你只需要重复之前的写文章和提交操作，你的文章就会被自动部署到 Cloudflare！&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;七、后续文章撰写与维护&lt;/h2&gt;
&lt;p&gt;如果嫌麻烦的话还可以试试我写的一个简单的脚本，只要在根目录创建一个 &lt;code&gt;bat&lt;/code&gt; 后缀的文件写入以下内容，以后每次要写文章只需要运行此脚本跟着提示做就可以实现半自动创建文章并提交(～￣▽￣)～（仅Windows）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@echo off
git pull

:: Create
set /p mark=&quot;Press article keywords(&quot;-^&quot; to link): &quot;
echo Run it by yourself: pnpm new-post %mark%
echo Then press enter to open the blog with default method.

pause &amp;gt; nul

explorer &quot;.\src\content\posts\%mark%.md&quot;

echo Press enter to submit the blog.
pause &amp;gt; nul

:: Commit
git add .
git commit -m &quot;Update %mark%&quot;
git push

echo Press enter to end.
pause &amp;gt; nul
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;八、文章的 Front-matter（前置参数）&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: 我的第一篇博客文章
published: 2023-09-09
description: 这是我的新 Astro 博客的第一篇文章。
image: ./cover.jpg
tags: [ Foo, Bar ]
category: 前端
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;属性&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;title&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;文章的标题。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;published&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;文章的发布日期。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;description&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;文章的简短描述，显示在首页。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;image&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;文章封面图路径。&amp;lt;br&amp;gt;1. 以 &lt;code&gt;http://&lt;/code&gt; 或 &lt;code&gt;https://&lt;/code&gt; 开头：使用网络图片。&amp;lt;br&amp;gt;2. 以 &lt;code&gt;/&lt;/code&gt; 开头：使用 &lt;code&gt;public&lt;/code&gt; 目录下的图片。&amp;lt;br&amp;gt;3. 无前缀：相对于 Markdown 文件的相对路径。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tags&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;文章的标签。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;category&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;文章的分类。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;draft&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;如果设为 &lt;code&gt;true&lt;/code&gt;，则该文章为草稿，不会被显示。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;九、文章文件存放位置&lt;/h2&gt;
&lt;p&gt;您的文章文件应放置在 &lt;code&gt;src/content/posts/&lt;/code&gt; 目录下。您还可以创建子目录来更好地组织文章和资源文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;十、结语&lt;/h2&gt;
&lt;p&gt;通过本文，你已经成功搭建并部署了一个基于 &lt;strong&gt;Fuwari + Astro&lt;/strong&gt; 的极简静态博客。整个过程无需服务器、不涉及后端，安全、快速、免费。&lt;/p&gt;
&lt;p&gt;Fuwari 的设计理念是“少即是多”，让写作者专注于内容本身。现在，是时候开始写下你的第一篇文章了！&lt;/p&gt;
</content:encoded></item><item><title>常用 CMD 命令提示符大全</title><link>https://fuwari.vercel.app/posts/%E9%9B%86%E5%90%88%E5%B8%B8%E7%94%A8%E7%9A%84cmd%E5%91%BD%E4%BB%A4%E9%9B%86%E5%90%88/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E9%9B%86%E5%90%88%E5%B8%B8%E7%94%A8%E7%9A%84cmd%E5%91%BD%E4%BB%A4%E9%9B%86%E5%90%88/</guid><description>Windows 系统管理必备！本文汇总了常用的 CMD 命令，涵盖系统工具调用、磁盘管理及电源管理快捷指令，助你摆脱繁琐的图形界面操作。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;CMD 命令提示符&lt;/strong&gt;是 Windows 操作系统中一个重要的工具，通过 CMD 命令可以执行各种系统管理和配置操作。本文将介绍常用的 CMD 命令，帮助读者更好地了解和使用 CMD 命令提示符。&lt;/p&gt;
&lt;h3&gt;常用系统管理命令表&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;序号&lt;/th&gt;
&lt;th&gt;命令名称&lt;/th&gt;
&lt;th&gt;功能描述&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;calc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动计算器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;appwiz.cpl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;程序和功能（卸载或修改程序）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;certmgr.msc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;证书管理实用程序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;charmap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动字符映射表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chkdsk.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Chkdsk 磁盘检查（需管理员权限）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cleanmgr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打开磁盘清理工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cliconfg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SQL SERVER 客户端网络实用工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cmstp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;连接管理器配置文件安装程序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cmd.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打开新的 CMD 命令提示符窗口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;code&gt;colorcpl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;颜色管理（配置显示器和打印机色彩）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;&lt;code&gt;compmgmt.msc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;计算机管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;&lt;code&gt;credwiz&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;备份或还原储存的用户名和密码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;&lt;code&gt;comexp.msc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打开系统组件服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;&lt;code&gt;control&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打开控制面板&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dcomcnfg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;打开系统组件服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Dccw&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示颜色校准&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;&lt;code&gt;devmgmt.msc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;设备管理器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;&lt;code&gt;desk.cpl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;屏幕分辨率设置&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dfrgui&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;优化驱动器（Win7 为 &lt;code&gt;dfrg.msc&lt;/code&gt; 磁盘碎片整理）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dialer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;电话拨号程序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;&lt;code&gt;diskmgmt.msc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;磁盘管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dvdplay&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DVD 播放器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dxdiag&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查 DirectX 信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eudcedit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;造字程序&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h3&gt;电源管理快捷命令&lt;/h3&gt;
&lt;p&gt;针对自动关机与锁定操作，可以使用以下快速指令：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自动关机&lt;/strong&gt;：&lt;code&gt;Shutdown -s -t 30&lt;/code&gt; （表示 30 秒后自动关机）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;取消关机&lt;/strong&gt;：&lt;code&gt;shutdown -a&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动重启&lt;/strong&gt;：&lt;code&gt;Shutdown -r -t 30&lt;/code&gt; （表示 30 秒后自动重启）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;锁定计算机&lt;/strong&gt;：&lt;code&gt;rundll32 user32.dll,LockWorkStation&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Edge 浏览器中的键盘快捷方式全指南</title><link>https://fuwari.vercel.app/posts/%E9%9B%86%E5%90%88edge%E9%94%AE%E7%9B%98%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F%E9%9B%86%E5%90%88/</link><guid isPermaLink="true">https://fuwari.vercel.app/posts/%E9%9B%86%E5%90%88edge%E9%94%AE%E7%9B%98%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F%E9%9B%86%E5%90%88/</guid><description>掌握 Microsoft Edge 的核心快捷键，显著提升网页浏览、标签页管理及 PDF 阅读的效率，让你的操作快人一步。</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://support.microsoft.com/zh-cn/microsoft-edge/microsoft-edge-%E4%B8%AD%E7%9A%84%E9%94%AE%E7%9B%98%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F-50d3edab-30d9-c7e4-21ce-37fe2713cfad&quot;&gt;https://support.microsoft.com/zh-cn/microsoft-edge/microsoft-edge-中的键盘快捷方式-50d3edab-30d9-c7e4-21ce-37fe2713cfad&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;应用对象 Edge for Windows Edge for Mac&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;键盘快捷方式是指按键或按键组合，可提供另一种方式来执行通常使用鼠标执行的操作。 下面是适用于 新版 Microsoft Edge 和 Microsoft Edge for Mac 的列表。&lt;/p&gt;
&lt;h2&gt;Microsoft Edge 中的键盘快捷方式&lt;a href=&quot;https://blog.142588.xyz/posts/%E6%B5%8B%E8%AF%95/#microsoft-edge-%E4%B8%AD%E7%9A%84%E9%94%AE%E7%9B%98%E5%BF%AB%E6%8D%B7%E6%96%B9%E5%BC%8F&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;按此键&lt;/th&gt;
&lt;th&gt;执行此操作&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;按此键&lt;/td&gt;
&lt;td&gt;执行此操作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +B&lt;/td&gt;
&lt;td&gt;显示或隐藏收藏夹栏&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt+Shift +B&lt;/td&gt;
&lt;td&gt;将焦点放在收藏夹栏中的第一项上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +D&lt;/td&gt;
&lt;td&gt;将当前选项卡另存为收藏夹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +D&lt;/td&gt;
&lt;td&gt;在新文件夹中将所有打开的标签页另存为收藏夹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +E&lt;/td&gt;
&lt;td&gt;在边栏中打开搜索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt +D&lt;/td&gt;
&lt;td&gt;选择地址栏中的 URL 以进行编辑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +E&lt;/td&gt;
&lt;td&gt;在地址栏中打开搜索查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt + E&lt;/td&gt;
&lt;td&gt;打开“设置及更多 ”菜单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + F&lt;/td&gt;
&lt;td&gt;在页面上打开查找&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt +F&lt;/td&gt;
&lt;td&gt;打开“设置及更多 ”菜单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +G&lt;/td&gt;
&lt;td&gt;跳转到下一个结果以在页面上查找&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +G&lt;/td&gt;
&lt;td&gt;跳转到上一个结果以在页面上查找&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +H&lt;/td&gt;
&lt;td&gt;打开历史记录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +I&lt;/td&gt;
&lt;td&gt;打开开发人员工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt +Shift +I&lt;/td&gt;
&lt;td&gt;打开“发送反馈”对话框&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +J&lt;/td&gt;
&lt;td&gt;打开“下载”文件夹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +K&lt;/td&gt;
&lt;td&gt;在地址栏中打开搜索查询&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +K&lt;/td&gt;
&lt;td&gt;复制当前标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +L&lt;/td&gt;
&lt;td&gt;选择地址栏中的 URL 以进行编辑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +L&lt;/td&gt;
&lt;td&gt;粘贴并搜索或粘贴并访问（如果它是 URL）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +M&lt;/td&gt;
&lt;td&gt;将当前标签页设为静音（切换）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +M&lt;/td&gt;
&lt;td&gt;以其他用户身份登录或以来宾身份浏览&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +N&lt;/td&gt;
&lt;td&gt;打开新窗口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +N&lt;/td&gt;
&lt;td&gt;打开新的 InPrivate 窗口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +O&lt;/td&gt;
&lt;td&gt;在 Microsoft Edge 中打开计算机中的文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +O&lt;/td&gt;
&lt;td&gt;打开收藏夹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +P&lt;/td&gt;
&lt;td&gt;打印当前页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +P&lt;/td&gt;
&lt;td&gt;使用系统对话框打印&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + R&lt;/td&gt;
&lt;td&gt;重新加载当前页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + Shift + R&lt;/td&gt;
&lt;td&gt;重新加载当前页，忽略缓存内容&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + S&lt;/td&gt;
&lt;td&gt;保存当前页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +T&lt;/td&gt;
&lt;td&gt;打开新标签页并切换到该标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +T&lt;/td&gt;
&lt;td&gt;重新打开上一个关闭的标签页并切换到该标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt + Shift + T&lt;/td&gt;
&lt;td&gt;将焦点放在应用栏工具栏中的第一项上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + U&lt;/td&gt;
&lt;td&gt;查看源&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +U&lt;/td&gt;
&lt;td&gt;开始或停止“大声朗读”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +V&lt;/td&gt;
&lt;td&gt;不带格式粘贴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +W&lt;/td&gt;
&lt;td&gt;关闭当前标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +W&lt;/td&gt;
&lt;td&gt;关闭当前窗口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Shift +Y&lt;/td&gt;
&lt;td&gt;打开集合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +0 （零）&lt;/td&gt;
&lt;td&gt;重置页面缩放级别&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +1,2, … 8&lt;/td&gt;
&lt;td&gt;切换到特定标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +9&lt;/td&gt;
&lt;td&gt;切换到最后一个标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +Enter&lt;/td&gt;
&lt;td&gt;将 www. 和 .com 分别添加到在地址栏中键入的文本的开头和末尾&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + Tab&lt;/td&gt;
&lt;td&gt;切换到下一个标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + Shift+ Tab&lt;/td&gt;
&lt;td&gt;切换到上一个标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+ 加号(+)&lt;/td&gt;
&lt;td&gt;放大&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + 减号 (-)&lt;/td&gt;
&lt;td&gt;缩小&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + \（在 PDF 中）&lt;/td&gt;
&lt;td&gt;在“根据页面调整”与“根据宽度调整”之间切换 PDF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl+ [ （在 PDF 中）&lt;/td&gt;
&lt;td&gt;将 PDF 逆时针旋转 90 度*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + ]（在 PDF 中）&lt;/td&gt;
&lt;td&gt;将 PDF 顺时针旋转 90 度*&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + Shift + Delete&lt;/td&gt;
&lt;td&gt;打开清除浏览数据选项&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt&lt;/td&gt;
&lt;td&gt;将焦点放在“设置及更多 ”按钮上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt + 向左键&lt;/td&gt;
&lt;td&gt;返回&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt + 向右键&lt;/td&gt;
&lt;td&gt;前进&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt + Home&lt;/td&gt;
&lt;td&gt;在当前标签页中打开主页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alt + F4&lt;/td&gt;
&lt;td&gt;关闭当前窗口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F1&lt;/td&gt;
&lt;td&gt;打开帮助&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F3&lt;/td&gt;
&lt;td&gt;查找当前标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F4&lt;/td&gt;
&lt;td&gt;选择地址栏中的 URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + F4&lt;/td&gt;
&lt;td&gt;关闭当前标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F5&lt;/td&gt;
&lt;td&gt;重新加载当前标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shift + F5&lt;/td&gt;
&lt;td&gt;重新加载当前标签页，忽略缓存内容&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F6&lt;/td&gt;
&lt;td&gt;将焦点移动到下一个窗格&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shift +F6&lt;/td&gt;
&lt;td&gt;将焦点移动到上一个窗格&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl +F6&lt;/td&gt;
&lt;td&gt;将焦点移动到 Web 内容窗格&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F7&lt;/td&gt;
&lt;td&gt;打开或关闭插入光标浏览&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F9&lt;/td&gt;
&lt;td&gt;进入或退出沉浸式阅读器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F10&lt;/td&gt;
&lt;td&gt;将焦点放在“设置及更多 ”按钮上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F10+ Enter&lt;/td&gt;
&lt;td&gt;打开“设置及更多 ”菜单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shift + F10&lt;/td&gt;
&lt;td&gt;打开上下文菜单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F11&lt;/td&gt;
&lt;td&gt;进入全屏（切换）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F12&lt;/td&gt;
&lt;td&gt;打开开发人员工具&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Esc&lt;/td&gt;
&lt;td&gt;停止加载页面；关闭对话框或弹出窗口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;空格键&lt;/td&gt;
&lt;td&gt;向下滚动网页，一次滚动一个屏幕&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shift + 空格键&lt;/td&gt;
&lt;td&gt;向上滚动网页，一次滚动一个屏幕&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PgDn&lt;/td&gt;
&lt;td&gt;向下滚动网页，一次滚动一个屏幕&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + PgDn&lt;/td&gt;
&lt;td&gt;切换到下一个标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PgUp&lt;/td&gt;
&lt;td&gt;向上滚动网页，一次滚动一个屏幕&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ctrl + PgUp&lt;/td&gt;
&lt;td&gt;切换到上一个标签页&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Home 键&lt;/td&gt;
&lt;td&gt;转到页面顶部，将键盘焦点移动到窗格的第一项&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;End&lt;/td&gt;
&lt;td&gt;转到页面底部，将键盘焦点移动到窗格的最后一项&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tab&lt;/td&gt;
&lt;td&gt;转到下一个制表位&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shift + Tab&lt;/td&gt;
&lt;td&gt;转到上一个制表位&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item></channel></rss>