<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><author><name>鸣心</name></author><generator uri="https://hexo.io/">Hexo</generator><icon>https://b.wihi.top/img/avatar.png</icon><id>https://b.wihi.top/</id><link href="https://b.wihi.top/" rel="alternate"/><link href="https://b.wihi.top/atom.xml" rel="self"/><rights>All rights reserved 2026, 鸣心</rights><subtitle>欢迎访问笔搁纸鸯</subtitle><title>笔搁纸鸯</title><updated>2026-04-04T12:43:48.000Z</updated><entry><author><name>鸣心</name></author><category term="Hexo" scheme="https://b.wihi.top/categories/Hexo/"/><category term="Hexo" scheme="https://b.wihi.top/tags/Hexo/"/><content><![CDATA[<p><font size="4">在Hexo-fluid的分类页中增加说明(2)--注入法</font></p><blockquote><p>之前发过一篇文章：<a href="https://b.wihi.top/posts/8de7287f.html">在Hexo-fluid的分类页中增加说明</a>，实现在分类页面增加说明介绍分类，是通过修改主题模板文件实习的，如果后期主题更新还需要手动再次修改，不太方便，这次实现不修改主题源码，数据驱动的内容注入</p></blockquote><h2 id="背景">背景</h2><p>在使用 Hexo + Fluid 主题时，我需要在分类页（/categories/）顶部添加一个“专栏说明”板块，用于展示不同分类的介绍、图标和自定义颜色。要求：</p><p>· 不修改主题源文件（便于后续升级）<br>· 内容通过配置文件管理（无需改动代码）<br>· 位置精确（位于分类列表之前）</p><p>经过探索，最终采用 Hexo 官方的 after_render:html 过滤器实现。下面分享完整的实现过程。</p><p>最终效果参见本站的<a href="https://b.wihi.top/categories/">分类页</a></p><h2 id="一、整体思路">一、整体思路</h2><ol><li>监听生成事件：使用 after_render:html 过滤器，在每个 HTML 文件生成后执行。</li><li>识别目标页面：判断当前文件路径是否为 categories/index.html。</li><li>注入样式：在 </head> 前插入专栏卡片所需的 CSS。</li><li>读取数据：从 source/_data/ 目录下的 YAML 文件中读取专栏配置。</li><li>生成 HTML：遍历数据，生成与主题结构兼容的卡片 HTML。</li><li>插入到正确位置：通过正则匹配分类列表容器（<code>&lt;div class=&quot;category-list&quot;&gt;</code>），将卡片 HTML 插入其前面。</li><li>返回修改后的内容。</li></ol><h2 id="二、具体实现">二、具体实现</h2><h3 id="1-引入-Font-Awesome（可选）">1. 引入 Font Awesome（可选）</h3><p>本方案使用 Font Awesome 免费图标库。请确保你的主题已引入 Font Awesome CSS，例如在主题配置或全局布局中添加：</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;stylesheet&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css&quot;</span>&gt;</span><br></code></pre></td></tr></table></figure><p>如果未引入，也可以在注入脚本中一并注入（见下文脚本注释）。</p><ol start="2"><li>创建数据文件</li></ol><p>在 source/_data/ 目录下新建：<br><strong>column_descriptions.yml</strong></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs yaml"><span class="hljs-attr">columns:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">&quot;技术随笔&quot;</span><br>    <span class="hljs-attr">subtitle:</span> <span class="hljs-string">&quot;编程与开发心得&quot;</span><br>    <span class="hljs-attr">icon:</span> <span class="hljs-string">&quot;fas fa-code&quot;</span><br>    <span class="hljs-attr">description:</span> <span class="hljs-string">&quot;分享前端、后端、DevOps 等技术实践。&quot;</span><br>    <span class="hljs-attr">color:</span> <span class="hljs-string">&quot;#1890ff&quot;</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">&quot;生活杂谈&quot;</span><br>    <span class="hljs-attr">subtitle:</span> <span class="hljs-string">&quot;日常思考与感悟&quot;</span><br>    <span class="hljs-attr">icon:</span> <span class="hljs-string">&quot;fas fa-pen-fancy&quot;</span><br>    <span class="hljs-attr">description:</span> <span class="hljs-string">&quot;记录生活中的点滴与读书笔记。&quot;</span><br>    <span class="hljs-attr">color:</span> <span class="hljs-string">&quot;#f5222d&quot;</span><br></code></pre></td></tr></table></figure><p>· icon 字段直接填写 Font Awesome 的完整类名（如 fas fa-code）。<br>· color 用于卡片边框、图标和高亮颜色。</p><p><em>注：name、subtitle、icon、description、color 请根据需求自行调整</em></p><ol start="3"><li>编写注入脚本</li></ol><p>在博客根目录创建 scripts/ 文件夹（如果没有），然后新建：<br><strong>categories-inject.js</strong></p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// scripts/categories-inject.js</span><br><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;fs&#x27;</span>);<br><span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;path&#x27;</span>);<br><span class="hljs-keyword">const</span> yaml = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;js-yaml&#x27;</span>);<br><br>hexo.<span class="hljs-property">extend</span>.<span class="hljs-property">filter</span>.<span class="hljs-title function_">register</span>(<span class="hljs-string">&#x27;after_render:html&#x27;</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">str, data</span>) &#123;<br>  <span class="hljs-comment">// 仅处理分类页</span><br>  <span class="hljs-keyword">if</span> (data.<span class="hljs-property">path</span> !== <span class="hljs-string">&#x27;categories/index.html&#x27;</span>) <span class="hljs-keyword">return</span> str;<br><br>  <span class="hljs-comment">// 1. 注入自定义 CSS</span><br>  <span class="hljs-keyword">if</span> (!str.<span class="hljs-title function_">includes</span>(<span class="hljs-string">&#x27;/css/column-cards.css&#x27;</span>)) &#123;<br>    str = str.<span class="hljs-title function_">replace</span>(<span class="hljs-string">&#x27;&lt;/head&gt;&#x27;</span>, <span class="hljs-string">&#x27;&lt;link rel=&quot;stylesheet&quot; href=&quot;/css/column-cards.css&quot;&gt;&lt;/head&gt;&#x27;</span>);<br>  &#125;<br><br>  <span class="hljs-comment">// 可选：如果主题没有引入 Font Awesome，可以在这里注入</span><br>  <span class="hljs-keyword">if</span> (!str.<span class="hljs-title function_">includes</span>(<span class="hljs-string">&#x27;font-awesome&#x27;</span>)) &#123;<br>    str = str.<span class="hljs-title function_">replace</span>(<span class="hljs-string">&#x27;&lt;/head&gt;&#x27;</span>, <span class="hljs-string">&#x27;&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css&quot;&gt;&lt;/head&gt;&#x27;</span>);<br>  &#125;<br><br>  <span class="hljs-comment">// 2. 读取专栏数据</span><br>  <span class="hljs-keyword">const</span> dataPath = path.<span class="hljs-title function_">join</span>(hexo.<span class="hljs-property">source_dir</span>, <span class="hljs-string">&#x27;_data&#x27;</span>, <span class="hljs-string">&#x27;column_descriptions.yml&#x27;</span>);<br>  <span class="hljs-keyword">let</span> columns = [];<br>  <span class="hljs-keyword">if</span> (fs.<span class="hljs-title function_">existsSync</span>(dataPath)) &#123;<br>    <span class="hljs-keyword">try</span> &#123;<br>      <span class="hljs-keyword">const</span> content = fs.<span class="hljs-title function_">readFileSync</span>(dataPath, <span class="hljs-string">&#x27;utf8&#x27;</span>);<br>      <span class="hljs-keyword">const</span> yamlData = yaml.<span class="hljs-title function_">load</span>(content);<br>      columns = yamlData &amp;&amp; yamlData.<span class="hljs-property">columns</span> ? yamlData.<span class="hljs-property">columns</span> : [];<br>    &#125; <span class="hljs-keyword">catch</span> (e) &#123;<br>      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">&#x27;读取专栏数据失败:&#x27;</span>, e);<br>    &#125;<br>  &#125;<br><br>  <span class="hljs-keyword">if</span> (!columns.<span class="hljs-property">length</span>) <span class="hljs-keyword">return</span> str;<br><br>  <span class="hljs-comment">// 3. 生成专栏卡片 HTML</span><br>  <span class="hljs-keyword">const</span> cardsHtml = <span class="hljs-title function_">generateCardsHtml</span>(columns);<br><br>  <span class="hljs-comment">// 4. 插入到分类列表之前（正则匹配 class=&quot;category-list&quot; 的 div）</span><br>  <span class="hljs-keyword">const</span> categoryListRegex = <span class="hljs-regexp">/&lt;div\s+class=&quot;category-list&quot;[^&gt;]*&gt;/i</span>;<br>  <span class="hljs-keyword">const</span> match = str.<span class="hljs-title function_">match</span>(categoryListRegex);<br>  <span class="hljs-keyword">if</span> (match) &#123;<br>    <span class="hljs-keyword">const</span> insertPosition = match.<span class="hljs-property">index</span>;<br>    str = str.<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, insertPosition) + cardsHtml + str.<span class="hljs-title function_">slice</span>(insertPosition);<br>  &#125; <span class="hljs-keyword">else</span> &#123;<br>    <span class="hljs-comment">// 回退：插入到 &lt;body&gt; 后</span><br>    str = str.<span class="hljs-title function_">replace</span>(<span class="hljs-string">&#x27;&lt;body&gt;&#x27;</span>, <span class="hljs-string">&#x27;&lt;body&gt;\n&#x27;</span> + cardsHtml);<br>  &#125;<br><br>  <span class="hljs-keyword">return</span> str;<br>&#125;);<br><br><span class="hljs-comment">// 生成卡片 HTML（适配 Font Awesome）</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">generateCardsHtml</span>(<span class="hljs-params">columns</span>) &#123;<br>  <span class="hljs-keyword">let</span> html = <span class="hljs-string">&#x27;&lt;div class=&quot;columns-container&quot;&gt;&#x27;</span>;<br>  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> col <span class="hljs-keyword">of</span> columns) &#123;<br>    <span class="hljs-keyword">const</span> color = col.<span class="hljs-property">color</span> || <span class="hljs-string">&#x27;#1890ff&#x27;</span>;<br>    <span class="hljs-keyword">const</span> rgb = <span class="hljs-title function_">hexToRgb</span>(color);<br>    html += <span class="hljs-string">`</span><br><span class="hljs-string">      &lt;div class=&quot;column-card&quot; style=&quot;--column-color: <span class="hljs-subst">$&#123;color&#125;</span>; --column-color-rgb: <span class="hljs-subst">$&#123;rgb.join(<span class="hljs-string">&#x27;,&#x27;</span>)&#125;</span>;&quot;&gt;</span><br><span class="hljs-string">        &lt;div class=&quot;card-header&quot;&gt;</span><br><span class="hljs-string">          &lt;i class=&quot;<span class="hljs-subst">$&#123;col.icon || <span class="hljs-string">&#x27;fas fa-circle-info&#x27;</span>&#125;</span>&quot;&gt;&lt;/i&gt;</span><br><span class="hljs-string">          &lt;div&gt;</span><br><span class="hljs-string">            &lt;h3&gt;<span class="hljs-subst">$&#123;escapeHtml(col.name)&#125;</span>专栏&lt;/h3&gt;</span><br><span class="hljs-string">            <span class="hljs-subst">$&#123;col.subtitle ? <span class="hljs-string">`&lt;p class=&quot;subtitle&quot;&gt;<span class="hljs-subst">$&#123;escapeHtml(col.subtitle)&#125;</span>&lt;/p&gt;`</span> : <span class="hljs-string">&#x27;&#x27;</span>&#125;</span></span><br><span class="hljs-string">          &lt;/div&gt;</span><br><span class="hljs-string">        &lt;/div&gt;</span><br><span class="hljs-string">        &lt;div class=&quot;card-content&quot;&gt;</span><br><span class="hljs-string">          &lt;p&gt;<span class="hljs-subst">$&#123;escapeHtml(col.description)&#125;</span>&lt;/p&gt;</span><br><span class="hljs-string">        &lt;/div&gt;</span><br><span class="hljs-string">      &lt;/div&gt;</span><br><span class="hljs-string">    `</span>;<br>  &#125;<br>  html += <span class="hljs-string">&#x27;&lt;/div&gt;&#x27;</span>;<br>  <span class="hljs-keyword">return</span> html;<br>&#125;<br><br><span class="hljs-comment">// 辅助函数：十六进制转RGB</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">hexToRgb</span>(<span class="hljs-params">hex</span>) &#123;<br>  hex = hex.<span class="hljs-title function_">replace</span>(<span class="hljs-string">&#x27;#&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>);<br>  <span class="hljs-keyword">if</span> (hex.<span class="hljs-property">length</span> === <span class="hljs-number">3</span>) &#123;<br>    hex = hex[<span class="hljs-number">0</span>] + hex[<span class="hljs-number">0</span>] + hex[<span class="hljs-number">1</span>] + hex[<span class="hljs-number">1</span>] + hex[<span class="hljs-number">2</span>] + hex[<span class="hljs-number">2</span>];<br>  &#125;<br>  <span class="hljs-keyword">const</span> r = <span class="hljs-built_in">parseInt</span>(hex.<span class="hljs-title function_">substring</span>(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>), <span class="hljs-number">16</span>);<br>  <span class="hljs-keyword">const</span> g = <span class="hljs-built_in">parseInt</span>(hex.<span class="hljs-title function_">substring</span>(<span class="hljs-number">2</span>, <span class="hljs-number">4</span>), <span class="hljs-number">16</span>);<br>  <span class="hljs-keyword">const</span> b = <span class="hljs-built_in">parseInt</span>(hex.<span class="hljs-title function_">substring</span>(<span class="hljs-number">4</span>, <span class="hljs-number">6</span>), <span class="hljs-number">16</span>);<br>  <span class="hljs-keyword">return</span> [r, g, b];<br>&#125;<br><br><span class="hljs-comment">// 辅助函数：HTML转义</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">escapeHtml</span>(<span class="hljs-params">str</span>) &#123;<br>  <span class="hljs-keyword">if</span> (!str) <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;&#x27;</span>;<br>  <span class="hljs-keyword">return</span> str.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/[&amp;&lt;&gt;]/g</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">m</span>) &#123;<br>    <span class="hljs-keyword">if</span> (m === <span class="hljs-string">&#x27;&amp;&#x27;</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;&amp;amp;&#x27;</span>;<br>    <span class="hljs-keyword">if</span> (m === <span class="hljs-string">&#x27;&lt;&#x27;</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;&amp;lt;&#x27;</span>;<br>    <span class="hljs-keyword">if</span> (m === <span class="hljs-string">&#x27;&gt;&#x27;</span>) <span class="hljs-keyword">return</span> <span class="hljs-string">&#x27;&amp;gt;&#x27;</span>;<br>    <span class="hljs-keyword">return</span> m;<br>  &#125;);<br>&#125;<br></code></pre></td></tr></table></figure><ol start="4"><li>编写卡片样式</li></ol><p>在 source/css/ 目录下创建：</p><p><strong>column-cards.css</strong></p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 专栏卡片容器 */</span><br><span class="hljs-selector-class">.columns-container</span> &#123;<br>  <span class="hljs-attribute">display</span>: grid;<br>  <span class="hljs-attribute">gap</span>: <span class="hljs-number">1.8rem</span>;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">2rem</span> <span class="hljs-number">0</span>;<br>&#125;<br><br><span class="hljs-comment">/* 单个卡片 */</span><br><span class="hljs-selector-class">.column-card</span> &#123;<br>  <span class="hljs-attr">--column-color</span>: <span class="hljs-number">#1890ff</span>;<br>  <span class="hljs-attr">--column-color-rgb</span>: <span class="hljs-number">24</span>, <span class="hljs-number">144</span>, <span class="hljs-number">255</span>;<br>  <span class="hljs-attr">--hover-color</span>: <span class="hljs-number">#40a9ff</span>;<br><br>  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1.5rem</span>;<br>  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">12px</span>;<br>  <span class="hljs-attribute">border-left</span>: <span class="hljs-number">4px</span> solid <span class="hljs-built_in">var</span>(--column-color);<br>  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">linear-gradient</span>(<span class="hljs-number">135deg</span>, <span class="hljs-built_in">rgba</span>(<span class="hljs-built_in">var</span>(--column-color-rgb), <span class="hljs-number">0.05</span>), <span class="hljs-built_in">rgba</span>(<span class="hljs-built_in">var</span>(--column-color-rgb), <span class="hljs-number">0.01</span>));<br>  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">12px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.05</span>);<br>  <span class="hljs-attribute">transition</span>: all <span class="hljs-number">0.3s</span> ease;<br>&#125;<br><br><span class="hljs-selector-class">.column-card</span><span class="hljs-selector-pseudo">:hover</span> &#123;<br>  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateY</span>(-<span class="hljs-number">3px</span>);<br>  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">8px</span> <span class="hljs-number">20px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.1</span>);<br>  <span class="hljs-attribute">border-left-color</span>: <span class="hljs-built_in">var</span>(--hover-color);<br>&#125;<br><br><span class="hljs-selector-class">.card-header</span> &#123;<br>  <span class="hljs-attribute">display</span>: flex;<br>  <span class="hljs-attribute">align-items</span>: center;<br>  <span class="hljs-attribute">gap</span>: <span class="hljs-number">1rem</span>;<br>  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0.8rem</span>;<br>&#125;<br><br><span class="hljs-selector-class">.card-header</span> <span class="hljs-selector-tag">i</span> &#123;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2rem</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-color);<br>&#125;<br><br><span class="hljs-selector-class">.card-header</span> <span class="hljs-selector-tag">h3</span> &#123;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.4rem</span>;<br>  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">600</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-color);<br>&#125;<br><br><span class="hljs-selector-class">.subtitle</span> &#123;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">0.9rem</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-number">#666</span>;<br>  <span class="hljs-attribute">font-style</span>: italic;<br>&#125;<br><br><span class="hljs-selector-class">.card-content</span> <span class="hljs-selector-tag">p</span> &#123;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.6</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-number">#333</span>;<br>&#125;<br><br><span class="hljs-comment">/* 响应式 */</span><br><span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width</span>: <span class="hljs-number">768px</span>) &#123;<br>  <span class="hljs-selector-class">.columns-container</span> &#123;<br>    <span class="hljs-attribute">gap</span>: <span class="hljs-number">1rem</span>;<br>  &#125;<br>  <span class="hljs-selector-class">.card-header</span> &#123;<br>    <span class="hljs-attribute">flex-wrap</span>: wrap;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure><ol start="5"><li>安装依赖</li></ol><p>脚本中使用了 js-yaml 解析 YAML 文件，需要安装：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm install js-yaml --save<br></code></pre></td></tr></table></figure><p>如果你不想增加依赖，可以将数据文件改为 JSON 格式（column_descriptions.json），然后用 JSON.parse 读取。</p><ol start="6"><li>测试</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">hexo clean &amp;&amp; hexo generate<br></code></pre></td></tr></table></figure><p>打开 public/categories/index.html，检查：</p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs routeros">· &lt;head&gt; 中是否包含 &lt;link <span class="hljs-attribute">rel</span>=<span class="hljs-string">&quot;stylesheet&quot;</span> <span class="hljs-attribute">href</span>=<span class="hljs-string">&quot;/css/column-cards.css&quot;</span>&gt;<br>· &lt;div <span class="hljs-attribute">class</span>=<span class="hljs-string">&quot;category-list&quot;</span>&gt; 之前是否存在 .columns-container 结构<br></code></pre></td></tr></table></figure><p>启动本地服务器 hexo server，访问分类页查看效果。</p><p>三、总结</p><p>通过 after_render:html 过滤器，实现了对 Hexo 主题的完全无侵入式修改：</p><p>这种思路不仅适用于 Fluid 主题，也可以推广到任何 Hexo 主题。</p><p>附：完整文件结构</p><figure class="highlight nix"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs nix">your-blog<span class="hljs-symbol">/</span><br>├── scripts<span class="hljs-symbol">/</span><br>│   └── categories-inject.js      <span class="hljs-comment"># 注入脚本</span><br>├── source<span class="hljs-symbol">/</span><br>│   ├── _data<span class="hljs-symbol">/</span><br>│   │   └── column_descriptions.yml   <span class="hljs-comment"># 专栏数据</span><br>│   └── css<span class="hljs-symbol">/</span><br>│       └── column-cards.css          <span class="hljs-comment"># 卡片样式</span><br>└── (其他Hexo文件)<br></code></pre></td></tr></table></figure><p>希望本文可以对你有所帮助</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/2da73f2a.html</id><link href="https://b.wihi.top/posts/2da73f2a.html"/><published>2026-04-04T12:43:48.000Z</published><summary>本文介绍如何使用注入法在Hexo-fluid的分类页中增加对分类的说明，之后即使主题更新也可以继续使用，如果布局样式无改变无需手动更新</summary><title>在Hexo-fluid的分类页中增加说明(2)--注入法</title><updated>2026-04-04T12:43:48.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="脚本" scheme="https://b.wihi.top/categories/%E8%84%9A%E6%9C%AC/"/><category term="脚本" scheme="https://b.wihi.top/tags/%E8%84%9A%E6%9C%AC/"/><content><![CDATA[<p><font size="4">通过Cloudflare Workers API部署项目</font></p><blockquote><p>在cloudflare部署Workers项目的项目的时候，有代码要改动，用那个网页控制台太过于卡顿，非常不方便。但是termux又不支持Wrangler所以考虑使用API</p></blockquote><h2 id="准备">准备</h2><h3 id="获得账号ID与API的Token：">获得账号ID与API的Token：</h3><ol><li>Account ID：登录 Cloudflare Dashboard → 右侧边栏找到（或者进去某个域，然后下滑就可以看到账号ID了）</li><li>API Token：My Profile → API Tokens → Create Token（选择 Edit Cloudflare Workers 模板）</li></ol><p>如果实在找不到，可以参考我的这篇文章<a href="https://b.wihi.top/posts/e9532218.html">自动删除Cloudflare域名缓存脚本</a>中关于找到账号ID与生成API的Token的方法。</p><h3 id="找到你Works的名称以及相关绑定的名称">找到你Works的名称以及相关绑定的名称</h3><ol><li>获得完整的Workers名字如<code>xxx-xxx-xxx</code>或者你自己起的什么名字</li><li>如果绑定R2，获得存储桶完整名字</li><li>如果绑定KV，获得KV-ID（注意是ID不是名称）</li><li>如果还有其他绑定请查询官方文档</li></ol><h2 id="开始干活">开始干活</h2><p><strong>这里绑定只展示同时绑定R2和KV，其他绑定请自行查阅官方文档，当然如果你没任何绑定那么请忽略本提示</strong></p><h3 id="准备文件">准备文件</h3><p>在一个<strong>空目录</strong>里面，依次生成如下文件</p><p><strong>metadata.json</strong></p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs awk">&#123;<br>  <span class="hljs-string">&quot;main_module&quot;</span>: <span class="hljs-string">&quot;worker.js&quot;</span>, <span class="hljs-regexp">//</span>入口文件<br>  <span class="hljs-string">&quot;bindings&quot;</span>: [  <span class="hljs-regexp">//</span>配置的绑定，如果没有请设置写为空内容，如<span class="hljs-string">&quot;bindings&quot;</span>: []<br>    &#123;<br>      <span class="hljs-string">&quot;type&quot;</span>: <span class="hljs-string">&quot;kv_namespace&quot;</span>,<br>      <span class="hljs-string">&quot;name&quot;</span>: <span class="hljs-string">&quot;绑定后变量名&quot;</span>,<br>      <span class="hljs-string">&quot;namespace_id&quot;</span>: <span class="hljs-string">&quot;你的KVID&quot;</span><br>    &#125;,<br>    &#123;<br>      <span class="hljs-string">&quot;type&quot;</span>: <span class="hljs-string">&quot;r2_bucket&quot;</span>,<br>      <span class="hljs-string">&quot;name&quot;</span>: <span class="hljs-string">&quot;绑定后变量名&quot;</span>,<br>      <span class="hljs-string">&quot;bucket_name&quot;</span>: <span class="hljs-string">&quot;你的R2存储桶名&quot;</span><br>    &#125;<br>  ]<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>push.sh</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-meta">#!/bin/bash</span><br><span class="hljs-built_in">export</span> CF_ACCOUNT_ID=<span class="hljs-string">&quot;你的ID&quot;</span><br><span class="hljs-built_in">export</span> CF_API_TOKEN=<span class="hljs-string">&quot;你的Token&quot;</span><br>WORKER_NAME=<span class="hljs-string">&quot;你的Worker名字&quot;</span><br>ENTRY_FILE=<span class="hljs-string">&quot;worker.js&quot;</span><br><br><span class="hljs-comment"># 部署</span><br>curl -X PUT <span class="hljs-string">&quot;https://api.cloudflare.com/client/v4/accounts/<span class="hljs-variable">$CF_ACCOUNT_ID</span>/workers/scripts/<span class="hljs-variable">$WORKER_NAME</span>&quot;</span> \<br>  -H <span class="hljs-string">&quot;Authorization: Bearer <span class="hljs-variable">$CF_API_TOKEN</span>&quot;</span> \<br>  -F <span class="hljs-string">&quot;metadata=@metadata.json;type=application/json&quot;</span> \<br>  -F <span class="hljs-string">&quot;<span class="hljs-variable">$ENTRY_FILE</span>=@./<span class="hljs-variable">$ENTRY_FILE</span>;type=application/javascript+module&quot;</span><br></code></pre></td></tr></table></figure><p><strong>worker.js</strong></p><figure class="highlight 1c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs 1c"><span class="hljs-comment">//遵循ES模块规范（EMS格式）的程序</span><br></code></pre></td></tr></table></figure><h3 id="执行">执行</h3><p>在终端<code>cd</code>进入你放置刚刚那些文件的目录，输入如下内容</p><figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arcade">bash <span class="hljs-built_in">push</span>.sh<br></code></pre></td></tr></table></figure><p>等待执行即可，如果成功将会返回类似于如下内容</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;result&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>    <span class="hljs-attr">&quot;created_on&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2026-03-15T01:45:23.343582Z&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;modified_on&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;2026-03-28T23:39:57.342352Z&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;id&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;xxx&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;tag&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;xxx&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;entry_point&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;worker.js&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;tags&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">null</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;deployment_id&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;xxx&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;tail_consumers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">null</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;logpush&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;has_assets&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;has_modules&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;etag&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;xxx&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;handlers&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><br>      <span class="hljs-string">&quot;fetch&quot;</span><br>    <span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;last_deployed_from&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;api&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;usage_model&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;standard&quot;</span><span class="hljs-punctuation">,</span><br>    <span class="hljs-attr">&quot;startup_time_ms&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0</span><br>  <span class="hljs-punctuation">&#125;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;success&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;errors&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;messages&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><span class="hljs-punctuation">]</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p>如果失败请自行根据提示排查问题</p><h2 id="结束语">结束语</h2><p>希望这些内容可以帮到你，理论上这些文件名都可以修改，但是修改后注意与变量的修改</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/6ea50ca0.html</id><link href="https://b.wihi.top/posts/6ea50ca0.html"/><published>2026-04-04T11:05:21.000Z</published><summary>本文提供了使用Cloudflare Workers API部署Workers项目的方案，适用于不想在网页部署项目，或者不想/无法使用Wrangler的情况</summary><title>通过Cloudflare Workers API部署项目</title><updated>2026-04-04T11:05:21.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Teach手记" scheme="https://b.wihi.top/categories/Teach%E6%89%8B%E8%AE%B0/"/><category term="Teach手记" scheme="https://b.wihi.top/tags/Teach%E6%89%8B%E8%AE%B0/"/><content><![CDATA[<p><font size="4">NoMachine客户端 不断创建tray monitor进程解决办法</font></p><blockquote><p>原因：在使用NoMachine连接香橙派远程客户端的过程中，发现电脑越来越卡顿，打开进程管理器发现，其不断创建了大量tray monitor进程从而占用大量资源导致电脑卡顿。</p></blockquote><p><img src="https://img.wihi.top/posts/5330f002030bace0c4e119f67009e7b0.png" alt="tray monitor大量占用进程" title="tray monitor大量占用进程"></p><p>去NoMahine官网查询找到了解决方案：<a href="https://kb.nomachine.com/TR05W11320?s=tray+monitor">NoMachine Tray Monitor processes open constantly on Windows  （UTF-16 unicode）<br></a> 这里进行记录</p><h2 id="解决方案">解决方案</h2><p>根据NoMachine官方提供的解决方案是<strong>启用系统的“Beta: 使用 Unicode UTF-8 提供全球语言支持”功能。</strong></p><p>详细步骤如下：</p><ol><li>打开控制面板<br>· 在开始菜单中搜索并打开 “控制面板”。</li><li>进入区域设置<br>· 在控制面板中，找到并点击 “时钟和区域”。<br>· 然后点击 “区域”。</li><li>进入管理选项<br>· 在弹出的“区域”窗口中，切换到 “管理” 选项卡。<br>· 点击 “更改系统区域设置…” 按钮。<br>· 注意：你可能需要提供管理员权限或确认 UAC 提示。</li><li>启用 UTF-8 支持<br>· 在“区域设置”窗口中，找到底部的复选框：<br>“Beta 版：使用 Unicode UTF-8 提供全球语言支持”。<br>· 勾选 此复选框。<br>· 点击 “确定”。</li><li>重启计算机<br>· 系统会提示你需要 重启计算机 以使更改生效。重启后即可生效</li></ol><p>我认为该解决方案的思路是：软件可能不兼容utf-16的环境，导致tray monitor进程无法完成初始化从而不断创建进程，而更改为utf-8环境后，使得初始化可以正常完成。</p><p><strong>注意：如此更改可能会导致系统内一些非常老旧的不支持Unicode的程序出现问题</strong></p><p><em>吐槽：根据官方回应，预计在8.x版本修复，可是我使用的是9.x版本，迄今为止仍然出现该问题</em></p><p>另：在寻找解决方案过程中发现也有人遇到了这个问题，发现删除了不断创建该进程的bin文件也可以解决不断创建进程问题，并且远程功能不受影响。我不太清楚其中原理，如果你的系统因为某些原因不支持切换utf-8环境或许可以试试。</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/4f461c7a.html</id><link href="https://b.wihi.top/posts/4f461c7a.html"/><published>2026-01-17T04:00:00.000Z</published><summary>记录解决在windows10系统下，NoMachine客户端启动后不断创建进程占用系统资源，使得电脑卡顿死机的问题。解决方案为启用系统的使用 Unicode UTF-8 提供全球语言支持功能</summary><title>NoMachine客户端 不断创建tray monitor进程解决办法</title><updated>2026-01-17T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="碎碎念" scheme="https://b.wihi.top/categories/%E7%A2%8E%E7%A2%8E%E5%BF%B5/"/><category term="碎碎念" scheme="https://b.wihi.top/tags/%E7%A2%8E%E7%A2%8E%E5%BF%B5/"/><content><![CDATA[<p><font size="4">辞旧迎新：再见2025，你好2026</font></p><p>  2026的钟声准时响起，清脆嘹亮。标志着2025的结束与2026年的开始。在这里，我将要总结2025年的收获，发出对2026年的展望。<br>  2025年，迎来了人生中多个第一次：人生中第一次具有重要意义的考试；启动了人生中第一块开发板；点亮了人生中第一个由自己控制的灯带...那一个个或忐忑，或迷茫，或激动的瞬间，一个个难忘、自豪的瞬间，记忆犹新。它们既是成长的里程碑，也是人生之路上的重要转折点，使我成长，使我得到了新的收获。<br>  2025年，我收获颇丰，可能因为一次失去，因为对于未来的期待，亦或是青春期带来的独立思考，使我渐渐对未来，对自己，有了更为深入的思考。因为长期不断对未知的探索，使我的技术不断深入与提高，即使提高的是那样微不足道。下面，我将进一步表达我对未来与自己的思考。<br>  人，一撇一捺。只有那么长，只有那么大，每个都长的一样，没有什么特别。意义，取决于书写一撇一捺时的力度、锋度。一生中可活的时间只有那么多，之后便会化作灰烬，随风飘散。意义，可能就显得有些耀眼，可仅仅如此罢了，也没有什么再过人之处了，只是对自己有了一个交代罢了。我通过不断的思考，我想明白了一点，我追求的意义是有善意的创造，写个程序实现我的想法，设计个网页，让它看起来很酷，从中得来的及时反馈，使我欢呼雀跃，但是那总是不太够。于是我对未来有了一个具体而明确未来目标，去获得更好的资源，做更优秀，更有善意的创造。考大学，考中我想去的专业。为什么我要强调有善意呢，善意代表着温度，可以温暖他人与自我，服务于人。2025年里，我立下了对于未来明确的目标，这是最大的收获。<br>  2025年我对人的社会也有些思考，众人，多个人组成了一个社会，每个人的书写方式都不完全相同，每个人都独一无二，都有力度，锋度。在城市间穿梭的穿着外卖员制服的人；在每个晨光微露的时刻便开始做早餐的人；坐在办公室盯着电子屏幕的人。都是鲜活而平等的生命，在人格上无高下之分。如果用收入差距去衡量一个人，等同于用尺子衡量风的长度，滑稽且无任何意义。我想要强调的是，在这片土地，尤其是我们所提倡的价值观中，人人本就平等。怎么活，怎么想，取决于自己，不要尝试做一些愚蠢的事情，去做一些滑稽而毫无意义的比量。<br>  对于人生的意义，每个人都不相同，或许有些人没找到，但那并不意味着失去了什么，反而那也是一种意义。但请不要过于功利，陷入对单一目标的盲目追求。因为那很可能是一个无底的深渊，恳请在追逐岸的同时，仰起头，看看那一颗颗繁星，宇宙浩瀚而博大，繁星或许也是个不错的选择。在当今这个充满功利的社会中，请不要忘记，人生的意义不至于此，不要被一叶所障目。<br>  2025年，我点亮了人生中第一块灯带——WS2812B，通过编写驱动ESP32的程序代码，指挥ESP32操控它。这个项目，对我而言意味着打通了从虚拟世界到物理世界的通路，让我更为深刻的感受到了创造的快乐与价值。因此，我欢呼雀跃，难以忘却。标志着我的技术路进入了一个新的阶段。<br>  2026年，像一张白纸，充满希望与未知，每一个符号，每一个笔迹，都取决于脚下的行动。在今年，我将要在如下几个方面进行重点深入发展。</p><ul><li><p>1.知识体系上：针对数学知识进行深入学习，深入了解数学原理，具体知识内容从高中课本到其所对应的应用数学相关内容。深入强化人文素养，提升人文关怀能力，写作能力。加强英语学习，使高中学业英语成绩保持优秀。</p></li><li><p>2.技术能力上：系统学习并且掌握Python，以及其相关常用模块与的使用，独立完成构建个人编程工具库。入门习TML/CSS/JavaScript开发。落实Linux熟练操作系统与基本了解系统学习计算机系统工作详细机制。</p></li><li><p>3.在个人方面，坚持锻炼与规律作息，进一步深化对未来的发展目标与行动路线，为高考做准备，努力争取获得优秀社会跳板资格。</p></li></ul><p>  辞旧迎新，2025再见，我收获颇丰。你好2026，我已准备就绪！</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/feaf11ab.html</id><link href="https://b.wihi.top/posts/feaf11ab.html"/><published>2026-01-01T13:02:00.000Z</published><summary>Carrazll对于2025年的收获与总结，包含有对2025人生思考与成果总结。对于2026年新的展望与未来目标，2026元旦辞旧迎新。</summary><title>辞旧迎新：再见2025，你好2026</title><updated>2026-01-01T13:02:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="学习笔记" scheme="https://b.wihi.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/><category term="数学" scheme="https://b.wihi.top/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/%E6%95%B0%E5%AD%A6/"/><category term="二进制" scheme="https://b.wihi.top/tags/%E4%BA%8C%E8%BF%9B%E5%88%B6/"/><content><![CDATA[<p><font size="4">二进制学习笔记</font></p><h2 id="引言">引言</h2><p>二进制是数学的计数法之一,由0与1组成是其基本特征.由于计算机的<strong>逻辑门</strong>工作方式故该计数法多用于计算机领域,学习二进制,有助于理解字符在计算机中的识别以及存储等</p><h2 id="定义">定义</h2><p>其基本定义为: 满2进1</p><p>由0,1组成</p><p>基数为2</p><ul><li><p><strong>10转2：</strong><br>$$N_{10} \rightarrow \text{除2取余，逆序排列} \rightarrow (d_{k-1}...d_0)_2$$</p></li><li><p><strong>2转10：</strong><br>将二进制数的每一位乘以其对应的位权（$2^n$），然后将所有乘积相加。<br>$$N_{10} = d_{n-1} \times 2^{,n-1} + \cdots + d_1 \times 2^{,1} + d_0 \times 2^{,0}$$</p></li></ul><h2 id="举例">举例</h2><p><strong>示例：将 29 转换为二进制</strong></p><table><thead><tr><th style="text-align:left">计算步骤</th><th style="text-align:center">商</th><th style="text-align:center">余数</th><th style="text-align:left">说明</th></tr></thead><tbody><tr><td style="text-align:left">29 ÷ 2</td><td style="text-align:center">14</td><td style="text-align:center"><strong>1</strong></td><td style="text-align:left">(最低位)</td></tr><tr><td style="text-align:left">14 ÷ 2</td><td style="text-align:center">7</td><td style="text-align:center"><strong>0</strong></td><td style="text-align:left"></td></tr><tr><td style="text-align:left">7 ÷ 2</td><td style="text-align:center">3</td><td style="text-align:center"><strong>1</strong></td><td style="text-align:left"></td></tr><tr><td style="text-align:left">3 ÷ 2</td><td style="text-align:center">1</td><td style="text-align:center"><strong>1</strong></td><td style="text-align:left"></td></tr><tr><td style="text-align:left">1 ÷ 2</td><td style="text-align:center">0</td><td style="text-align:center"><strong>1</strong></td><td style="text-align:left">(最高位)</td></tr></tbody></table><p><strong>逆序排列余数</strong>（从下往上读）：<strong>11101</strong></p><hr><p><strong>示例：将 1101 转换为十进制</strong></p><table><thead><tr><th style="text-align:left">二进制位</th><th style="text-align:center">1</th><th style="text-align:center">1</th><th style="text-align:center">0</th><th style="text-align:center">1</th></tr></thead><tbody><tr><td style="text-align:left"><strong>位权 (2^n)</strong></td><td style="text-align:center"><strong>2³ = 8</strong></td><td style="text-align:center"><strong>2² = 4</strong></td><td style="text-align:center"><strong>2¹ = 2</strong></td><td style="text-align:center"><strong>2⁰ = 1</strong></td></tr><tr><td style="text-align:left"><strong>计算 (位 × 位权)</strong></td><td style="text-align:center">1 × 8 = 8</td><td style="text-align:center">1 × 4 = 4</td><td style="text-align:center">0 × 2 = 0</td><td style="text-align:center">1 × 1 = 1</td></tr></tbody></table><p><strong>求和</strong>：8 + 4 + 0 + 1 = <strong>13</strong></p><h2 id="在计算机中应用">在计算机中应用</h2><p>一个0或1称为1bit,计算机中以8bit为1byte</p><p>二进制标识符0b</p><h2 id="补充：">补充：</h2><p>2进制多转换为16进制，因为$2^4 =16$，其中二进制与16进制可以相互转换，故计算机中多用16进制表示，例如内存地址中就用16进制标记位置</p><p>十六进制与二进制同理，0-9A-F表示10进制的0-15，A-F表示10-15</p><p>16进制标志符：0x</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/ba7e9a6a.html</id><link href="https://b.wihi.top/posts/ba7e9a6a.html"/><published>2025-11-16T04:00:00.000Z</published><summary>学习二进制基础知识，理解二进制的定义、与十进制的转换方法（含公式与实例），并了解其在计算机中的应用原理。</summary><title>二进制学习笔记</title><updated>2025-11-16T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="开发板" scheme="https://b.wihi.top/categories/%E5%BC%80%E5%8F%91%E6%9D%BF/"/><category term="ESP32" scheme="https://b.wihi.top/categories/%E5%BC%80%E5%8F%91%E6%9D%BF/ESP32/"/><category term="ESP32" scheme="https://b.wihi.top/tags/ESP32/"/><category term="WS2812B" scheme="https://b.wihi.top/tags/WS2812B/"/><content><![CDATA[<p><font size="4">WS2812B灯带项目</font></p><blockquote><p>刷B站偶然间看到了用电脑控制WS2812B显示各种图案，对此非常感兴趣，于是通过查资料，AI等实现了本项目，项目化驱动学习。</p></blockquote><h2 id="项目概述">项目概述</h2><p>本项目基于ESP32的实现智能WS2812B RGB灯带控制，主要是通过该项目学习电路，单片机等相关知识</p><p>设计思路分析</p><ol><li>硬件架构设计思路</li></ol><p>安全第一的设计理念</p><p>· 采用电平转换器解决3.3V ESP32与5V WS2812B的通信兼容性问题<br>· 通过220Ω电阻保护数据信号线，防止电流冲击<br>· 严格的共地(GND)设计，确保信号稳定性<br>· 外部独立供电方案，避免USB供电不足和潜在风险</p><p>模块化连接策略</p><p>· 电源模块：5V5A外部电源 → 定制线 → 灯带供电<br>· 控制模块：ESP32 → 电平转换 → 灯带数据控制<br>· 信号调理：串联电阻优化信号质量<br>· 灵活扩展：面包板设计便于调试和扩展</p><ol start="2"><li>软件架构设计思路</li></ol><p>分层式程序设计</p><p>· 底层驱动层：FastLED库提供硬件抽象<br>· 核心逻辑层：模式管理和动画算法<br>· 用户交互层：串口命令解析和反馈<br>· 效果展示层：多种预设灯光模式</p><p>状态机设计模式</p><p>· 定义8种独立灯光模式，每种模式有专属的状态管理<br>· 统一的模式切换接口，支持热切换<br>· 参数持久化设计，保持用户设置</p><h2 id="材料准备">材料准备</h2><ol><li><p>WS2812B灯带1条(30灯珠,品牌:btf lighting)</p></li><li><p>ESP32(WROOM-32E,品牌:源地工作室)</p></li><li><p>三种杜邦线若干(共对共,母对母,共对母)</p></li><li><p>面包板</p></li><li><p>3.3v  5v电平逻辑转换器</p></li><li><p>5V5A DC电源(内正外负)</p></li><li><p>特殊定制线(一端DC插座,内正外负,一端分为两正负:裸线正负+杜邦公头正负)</p></li><li><p>快速接线端子</p></li><li><p>220R电阻x1</p></li><li><p>一根USB-A to USB-C 数据线</p></li></ol><h2 id="电路连接">电路连接</h2><p>电路连接遵循 <strong>共地(GND)</strong> 原则,并且注意单片机供电<strong>不得</strong>同时接入多个外部电源输入,否则极有可能<strong>烧毁电脑主板</strong>，并且在没有连接好的情况下，<strong>绝对不可</strong>以接电源，否则可能触电！</p><pre><code class=" mermaid">graph TD    A[开始连接WS2812电路] --&gt; B[材料准备]    B --&gt; C[电源部分连接]    B --&gt; D[面包板线路布置]    B --&gt; E[信号线路连接]    C --&gt; C1[5V5A DC电源]    C1 --&gt; C2[连接定制线&lt;br&gt;DC插座端]    C2 --&gt; C3[定制线裸线端&lt;br&gt;通过快速接线端子&lt;br&gt;连接灯带电源正负]    D --&gt; D1[定制线杜邦头&lt;br&gt;连接面包板正负轨道]    D1 --&gt; D2[正轨道引线到&lt;br&gt;逻辑转换器HV VCC]    D1 --&gt; D3[负轨道三根线分别连接:]    D3 --&gt; D4[ESP32GND]    D3 --&gt; D5[逻辑转换器LV GND]    D3 --&gt; D6[逻辑转换器HV GND]    E --&gt; E1[ESP32 GPIO4&lt;br&gt;连接逻辑转换器A1通道]    E1 --&gt; E2[逻辑转换器B1通道&lt;br&gt;串联220R电阻]    E2 --&gt; E3[连接到灯带数据端&lt;br&gt;3pin中间引脚]    E --&gt; E4[ESP32 USB连接电脑&lt;br&gt;供电和数据通讯]    E4 --&gt; E5[ESP32 3.3V输出&lt;br&gt;连接逻辑转换器LV VCC]    C3 --&gt; F[电路连接完成]    E3 --&gt; F    E5 --&gt; F    F --&gt; G[开始编程控制]    %% 样式定义    classDef power fill:#f9f,stroke:#333,stroke-width:2px;    classDef logic fill:#ccf,stroke:#333,stroke-width:2px;    classDef signal fill:#9f9,stroke:#333,stroke-width:2px;    classDef complete fill:#ff9,stroke:#333,stroke-width:3px;    class C1,C2,C3 power;    class D2,D5,D6,E5 logic;    class E1,E2,E3 signal;    class F complete;</code></pre><h3 id="补充">补充</h3><p>如果你考虑不接电脑,那么可以 <strong>拔掉</strong>USB与电脑相接的线后,然后在从电源轨道引出一根公对母杜邦线和ESP32的5V的GPIO相连接.</p><h2 id="程序烧录">程序烧录</h2><h3 id="烧录方法">烧录方法</h3><p>我采用Arduino IDE进行本项目程序编写与烧录</p><ol><li><p>去Arduino IDE官网下载最新的IDE</p></li><li><p>在File-preference中下滑找到语言选项，选择中文（据说此功能仅限2.x版本）</p></li><li><p>在文件-首选项中下滑在下面的项目链接，添加：</p></li></ol><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">https:<span class="hljs-regexp">//</span>jihulab.com<span class="hljs-regexp">/esp-mirror/</span>espressif<span class="hljs-regexp">/arduino-esp32/</span>-<span class="hljs-regexp">/raw/g</span>h-pages/package_esp32_index_cn.json<br></code></pre></td></tr></table></figure><p>这个链接是乐鑫官方文档中提供的镜像版本，更多内容可以<a href="https://docs.espressif.com/projects/arduino-esp32/en/latest/installing.html">参考文档</a>，切换该文档可以有效解决安装工具链和库的时候无法访问github无法安装的问题。</p><ol start="4"><li><p>在工具-开发板-开发板管理器顶部输入esp32，找到由 Espressif Systems 提供的 ESP32 项目。建议安装最新版，如果你用的上面的链接，可能还会有-cn版本，建议安装此版本。</p></li><li><p>选择开发板：点击 工具 (Tools) &gt; 开发板 (Board)。在弹出的列表中，找到 ESP32 Arduino 分类。这里有很多具体的型号。如果您不确定，一个通用且安全的选择是 ESP32 Dev Module。</p></li><li><p>选择端口：将您的 ESP32 通过 USB 线连接到电脑。点击 工具 (Tools) &gt; 端口 (Port)。选择一个新出现的端口。在 Windows 上通常是 COMx（如 COM3），在 Mac 上是 /dev/cu.usbmodem...。</p></li></ol><p>7.然后写入你的代码，然后点击验证，如果编译通过了，然后再点上传即可。（首次编译可能较慢）</p><ol start="8"><li>然后重新上电或者摁复位键，ESP32就会开始工作，你的灯带就会亮起来～哦耶</li></ol><h3 id="代码分享：">代码分享：</h3><p>针对30个灯珠并使用GPIO4，WS2812控制代码。这个代码包含多种灯光模式，可以通过串口命令切换。</p><p>硬件连接</p><p>WS2812 灯带 ESP32 开发板<br>VCC (5V) 5V 引脚<br>GND GND 引脚<br>DIN (数据线) GPIO 4</p><p>完整代码</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br></pre></td><td class="code"><pre><code class="hljs cpp"><span class="hljs-meta">#<span class="hljs-keyword">include</span> <span class="hljs-string">&lt;FastLED.h&gt;</span></span><br><br><span class="hljs-comment">// LED配置</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> LED_PIN     4     <span class="hljs-comment">// 数据线连接到GPIO4</span></span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> NUM_LEDS    30    <span class="hljs-comment">// 30个灯珠</span></span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> BRIGHTNESS 100    <span class="hljs-comment">// 初始亮度 (0-255)</span></span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> LED_TYPE    WS2812</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> COLOR_ORDER GRB   <span class="hljs-comment">// WS2812的颜色顺序</span></span><br><br><span class="hljs-comment">// 定义LED数组</span><br>CRGB leds[NUM_LEDS];<br><br><span class="hljs-comment">// 模式定义</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_RAINBOW    0</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_THEATER    1</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_CONFETTI   2</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_SOLID      3</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_BREATH     4</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_RAIN       5</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_FIRE       6</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> MODE_COMET      7</span><br><span class="hljs-meta">#<span class="hljs-keyword">define</span> NUM_MODES       8</span><br><br><span class="hljs-comment">// 全局变量</span><br><span class="hljs-type">uint8_t</span> currentMode = MODE_RAINBOW;<br><span class="hljs-type">uint8_t</span> gHue = <span class="hljs-number">0</span>; <span class="hljs-comment">// 彩虹色调</span><br><span class="hljs-type">uint8_t</span> currentBrightness = BRIGHTNESS;<br>CRGB solidColor = CRGB::Blue; <span class="hljs-comment">// 纯色模式的默认颜色</span><br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">setup</span><span class="hljs-params">()</span> </span>&#123;<br>  Serial.<span class="hljs-built_in">begin</span>(<span class="hljs-number">115200</span>);<br>  <span class="hljs-built_in">delay</span>(<span class="hljs-number">1000</span>); <span class="hljs-comment">// 等待串口初始化</span><br>  <br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;=== ESP32 WS2812 控制器 ===&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;连接信息:&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;- GPIO: 4&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;- 灯珠数量: 30&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;- 当前模式: 彩虹&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>();<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;串口命令:&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;0-7: 切换模式 (0=彩虹, 1=跑马灯, 2=五彩纸屑, 3=纯色, 4=呼吸, 5=下雨, 6=火焰, 7=彗星)&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;b100: 设置亮度为100&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;r/g/b: 纯色模式切换颜色&quot;</span>);<br>  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;----------------------------&quot;</span>);<br><br>  <span class="hljs-comment">// 初始化FastLED</span><br>  FastLED.<span class="hljs-built_in">addLeds</span>&lt;LED_TYPE, LED_PIN, COLOR_ORDER&gt;(leds, NUM_LEDS).<span class="hljs-built_in">setCorrection</span>(TypicalLEDStrip);<br>  FastLED.<span class="hljs-built_in">setBrightness</span>(currentBrightness);<br>  <br>  <span class="hljs-comment">// 初始显示一个启动动画</span><br>  <span class="hljs-built_in">startupAnimation</span>();<br>&#125;<br><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">loop</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-comment">// 检查串口命令</span><br>  <span class="hljs-built_in">checkSerialCommands</span>();<br>  <br>  <span class="hljs-comment">// 根据当前模式执行相应的动画</span><br>  <span class="hljs-keyword">switch</span>(currentMode) &#123;<br>    <span class="hljs-keyword">case</span> MODE_RAINBOW:<br>      <span class="hljs-built_in">rainbow</span>();<br>      <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_THEATER:<br>      <span class="hljs-built_in">theaterChase</span>();<br>      <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_CONFETTI:<br>      <span class="hljs-built_in">confetti</span>();<br>      <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_SOLID:<br>      <span class="hljs-built_in">solid</span>();<br>      <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_BREATH:<br>      <span class="hljs-built_in">breath</span>();<br>      <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_RAIN:<br>      <span class="hljs-built_in">rain</span>();<br>      <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_FIRE:<br>      <span class="hljs-built_in">fire</span>();<br>      <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_COMET:<br>      <span class="hljs-built_in">comet</span>();<br>      <span class="hljs-keyword">break</span>;<br>  &#125;<br>  <br>  FastLED.<span class="hljs-built_in">show</span>();<br>  <span class="hljs-comment">// 每种模式有自己的延时控制，这里不需要额外延时</span><br>&#125;<br><br><span class="hljs-comment">// === 模式函数 ===</span><br><br><span class="hljs-comment">// 彩虹模式</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">rainbow</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-built_in">fill_rainbow</span>(leds, NUM_LEDS, gHue, <span class="hljs-number">7</span>);<br>  <span class="hljs-built_in">EVERY_N_MILLISECONDS</span>(<span class="hljs-number">20</span>) &#123;<br>    gHue++;<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">// 跑马灯模式</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">theaterChase</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-type">static</span> <span class="hljs-type">uint8_t</span> j = <span class="hljs-number">0</span>;<br>  <br>  <span class="hljs-comment">// 将所有LED设置为暗</span><br>  <span class="hljs-built_in">fill_solid</span>(leds, NUM_LEDS, CRGB::Black);<br>  <br>  <span class="hljs-comment">// 每隔3个LED设置一个亮起的LED</span><br>  <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt; NUM_LEDS; i = i + <span class="hljs-number">3</span>) &#123;<br>    leds[(i + j) % NUM_LEDS] = <span class="hljs-built_in">CHSV</span>(gHue, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>);<br>  &#125;<br>  <br>  <span class="hljs-built_in">EVERY_N_MILLISECONDS</span>(<span class="hljs-number">100</span>) &#123;<br>    j = (j + <span class="hljs-number">1</span>) % <span class="hljs-number">3</span>;<br>    gHue++;<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">// 五彩纸屑模式</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">confetti</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-comment">// 淡出所有LED</span><br>  <span class="hljs-built_in">fadeToBlackBy</span>(leds, NUM_LEDS, <span class="hljs-number">10</span>);<br>  <br>  <span class="hljs-comment">// 随机位置添加彩色点</span><br>  <span class="hljs-type">int</span> pos = <span class="hljs-built_in">random16</span>(NUM_LEDS);<br>  leds[pos] += <span class="hljs-built_in">CHSV</span>(gHue + <span class="hljs-built_in">random8</span>(<span class="hljs-number">64</span>), <span class="hljs-number">200</span>, <span class="hljs-number">255</span>);<br>  <br>  <span class="hljs-built_in">EVERY_N_MILLISECONDS</span>(<span class="hljs-number">30</span>) &#123;<br>    gHue++;<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">// 纯色模式</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">solid</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-built_in">fill_solid</span>(leds, NUM_LEDS, solidColor);<br>&#125;<br><br><span class="hljs-comment">// 呼吸灯模式</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">breath</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-type">uint8_t</span> breath = (<span class="hljs-built_in">exp</span>(<span class="hljs-built_in">sin</span>(<span class="hljs-built_in">millis</span>() / <span class="hljs-number">2000.0</span> * PI)) - <span class="hljs-number">0.36787944</span>) * <span class="hljs-number">108.0</span>;<br>  <span class="hljs-built_in">fill_solid</span>(leds, NUM_LEDS, <span class="hljs-built_in">CHSV</span>(gHue, <span class="hljs-number">255</span>, breath));<br>  <br>  <span class="hljs-built_in">EVERY_N_SECONDS</span>(<span class="hljs-number">10</span>) &#123;<br>    gHue += <span class="hljs-number">32</span>;<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">// 下雨模式</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">rain</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-comment">// 所有LED向下移动并淡出</span><br>  <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt; NUM_LEDS - <span class="hljs-number">1</span>; i++) &#123;<br>    leds[i] = leds[i + <span class="hljs-number">1</span>];<br>    leds[i].<span class="hljs-built_in">fadeToBlackBy</span>(<span class="hljs-number">20</span>);<br>  &#125;<br>  <br>  <span class="hljs-comment">// 随机在顶部添加新的雨滴</span><br>  <span class="hljs-keyword">if</span>(<span class="hljs-built_in">random8</span>() &lt; <span class="hljs-number">50</span>) &#123;<br>    leds[NUM_LEDS - <span class="hljs-number">1</span>] = <span class="hljs-built_in">CHSV</span>(<span class="hljs-number">160</span>, <span class="hljs-number">200</span>, <span class="hljs-number">255</span>); <span class="hljs-comment">// 蓝色雨滴</span><br>  &#125; <span class="hljs-keyword">else</span> &#123;<br>    leds[NUM_LEDS - <span class="hljs-number">1</span>] = CRGB::Black;<br>  &#125;<br>  <br>  <span class="hljs-built_in">delay</span>(<span class="hljs-number">50</span>);<br>&#125;<br><br><span class="hljs-comment">// 火焰效果</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">fire</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-comment">// 热源在底部</span><br>  <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt; NUM_LEDS; i++) &#123;<br>    <span class="hljs-comment">// 温度从底部到顶部递减</span><br>    <span class="hljs-type">int</span> temperature = <span class="hljs-built_in">map</span>(i, <span class="hljs-number">0</span>, NUM_LEDS - <span class="hljs-number">1</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0</span>);<br>    temperature = <span class="hljs-built_in">qsub8</span>(temperature, <span class="hljs-built_in">random8</span>(<span class="hljs-number">0</span>, <span class="hljs-number">80</span>));<br>    <br>    <span class="hljs-comment">// 将温度转换为火焰颜色 (红-&gt;黄-&gt;白)</span><br>    <span class="hljs-keyword">if</span>(temperature &gt; <span class="hljs-number">200</span>) &#123;<br>      leds[i] = <span class="hljs-built_in">CRGB</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>); <span class="hljs-comment">// 白色核心</span><br>    &#125; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(temperature &gt; <span class="hljs-number">150</span>) &#123;<br>      leds[i] = <span class="hljs-built_in">CRGB</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0</span>);   <span class="hljs-comment">// 黄色</span><br>    &#125; <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(temperature &gt; <span class="hljs-number">100</span>) &#123;<br>      leds[i] = <span class="hljs-built_in">CRGB</span>(<span class="hljs-number">255</span>, <span class="hljs-number">100</span>, <span class="hljs-number">0</span>);   <span class="hljs-comment">// 橙色</span><br>    &#125; <span class="hljs-keyword">else</span> &#123;<br>      leds[i] = <span class="hljs-built_in">CRGB</span>(<span class="hljs-number">255</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);     <span class="hljs-comment">// 红色</span><br>    &#125;<br>    <br>    leds[i].<span class="hljs-built_in">nscale8_video</span>(temperature);<br>  &#125;<br>  <br>  <span class="hljs-comment">// 随机闪烁</span><br>  <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">3</span>; i++) &#123;<br>    <span class="hljs-type">int</span> flicker = <span class="hljs-built_in">random8</span>(NUM_LEDS / <span class="hljs-number">3</span>);<br>    leds[flicker] += <span class="hljs-built_in">CRGB</span>(<span class="hljs-number">50</span>, <span class="hljs-number">25</span>, <span class="hljs-number">0</span>);<br>  &#125;<br>  <br>  <span class="hljs-built_in">delay</span>(<span class="hljs-number">30</span>);<br>&#125;<br><br><span class="hljs-comment">// 彗星效果</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">comet</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-type">static</span> <span class="hljs-type">int</span> cometPosition = <span class="hljs-number">0</span>;<br>  <br>  <span class="hljs-comment">// 淡出所有LED</span><br>  <span class="hljs-built_in">fadeToBlackBy</span>(leds, NUM_LEDS, <span class="hljs-number">30</span>);<br>  <br>  <span class="hljs-comment">// 绘制彗星头部 (最亮)</span><br>  leds[cometPosition] = <span class="hljs-built_in">CHSV</span>(gHue, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>);<br>  <br>  <span class="hljs-comment">// 绘制彗星尾巴</span><br>  <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i = <span class="hljs-number">1</span>; i &lt; <span class="hljs-number">8</span>; i++) &#123;<br>    <span class="hljs-type">int</span> pos = cometPosition - i;<br>    <span class="hljs-keyword">if</span>(pos &gt;= <span class="hljs-number">0</span>) &#123;<br>      leds[pos] = <span class="hljs-built_in">CHSV</span>(gHue, <span class="hljs-number">255</span>, <span class="hljs-number">255</span> - (i * <span class="hljs-number">32</span>));<br>    &#125;<br>  &#125;<br>  <br>  <span class="hljs-built_in">EVERY_N_MILLISECONDS</span>(<span class="hljs-number">50</span>) &#123;<br>    cometPosition = (cometPosition + <span class="hljs-number">1</span>) % NUM_LEDS;<br>    <span class="hljs-keyword">if</span>(cometPosition == <span class="hljs-number">0</span>) &#123;<br>      gHue += <span class="hljs-number">32</span>; <span class="hljs-comment">// 每次循环完成改变颜色</span><br>    &#125;<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">// === 辅助函数 ===</span><br><br><span class="hljs-comment">// 启动动画</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">startupAnimation</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-comment">// 从中间向两边展开</span><br>  <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt;= NUM_LEDS / <span class="hljs-number">2</span>; i++) &#123;<br>    <span class="hljs-type">int</span> left = (NUM_LEDS / <span class="hljs-number">2</span>) - i;<br>    <span class="hljs-type">int</span> right = (NUM_LEDS / <span class="hljs-number">2</span>) + i;<br>    <br>    <span class="hljs-keyword">if</span>(left &gt;= <span class="hljs-number">0</span>) leds[left] = CRGB::Green;<br>    <span class="hljs-keyword">if</span>(right &lt; NUM_LEDS) leds[right] = CRGB::Green;<br>    <br>    FastLED.<span class="hljs-built_in">show</span>();<br>    <span class="hljs-built_in">delay</span>(<span class="hljs-number">30</span>);<br>  &#125;<br>  <br>  <span class="hljs-comment">// 彩虹扫描</span><br>  <span class="hljs-keyword">for</span>(<span class="hljs-type">int</span> i = <span class="hljs-number">0</span>; i &lt; NUM_LEDS; i++) &#123;<br>    leds[i] = <span class="hljs-built_in">CHSV</span>(i * <span class="hljs-number">8</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>);<br>    FastLED.<span class="hljs-built_in">show</span>();<br>    <span class="hljs-built_in">delay</span>(<span class="hljs-number">20</span>);<br>  &#125;<br>  <br>  <span class="hljs-comment">// 清空</span><br>  <span class="hljs-built_in">fill_solid</span>(leds, NUM_LEDS, CRGB::Black);<br>  FastLED.<span class="hljs-built_in">show</span>();<br>  <span class="hljs-built_in">delay</span>(<span class="hljs-number">500</span>);<br>&#125;<br><br><span class="hljs-comment">// 检查串口命令</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">checkSerialCommands</span><span class="hljs-params">()</span> </span>&#123;<br>  <span class="hljs-keyword">if</span>(Serial.<span class="hljs-built_in">available</span>() &gt; <span class="hljs-number">0</span>) &#123;<br>    String command = Serial.<span class="hljs-built_in">readString</span>();<br>    command.<span class="hljs-built_in">trim</span>();<br>    <br>    <span class="hljs-keyword">if</span>(command.<span class="hljs-built_in">length</span>() &gt; <span class="hljs-number">0</span>) &#123;<br>      <span class="hljs-type">char</span> cmd = command.<span class="hljs-built_in">charAt</span>(<span class="hljs-number">0</span>);<br>      <br>      <span class="hljs-comment">// 模式切换 (0-7)</span><br>      <span class="hljs-keyword">if</span>(cmd &gt;= <span class="hljs-string">&#x27;0&#x27;</span> &amp;&amp; cmd &lt;= <span class="hljs-string">&#x27;7&#x27;</span>) &#123;<br>        <span class="hljs-type">uint8_t</span> newMode = cmd - <span class="hljs-string">&#x27;0&#x27;</span>;<br>        <span class="hljs-keyword">if</span>(newMode != currentMode) &#123;<br>          currentMode = newMode;<br>          Serial.<span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;切换到模式: &quot;</span>);<br>          Serial.<span class="hljs-built_in">println</span>(newMode);<br>          <span class="hljs-built_in">printModeName</span>(newMode);<br>        &#125;<br>      &#125;<br>      <span class="hljs-comment">// 亮度设置 (b100)</span><br>      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(cmd == <span class="hljs-string">&#x27;b&#x27;</span> || cmd == <span class="hljs-string">&#x27;B&#x27;</span>) &#123;<br>        <span class="hljs-type">int</span> brightnessValue = command.<span class="hljs-built_in">substring</span>(<span class="hljs-number">1</span>).<span class="hljs-built_in">toInt</span>();<br>        <span class="hljs-keyword">if</span>(brightnessValue &gt;= <span class="hljs-number">0</span> &amp;&amp; brightnessValue &lt;= <span class="hljs-number">255</span>) &#123;<br>          currentBrightness = brightnessValue;<br>          FastLED.<span class="hljs-built_in">setBrightness</span>(currentBrightness);<br>          Serial.<span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;亮度设置为: &quot;</span>);<br>          Serial.<span class="hljs-built_in">println</span>(currentBrightness);<br>        &#125;<br>      &#125;<br>      <span class="hljs-comment">// 纯色模式颜色切换</span><br>      <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(currentMode == MODE_SOLID) &#123;<br>        <span class="hljs-keyword">switch</span>(cmd) &#123;<br>          <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;r&#x27;</span>: <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;R&#x27;</span>:<br>            solidColor = CRGB::Red;<br>            Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;颜色: 红色&quot;</span>);<br>            <span class="hljs-keyword">break</span>;<br>          <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;g&#x27;</span>: <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;G&#x27;</span>:<br>            solidColor = CRGB::Green;<br>            Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;颜色: 绿色&quot;</span>);<br>            <span class="hljs-keyword">break</span>;<br>          <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;b&#x27;</span>: <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;B&#x27;</span>:<br>            solidColor = CRGB::Blue;<br>            Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;颜色: 蓝色&quot;</span>);<br>            <span class="hljs-keyword">break</span>;<br>          <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;w&#x27;</span>: <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;W&#x27;</span>:<br>            solidColor = CRGB::White;<br>            Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;颜色: 白色&quot;</span>);<br>            <span class="hljs-keyword">break</span>;<br>          <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;y&#x27;</span>: <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;Y&#x27;</span>:<br>            solidColor = CRGB::Yellow;<br>            Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;颜色: 黄色&quot;</span>);<br>            <span class="hljs-keyword">break</span>;<br>          <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;p&#x27;</span>: <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;P&#x27;</span>:<br>            solidColor = CRGB::Purple;<br>            Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;颜色: 紫色&quot;</span>);<br>            <span class="hljs-keyword">break</span>;<br>        &#125;<br>      &#125;<br>    &#125;<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">// 打印模式名称</span><br><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">printModeName</span><span class="hljs-params">(<span class="hljs-type">uint8_t</span> mode)</span> </span>&#123;<br>  <span class="hljs-keyword">switch</span>(mode) &#123;<br>    <span class="hljs-keyword">case</span> MODE_RAINBOW:  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;彩虹循环&quot;</span>); <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_THEATER:  Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;跑马灯&quot;</span>); <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_CONFETTI: Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;五彩纸屑&quot;</span>); <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_SOLID:    Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;纯色&quot;</span>); <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_BREATH:   Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;呼吸灯&quot;</span>); <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_RAIN:     Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;下雨效果&quot;</span>); <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_FIRE:     Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;火焰效果&quot;</span>); <span class="hljs-keyword">break</span>;<br>    <span class="hljs-keyword">case</span> MODE_COMET:    Serial.<span class="hljs-built_in">println</span>(<span class="hljs-string">&quot;彗星效果&quot;</span>); <span class="hljs-keyword">break</span>;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>使用说明</p><ol><li>上传代码</li></ol><p>· 确保已正确安装 ESP32 开发板和 FastLED 库<br>· 选择正确的开发板（如 ESP32 Dev Module）和端口<br>· 点击上传</p><ol start="2"><li>串口控制命令</li></ol><p>打开串口监视器（波特率115200），发送以下命令：</p><p>模式切换：</p><p>· 0 - 彩虹循环<br>· 1 - 跑马灯<br>· 2 - 五彩纸屑<br>· 3 - 纯色模式<br>· 4 - 呼吸灯<br>· 5 - 下雨效果<br>· 6 - 火焰效果<br>· 7 - 彗星效果</p><p>亮度控制：</p><p>· b50 - 设置亮度为50<br>· b150 - 设置亮度为150<br>· b255 - 设置亮度为255（最亮）</p><p>纯色模式颜色切换：</p><p>· r - 红色<br>· g - 绿色<br>· b - 蓝色<br>· w - 白色<br>· y - 黄色<br>· p - 紫色</p><ol start="3"><li>电源注意事项</li></ol><p>30个WS2812灯珠全白最亮时功耗约 30 × 0.06A × 5V = 9W，建议使用外部5V电源供电，并将外部电源的GND与ESP32的GND连接。</p><p>这个代码提供了丰富的灯光效果和完整的控制功能，您可以通过串口实时切换模式和调整参数。</p><h2 id="写在最后">写在最后</h2><p>本文篇用于记录本次WS2812B项目经过，如有不妥，请见谅。</p>]]></content><id>https://b.wihi.top/posts/addc03d1.html</id><link href="https://b.wihi.top/posts/addc03d1.html"/><published>2025-10-19T04:00:00.000Z</published><summary>本文记录了WS2812B灯带项目设计思路以及过程，通过本次项目，学习如何使用Arduino IDE ，ESP32，WS2812B，电路设计等，项目化驱动学习</summary><title>WS2812B灯带项目</title><updated>2025-10-19T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="开发板" scheme="https://b.wihi.top/categories/%E5%BC%80%E5%8F%91%E6%9D%BF/"/><category term="SBC" scheme="https://b.wihi.top/categories/%E5%BC%80%E5%8F%91%E6%9D%BF/SBC/"/><category term="SBC" scheme="https://b.wihi.top/tags/SBC/"/><content><![CDATA[<p><font size="4">启动，人生中第一块开发板！</font></p><blockquote><p>在一次网上浏览时，我偶然发现了‘开发板’这个概念。经过一段时间的学习和研究，我最终选择购买一块香橙派（Orange Pi）SBC（单板计算机），作为我个人的‘电子实验室’。</p></blockquote><h2 id="引言">引言</h2><p>SBC 的全称是 Single-Board Computer，中文叫做 ‘单板计算机’。</p><p>顾名思义，它就是将一台完整计算机的所有核心部件（处理器、内存、输入/输出接口等）都集成在一块电路板上的微型电脑。它不像我们日常用的台式机那样由多个独立硬件组成，而是所有的功能都浓缩在了这一张‘板子’上。</p><p>因为它高度集成、体积小巧、价格亲民的特性，所以我选择以它作为我的电子实验室，而不是我家电脑。</p><p>这里我使用的开发板型号为：<strong>香橙派5ultra</strong>，下文所讲述的内容都以这个开发板的使用为基础。</p><p>（或许你会问：为什么不买树莓派？答：买的时候不知道树莓派生态的强大，但是香橙派有丰富的手册，可以实现我跑代码的需求）</p><h2 id="准备">准备</h2><h3 id="硬件">硬件</h3><ol><li><p>USB to USB公对公数据线 x1（用来烧录系统，当然也可以用串口，详细操作查看手册）</p></li><li><p>5v5a电源适配器 x1（给板子供电）</p></li><li><p>一个存储介质（这里我选择的铠侠SSD M.2280 PCle Gen3x4 不同存储介质有不同的烧录方法，详细查看手册）</p></li><li><p>一些散热措施：风扇，散热片等</p></li></ol><h3 id="软件">软件</h3><ol><li><p>一个要刷的系统的镜像（建议使用香橙派官方提供的镜像）</p></li><li><p>烧录软件和驱动（详细查看手册）</p></li></ol><h2 id="启动">启动</h2><h3 id="烧录">烧录</h3><p>根据手册提示，我使用SSD烧录，板子插上SSD，板子USB烧录口（手册中有，一个TYPE-A口）和电脑连接。然后摁住<strong>MaskROM</strong>后上电，上电后松手即可进入烧录模式。</p><p>然后根据手册内容进行烧录即可，烧录后系统会自动启动。</p><p>这里补充一下：如果烧录的这个系统不满意，可以根据手册提示操作<strong>清空SPIFLASH</strong>后重新烧录新的系统，重新烧录会自动清空磁盘中的数据，所以不用担心冲突等问题（在磁盘未分区的情况下）</p><h3 id="进入系统">进入系统</h3><p>烧录完毕后系统会自动启动，这里我刷的是Ubuntu，可以用SSH控制，但是刚刚烧录需要进入系统配网。</p><p>配网可以接入一个显示器（hdmi输出口，可以直接插家里电视上就好），然后根据提示操作即可，默认密码是orangepi。</p><p>手册说也可以串口控制，我没试过，但是应该是可以的。</p><p>另外：由于贫困，买不起显示器，于是买了一个HDMI采集器，把家里笔记本电脑变成显示器也是可以的。当然如果家里有废旧显示器，可能是VGA口，买一根hdmi转VGA就好了。</p><h2 id="更多玩转技巧">更多玩转技巧</h2><p>更多使用技巧手册中都有提供，例如查看CPU温度等指令。</p><p>我刷的是Ubuntu，这里记录一些常用操作：</p><h3 id="1-重命名主机名">1. 重命名主机名</h3><figure class="highlight dsconfig"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dsconfig"><span class="hljs-string">sudo</span> <span class="hljs-string">hostnamectl</span> <span class="hljs-built_in">set-hostname</span> <span class="hljs-string">new-hostname</span><br></code></pre></td></tr></table></figure><p>new-hostname就是新的主机名</p><p>hosts文件可能也有残留旧主机名的记录，sudo nano /etc/hosts进去然后把旧主机名改成新的</p><h3 id="2-修改密码">2. 修改密码</h3><p><strong>passwd</strong></p><p>根据提示输入即可，passwd后门可以跟一个用户名</p><h3 id="3-SSH禁止root登录和修改登录端口">3.SSH禁止root登录和修改登录端口</h3><p>进入/etc/ssh/sshd_config文件中，把以下选项设置为no</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">PermitRootLogin</span> <span class="hljs-literal">no</span><br></code></pre></td></tr></table></figure><p>可能该选项是yes或者被注释了，如果被注释就删掉注释符号然后改为no</p><p>把以下选项端口改为其他端口，范围0-65535</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">Port</span> <span class="hljs-number">56789</span> <span class="hljs-comment"># 示例端口，请换成你自己的</span><br></code></pre></td></tr></table></figure><p>你需要确保修改的端口没程序占用，并且你的防火墙允许了该端口（如果有防火墙）</p><h3 id="4-更换shell为zsh">4. 更换shell为zsh</h3><p>安装</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">sudo</span> apt update &amp;&amp; <span class="hljs-built_in">sudo</span> apt install zsh<br></code></pre></td></tr></table></figure><p>切换</p><figure class="highlight arcade"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arcade">chsh -s $(which zsh)<br></code></pre></td></tr></table></figure><h4 id="以下为AI代为总结的zsh介绍和使用">以下为AI代为总结的zsh介绍和使用</h4><p>好的，这是一份为你精心整理的 Zsh 终极总结，从介绍、使用到玩转，带你全面了解这款终端效率神器。</p><p>一、 Zsh 是什么？ (Introduction)</p><p>· 定位：Zsh (Z Shell) 是一个功能强大的 Linux/Unix 命令行解释器（Shell）。它被设计为 Bash (Bourne-Again Shell) 的增强替代品，兼容 Bash 的同时，提供了大量开箱即用的高级功能。<br>· 核心目标：提升用户在命令行环境下的效率、体验和美观度。<br>· 历史：诞生于 1990 年，经过多年发展，凭借 Oh My Zsh 框架的出现，成为最受欢迎的 Shell 之一。<br>· 与 Bash 的关系：可以理解为 Bash 的“超级进化版”。Bash 稳定通用，Zsh 则更智能、更易定制。</p><hr><p>二、 为什么要用 Zsh？ (The &quot;Why&quot;)</p><p>与 Bash 对比，其核心优势在于：</p><ol><li>智能补全：不只是文件名，更能补全命令选项、参数、路径、甚至进程名。按 Tab 的次数减少 80%。</li><li>主题系统：提示符 (Prompt) 变身信息中心，可直观显示 Git 分支、状态、错误码、路径等，无需反复输入 pwd, git status 等命令。</li><li>插件生态：通过插件轻松添加新功能，如语法高亮、命令自动建议，让终端变得“会思考”。</li><li>全局历史：所有终端窗口共享并即时同步命令历史，在一个窗口输入的命令，在另一个窗口按 ↑ 立刻能找到。</li><li>拼写纠正：自动提示并纠正输错的目录名和命令。</li></ol><hr><p>三、 Oh My Zsh 是什么？与 Zsh 的关系</p><p>这是最容易混淆的概念，必须厘清：</p><p>· Zsh：是引擎，是核心程序本身。没有配置的 Zsh 非常强大但难以驾驭。<br>· Oh My Zsh：是一个社区驱动的配置管理框架。它不是 Shell，而是一套庞大的配置文件、主题和插件的集合，并提供了便捷的管理工具。<br>· 完美比喻：<br>· Zsh = 安卓原生系统 (强大但简陋)<br>· Oh My Zsh = 小米 MIUI / 三星 One UI (对原生系统进行深度美化，提供应用商店、主题商店)<br>· 主题 = 手机主题皮肤<br>· 插件 = 安装在系统上的 App</p><p>Oh My Zsh 的意义在于，它让普通人也能通过简单配置，轻松享受 Zsh 的全部威力。</p><hr><p>四、 如何在 Ubuntu 下安装与切换 (Usage)</p><ol><li>安装 Zsh：<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">sudo</span> apt update &amp;&amp; <span class="hljs-built_in">sudo</span> apt install zsh<br></code></pre></td></tr></table></figure></li><li>设置为默认 Shell：<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">chsh -s $(<span class="hljs-built_in">which</span> zsh)<br></code></pre></td></tr></table></figure>【关键】：务必完全注销后重新登录，更改才会生效。</li><li>安装 Oh My Zsh 框架：<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">sh -c <span class="hljs-string">&quot;<span class="hljs-subst">$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)</span>&quot;</span><br></code></pre></td></tr></table></figure></li><li>验证：重新打开终端，执行 echo $SHELL，输出 /usr/bin/zsh 即成功。</li></ol><hr><p>五、 如何玩转 Zsh (Play &amp; Explore)</p><p>玩转 Zsh = 选择主题 (换皮肤) + 安装插件 (加技能)</p><p>第一步：玩转主题 (换皮肤) 主题决定了提示符的外观和信息量。</p><p>· 查看内置主题：ls ~/.oh-my-zsh/themes/<br>· 在线预览效果：Oh My Zsh 主题Wiki (必看！)<br>· 更换主题：编辑 ~/.zshrc，修改 ZSH_THEME=&quot;主题名&quot; (如 agnoster)，然后执行 source ~/.zshrc 生效。<br>· 【必做】：若主题显示乱码（方块□），请在你本地电脑的终端软件中安装 Nerd Font 字体 (如 MesloLGS NF)。</p><p>第二步：玩转插件 (加技能) 插件为 Zsh 增加全新功能。</p><p>· 安装必备神器：</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 1. 语法高亮：命令正确绿色，错误红色</span><br>git <span class="hljs-built_in">clone</span> https://github.com/zsh-users/zsh-syntax-highlighting.git <span class="hljs-variable">$&#123;ZSH_CUSTOM:-~/.oh-my-zsh/custom&#125;</span>/plugins/zsh-syntax-highlighting<br><br><span class="hljs-comment"># 2. 自动建议：根据历史给出灰色提示，按 → 采纳</span><br>git <span class="hljs-built_in">clone</span> https://github.com/zsh-users/zsh-autosuggestions <span class="hljs-variable">$&#123;ZSH_CUSTOM:-~/.oh-my-zsh/custom&#125;</span>/plugins/zsh-autosuggestions<br></code></pre></td></tr></table></figure><p>· 启用插件：编辑 ~/.zshrc，在 plugins=(git) 中加入插件名：</p>  <figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">plugins=(git zsh-autosuggestions zsh-syntax-highlighting)<br></code></pre></td></tr></table></figure><p>保存后执行 source ~/.zshrc，体验质的飞跃。</p><p>第三步：高级玩法</p><p>· 探索更多插件：如 autojump (快速目录跳转)、web-search (命令行搜索)。<br>· 自定义别名：在 ~/.zshrc 中添加 alias xx='xxx -yy'，简化长命令。<br>· 深度定制：直接编辑 ~/.zshrc 文件，调整各种环境变量和选项。</p><h3 id="5-终端工具推荐">5. 终端工具推荐</h3><p>桌面版：Tabby</p><p>高度集成全部的终端功能，还提供丰富的插件，比如要设置一个终端背景安装一个背景插件就好了。</p><p>更多介绍请查看它的<a href="https://tabby.sh/">Tabby官网</a></p><p>安卓版：Termux</p><p>安卓终端神器，用它就对了。<a href="https://termux.dev/cn/">Termux官网</a></p><h2 id="后记">后记</h2><p>板子如果连接显示器后CPU发热比较严重，贴了铜片散热依然70多摄氏度。我更换风扇为3010 11000转后温度稳定压在40度左右，但是噪声比较明显。我的风扇是装在保护壳上的，然后直吹CPU，或许你也可以考虑这么做。</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/bb9aec9d.html</id><link href="https://b.wihi.top/posts/bb9aec9d.html"/><published>2025-09-21T01:38:00.000Z</published><summary>记录了一份香橙派5 Ultra开发板入门指南，涵盖从硬件准备、系统烧录到Ubuntu基础配置的全过程。内容包括SSH安全设置、zsh安装、终端工具推荐及散热解决方案，希望对你有所帮助</summary><title>启动，人生中第一块开发板！</title><updated>2025-09-21T01:38:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Teach手记" scheme="https://b.wihi.top/categories/Teach%E6%89%8B%E8%AE%B0/"/><category term="Teach手记" scheme="https://b.wihi.top/tags/Teach%E6%89%8B%E8%AE%B0/"/><content><![CDATA[<p><font size="4">CloudFlare-R2配置mTLS</font></p><blockquote><p>CloudFlare开启mTLS文档已经写的很明白了，但是经过我的实践，我的R2存储桶部分文件需要通过客户端身份验证才能访问，但是我发现当使用R2的自定义公共域名的时候配置mTLS就无效了，故而用本篇文章来记录。</p></blockquote><h2 id="引入">引入</h2><p>  mTLS (Mutual TLS) 是标准TLS协议的扩展，在传统TLS基础上增加了客户端验证。在普通TLS中，只有服务器向客户端证明其身份；而在mTLS中，客户端也需要向服务器证明自己的身份。<br>  但是在为R2存储桶的公共域名开启mTLS后发现无法生效，服务器不向客户端发送证书验证请求。为了解决这个问题，我考虑使用CloudFlare的Works</p><h2 id="操作">操作</h2><h3 id="一-新建Workers项目">一.新建Workers项目</h3><ol><li><p>在Cloudflare仪表盘的账户主页侧边栏下滑，找到<strong>Workers</strong>，选择<strong>Workers和Pages</strong>，点击<strong>创建</strong></p></li><li><p>选择Workers的<strong>从 Hello World! 开始</strong>点击<strong>开始使用</strong>。</p></li><li><p>这时候无法编辑创建时候的项目代码，但是不用担心，点击下图所示的按钮以编辑项目代码。</p></li></ol><p><img src="https://img.wihi.top/posts/2e0babb9821095d268bddbfa36918732.png" alt="编辑按钮" title="项目编辑按钮"></p><ol start="4"><li>进行编辑，删掉全部原来的内容，写入如下内容：</li></ol><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> &#123;<br>  <span class="hljs-keyword">async</span> <span class="hljs-title function_">fetch</span>(<span class="hljs-params">request, env</span>) &#123;<br>    <span class="hljs-comment">// mTLS 验证</span><br>    <span class="hljs-keyword">const</span> tlsAuth = request.<span class="hljs-property">cf</span>.<span class="hljs-property">tlsClientAuth</span> || &#123;&#125;;<br>    <span class="hljs-keyword">if</span> (!tlsAuth.<span class="hljs-property">certVerified</span> || !tlsAuth.<span class="hljs-property">certPresented</span>) &#123;<br>      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Response</span>(<span class="hljs-string">&quot;mTLS required&quot;</span>, &#123; <span class="hljs-attr">status</span>: <span class="hljs-number">401</span> &#125;);<br>    &#125;<br><br>    <span class="hljs-keyword">try</span> &#123;<br>      <span class="hljs-keyword">const</span> objectKey = <span class="hljs-keyword">new</span> <span class="hljs-title function_">URL</span>(request.<span class="hljs-property">url</span>).<span class="hljs-property">pathname</span>.<span class="hljs-title function_">slice</span>(<span class="hljs-number">1</span>);<br>      <span class="hljs-keyword">const</span> <span class="hljs-built_in">object</span> = <span class="hljs-keyword">await</span> env.<span class="hljs-property">MY_BUCKET</span>.<span class="hljs-title function_">get</span>(objectKey);<br>      <span class="hljs-comment">// 注意，这里的存储桶变量名为MY_BUCKET</span><br>      <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">object</span>) &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Response</span>(<span class="hljs-string">`Object <span class="hljs-subst">$&#123;objectKey&#125;</span> not found`</span>, &#123; <span class="hljs-attr">status</span>: <span class="hljs-number">404</span> &#125;);<br>      &#125;<br><br>      <span class="hljs-keyword">const</span> headers = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Headers</span>();<br>      <span class="hljs-built_in">object</span>.<span class="hljs-title function_">writeHttpMetadata</span>(headers);<br>      headers.<span class="hljs-title function_">set</span>(<span class="hljs-string">&quot;etag&quot;</span>, <span class="hljs-built_in">object</span>.<span class="hljs-property">httpEtag</span>);<br><br>      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Response</span>(<span class="hljs-built_in">object</span>.<span class="hljs-property">body</span>, &#123; headers &#125;);<br><br>    &#125; <span class="hljs-keyword">catch</span> (err) &#123;<br>      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Response</span>(<span class="hljs-string">&quot;Internal error: &quot;</span> + err.<span class="hljs-property">message</span>, &#123; <span class="hljs-attr">status</span>: <span class="hljs-number">500</span> &#125;);<br>    &#125;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>以上代码的存储桶变量名为<strong>MY_BUCKET</strong></p><ol start="5"><li><p>点击右上角的部署按钮部署项目</p></li><li><p>然后返回到你的项目主页，点击添加绑定，选择R2存储桶，再次点击添加绑定，如图所示。</p></li></ol><p><img src="https://img.wihi.top/posts/bc06c8f82e964dc0e27f0d05ef72da95.png" alt="绑定按钮" title="绑定按钮"></p><p>我们只点击添加绑定，不复制其提供的代码，因为这个代码是PUT方法，我们下载浏览器访问并不需要PUT方法。当然如果你有需要你可以自己修改。</p><p><img src="https://img.wihi.top/posts/35c281dcb2a805143824355c4c3a9b14.png" alt="R2绑定" title="R2绑定"></p><ol start="7"><li>点击添加绑定后的变量名写<strong>MY BUCKET</strong>，这里写不了下划线，但是保存后自动会把空格替换成下划线。之所以写这个变量名是因为我们的代码中写的环境变量名为MY_BUCKET。然后R2存储桶选择你需要的存储桶，然后点击部署即可。</li></ol><h3 id="二-为Workers项目增加自定义域名">二. 为Workers项目增加自定义域名</h3><blockquote><p>因为使用mTLS的是我们自己的域名，因此需要为它增加自定义域名。但是与pages项目不同的是无法直接添加绑定自定义域名，需要我们自行添加Workers路由，如果你会该操作可以直接跳到第三步。</p></blockquote><ol><li><p>点击你的Workers项目的<strong>设置</strong>，在域和路由中复制<strong>workers.dev</strong>类型中的值，也就是你的项目域名。例如xxx.workers.dev</p></li><li><p>在Cloudflare的你的域的控制板中侧边栏的DNS中选择<strong>记录</strong>增加解析，类型选择<strong>CNAME</strong>，名称写入你自己想要的，例如我写入r2.wihi.top，目标写入刚刚你的xxx.workers.dev，代理状态一定要勾选已代理。然后点击保存即可</p></li></ol><blockquote><p>其实以上步骤按照网上其他人的说法随便写一个解析即可，但是我个人是这么弄的，你也可以尝试随便解析。</p></blockquote><ol start="3"><li>在侧边栏进入<strong>Workers路由</strong>，在HTTP路由点击添加路由，路由写入上文的r2.wihi.top/*，这里注意，一定要写/*，不然访问其他路径不会有正确路由，然后点击保存即可。如下图</li></ol><p><img src="https://img.wihi.top/posts/c3da12a502309d85dc358c7c16c4bbde.png" alt="workers路由" title="workers路由"></p><h3 id="三-开启mTLS，并配置规则">三. 开启mTLS，并配置规则</h3><ol><li><p>依旧在Cloudflare的你的域的控制板的侧边栏中，选择<strong>SSL/TLS</strong>，然后点击<strong>客户端证书</strong>。</p></li><li><p>点击客户端证书中右侧的<strong>创建证书</strong>，然后进行相关提示操作即可，由于官方文档其他人的文章已经写的很详细了，这里不再赘述。但是值得一提的是，如果选择的是使用Cloudflare生成私钥和CSR。在生成后，证书格式需要复制<strong>pem</strong>格式的，以便生成PCKS12格式证书导入到电脑中。</p></li><li><p>(可选)如果你有用浏览器访问的需求，可以参考该网站的<a href="https://myssl.com/cert_convert.html">证书格式转换</a>，这里提供使用openssl把pem格式证书转换为PCSK12。</p></li></ol><figure class="highlight d"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs d">openssl pkcs12 -<span class="hljs-keyword">export</span> -<span class="hljs-keyword">out</span> cert.pfx -inkey <span class="hljs-keyword">private</span>.key -<span class="hljs-keyword">in</span> cert.pem -certfile ca_bundle.pem<br></code></pre></td></tr></table></figure><ul><li>private.key: 私钥</li><li>cert.pem: 证书</li><li>ca_bundle.pem: 中间证书链（可选）</li></ul><p>注意，如果要删除中间链证书，那么-certfile也需要删掉。也就是如下命令：</p><figure class="highlight d"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs d">openssl pkcs12 -<span class="hljs-keyword">export</span> -<span class="hljs-keyword">out</span> cert.pfx -inkey <span class="hljs-keyword">private</span>.key -<span class="hljs-keyword">in</span> cert.pem<br></code></pre></td></tr></table></figure><ol start="4"><li><p>为域名启用mtls，在刚刚cloudflare控制板的客户端证书的主机处点击编辑添加需要启用mtls的域名例如上文的r2.wihi.top。值得注意的是这个域名必须开启了cloudflare代理</p></li><li><p>在客户端证书控制板中点击创建mTLS，启用WAF，拦截没有通过客户端验证的请求访问。这个已验证客户端证书，值一定是没有勾选的，也就是未通过验证的。如下图：</p></li></ol><p><img src="https://img.wihi.top/posts/c0f4d9cb65eb5dfacecd8938df92ae91.png" alt="mTLS拦截规则" title="mTLS拦截规则"></p><ol start="6"><li>到这里相关配置已经结束了，更多内容可以参考官方文档:</li></ol><ul><li><p><a href="https://developers.cloudflare.com/learning-paths/mtls/mtls-app-security/">具有应用程序安全性的 mTLS</a></p></li><li><p><a href="https://developers.cloudflare.com/ssl/client-certificates/">客户端证书 （mTLS）</a></p></li></ul><h3 id="四-在Win10电脑Edge浏览器中安装客户端证书">四. 在Win10电脑Edge浏览器中安装客户端证书</h3><ol><li><p>在电脑中点击打开第三步中生成的<strong>pfx</strong>文件,一定要选择<strong>安装到用户</strong>到计算机无效.其他根据提示安装即可</p></li><li><p>在浏览器的<strong>证书管理器</strong>的<strong>你的证书</strong>中查看<strong>从window导入的证书</strong>可以看到证书导入完毕,如下图</p></li></ol><p><img src="https://img.wihi.top/posts/d643376b8eda2c0e9de8d49ae9ae3e4f.png" alt="导入证书查看" title="导入证书查看"></p><ol start="3"><li>然后访问开启mTLS的网站,如上文的r2.wihi.top,正常应该提示选择证书,如下图,如果没有可以尝试清除浏览器缓存重新访问</li></ol><p><img src="https://img.wihi.top/posts/b737ef470557cfa6ab81af0e3fcca731.png" alt="请求验证证书" title="请求验证证书"></p><h2 id="温馨提示">温馨提示</h2><p>  本篇文章着重针对的是在浏览器中使用客户端验证,你当然也可以使用其他方法,如官方的例子:</p><p>将公共证书和私有证书放在同一个目录中，使用此 cURL 命令，我们将获得访问权限：</p><p>终端窗口</p><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">curl -I <span class="hljs-attr">--cert</span> cert<span class="hljs-selector-class">.pem</span> <span class="hljs-attr">--key</span> private-cert<span class="hljs-selector-class">.pem</span> https:<span class="hljs-comment">//mtls-test.example.com/mtls-test</span><br></code></pre></td></tr></table></figure><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">HTTP</span>/<span class="hljs-number">2</span> <span class="hljs-number">200</span>server: cloudflare<br></code></pre></td></tr></table></figure><p>如果没有证书，终端将显示以下内容：</p><p>终端窗口</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">curl -I https://mtls-<span class="hljs-keyword">test</span>.example.com/mtls-<span class="hljs-keyword">test</span><br></code></pre></td></tr></table></figure><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">HTTP</span>/<span class="hljs-number">2</span> <span class="hljs-number">403</span>server: cloudflare<br></code></pre></td></tr></table></figure><p>  如果有其他问题请查看官方文档查看指导,希望本篇内容对你有所帮助</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/54a16023.html</id><link href="https://b.wihi.top/posts/54a16023.html"/><published>2025-08-07T11:30:00.000Z</published><summary>详细解决CloudFlare R2存储桶使用自定义域名时mTLS配置失效的问题。通过Workers脚本实现客户端证书验证，完整介绍从证书生成、Workers部署、路由配置到浏览器证书安装的全流程</summary><title>CloudFlare-R2配置mTLS</title><updated>2025-08-07T11:30:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Teach手记" scheme="https://b.wihi.top/categories/Teach%E6%89%8B%E8%AE%B0/"/><category term="Teach手记" scheme="https://b.wihi.top/tags/Teach%E6%89%8B%E8%AE%B0/"/><content><![CDATA[<p><font size="4">CloudfalreDNS结合阿里云域名设置DNSSSEC</font></p><h2 id="引入">引入</h2><p>  DNSSEC（Domain Name System Security Extensions）是一种用于保护DNS查询和响应的安全机制，旨在防止DNS欺骗和缓存污染攻击。它通过数字签名验证DNS数据的真实性和完整性，从而确保用户获得的DNS信息是可信的。详细原理可以参考我的知识库中的文章<a href="https://doc.wihi.top/%E8%AE%A1%E7%AE%97%E6%9C%BA/dns/dnssec%E8%A7%A3%E6%9E%90/">DNSSEC解析</a></p><p>  但是值得注意的是，本文章指的是在阿里云（万网）注册的域名，然后修改域名的DNS服务器为cloudflare的DNS。从而进行设置的DNSSEC，如果您不是这个场景本篇文章可能有所不妥，请辩证看待。</p><p>  记录这篇文章主要是因为cloudflare设置DNSSEC的这个DS记录和阿里云要填写的DS记录这个相关名称不一样，故而特殊记录一下。</p><h2 id="操作">操作</h2><p>在Cloudfalre控制台中开启DNSSSEC,会展示下图内容:</p><p><img src="https://img.wihi.top/posts/52b21edbe9f19376149c95d8c46d084d.png" alt="Cloudflare控制台DNSSEC" title="Cloudflare控制台DNSSEC"></p><p>在阿里云域名控制台中进入DNSSEC设置,点击添加DS记录,会展示下图内容:</p><p><img src="https://img.wihi.top/posts/41b2b756d0c79b1f9b9b77285e42874d.png" alt="阿里云控制台DNSSEC" title="阿里云控制台DNSSEC"></p><h3 id="特殊：">特殊：</h3><p><strong>注意</strong>：阿里云处的密钥标签（Key Tag）对应cloudfalre的DS记录中的xxx.xxx. 3600 IN DS 后面的4位数(再后面的俩数字和字符无需理会)</p><p><strong>注意</strong>:阿里云处的加密算法（Algorithm）对应cloudflare的算法,查阅手册发现这里cloudfalre的算法<strong>13</strong>指的是阿里云的<strong>ECDSA Curve P-256 with SHA-256</strong></p><h3 id="其他的基本上一致：">其他的基本上一致：</h3><p>摘要类型对应摘要类型</p><p>摘要对应摘要</p><p>配置完毕点击提交即可.如果成功的话cloudflare的设置DNSSEC的地方过段时间会显示成功！提示：xxx 将受到 DNSSEC 的保护</p><h2 id="补充">补充</h2><p>我发现该方法也适用于腾讯云域名DNSSEC</p><p>如果在使用多个DNS提供商时可能需要考虑开启多签名者DNSSEC</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/a4e26f24.html</id><link href="https://b.wihi.top/posts/a4e26f24.html"/><published>2025-08-02T04:00:00.000Z</published><summary>介绍了如何在Cloudflare DNS中为阿里云注册的域名配置DNSSEC安全扩展。内容包括DNSSEC原理简述、Cloudflare控制台设置、阿里云DS记录填写指南，两平台间密钥标签和加密算法的对应关系解析</summary><title>CloudfalreDNS结合阿里云域名设置DNSSSEC</title><updated>2025-08-05T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Teach手记" scheme="https://b.wihi.top/categories/Teach%E6%89%8B%E8%AE%B0/"/><category term="Teach手记" scheme="https://b.wihi.top/tags/Teach%E6%89%8B%E8%AE%B0/"/><content><![CDATA[<p><font size="4">Material for MkDocs---数学公式</font></p><blockquote><p>知识库里面的内容涉及安培定律公式，发现无法渲染，也就是不支持数学公式，去必应搜索，出来的Material for MkDocs中文文档。其中的数学公式配置无法生效，可能是由于其调用的polyfill.io被封了，所以无效。阴差阳错才找到了原版官网，才找到正确方法。</p></blockquote><h2 id="操作">操作</h2><p>详细内容：<a href="https://squidfunk.github.io/mkdocs-material/reference/math/#mathjax-docsjavascriptsmathjaxjs">Material for MkDocs官方文档中配置数学公式</a></p><p>这里记录一下<strong>MathJax</strong>进行配置，<strong>没有使用KaTeX</strong>，KaTex不知道有没有我下面遇到的问题</p><p>在<strong>项目根目录起</strong>中新建docs/javascripts/mathjax.js文件。然后写入如下内容：</p><figure class="highlight nix"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs nix">w<span class="hljs-attr">indow.MathJax</span> <span class="hljs-operator">=</span> &#123;<br>  <span class="hljs-params">tex:</span> &#123;<br>    <span class="hljs-params">inlineMath:</span> [[<span class="hljs-string">&quot;<span class="hljs-char escape_">\\</span>(&quot;</span>, <span class="hljs-string">&quot;<span class="hljs-char escape_">\\</span>)&quot;</span>]],<br>    <span class="hljs-params">displayMath:</span> [[<span class="hljs-string">&quot;<span class="hljs-char escape_">\\</span>[&quot;</span>, <span class="hljs-string">&quot;<span class="hljs-char escape_">\\</span>]&quot;</span>]],<br>    <span class="hljs-params">processEscapes:</span> <span class="hljs-literal">true</span>,<br>    <span class="hljs-params">processEnvironments:</span> <span class="hljs-literal">true</span><br>  &#125;,<br>  <span class="hljs-params">options:</span> &#123;<br>    <span class="hljs-params">ignoreHtmlClass:</span> <span class="hljs-string">&quot;.*|&quot;</span>,<br>    <span class="hljs-params">processHtmlClass:</span> <span class="hljs-string">&quot;arithmatex&quot;</span><br>  &#125;<br>&#125;;<br><br>document$.subscribe(() <span class="hljs-operator">=</span><span class="hljs-operator">&gt;</span> &#123; <br>  MathJax.startup.output.clearCache()<br>  MathJax.typesetClear()<br>  MathJax.texReset()<br>  MathJax.typesetPromise()<br>&#125;)<br></code></pre></td></tr></table></figure><p>然后在项目的<strong>mkdocs.yml</strong>配置中写入如下内容：</p><figure class="highlight nestedtext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs nestedtext"><span class="hljs-attribute">markdown_extensions</span><span class="hljs-punctuation">:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-string">pymdownx.arithmatex:</span><br>      <span class="hljs-attribute">generic</span><span class="hljs-punctuation">:</span> <span class="hljs-string">true</span><br><br><span class="hljs-attribute">extra_javascript</span><span class="hljs-punctuation">:</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-string">javascripts/mathjax.js</span><br>  <span class="hljs-bullet">-</span> <span class="hljs-string">https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js</span><br></code></pre></td></tr></table></figure><p>这里的unpkg.com国内可以正常访问</p><p>我按照官方文档中的MathJax配置后，发现公式结构\[ \]无法渲染。于是修改docs/javascripts/mathjax.js文件代码如下：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-variable language_">window</span>.<span class="hljs-property">MathJax</span> = &#123;<br>  <span class="hljs-attr">tex</span>: &#123;<br>    <span class="hljs-attr">inlineMath</span>: [[<span class="hljs-string">&#x27;$&#x27;</span>, <span class="hljs-string">&#x27;$&#x27;</span>], [<span class="hljs-string">&#x27;\\(&#x27;</span>, <span class="hljs-string">&#x27;\\)&#x27;</span>]],<br>    <span class="hljs-attr">displayMath</span>: [[<span class="hljs-string">&#x27;$$&#x27;</span>, <span class="hljs-string">&#x27;$$&#x27;</span>], [<span class="hljs-string">&#x27;\\[&#x27;</span>, <span class="hljs-string">&#x27;\\]&#x27;</span>]],<br>    <span class="hljs-attr">packages</span>: &#123;<span class="hljs-string">&#x27;[+]&#x27;</span>: [<span class="hljs-string">&#x27;ams&#x27;</span>]&#125; <span class="hljs-comment">// 仅保留必要AMS扩展</span><br>  &#125;,<br>  <span class="hljs-attr">startup</span>: &#123;<br>    <span class="hljs-attr">typeset</span>: <span class="hljs-literal">false</span> <span class="hljs-comment">// 必须禁用自动渲染</span><br>  &#125;<br>&#125;;<br><br><span class="hljs-comment">// 单独提取渲染控制（关键！）</span><br><span class="hljs-variable language_">document</span>$.<span class="hljs-title function_">subscribe</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>  <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">window</span>.<span class="hljs-property">MathJax</span>?.<span class="hljs-property">typesetPromise</span>) &#123;<br>    <span class="hljs-title class_">MathJax</span>.<span class="hljs-title function_">typesetPromise</span>();<br>  &#125;<br>&#125;);<br></code></pre></td></tr></table></figure><h2 id="注意事项">注意事项</h2><p>我是询问AI后进行的解决。至于本质原因并不是很理解，未来深入学习后，会补充本质原因分析。如果修改后有任何BUG，请恢复官方配置。</p><p>本文章编写于2025年8月1日，如果在未来的失效了请以最新版本为主。</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/5dd226f0.html</id><link href="https://b.wihi.top/posts/5dd226f0.html"/><published>2025-08-01T04:00:00.000Z</published><summary>解决Material for MkDocs中数学公式无法渲染的问题，提供有效的MathJax配置方案。包含JavaScript配置文件和mkdocs.yml设置，解决公式结构解析异常，确保数学公式正确显示</summary><title>Material for MkDocs---数学公式</title><updated>2025-08-05T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Hexo" scheme="https://b.wihi.top/categories/Hexo/"/><category term="Hexo" scheme="https://b.wihi.top/tags/Hexo/"/><content><![CDATA[<p><font size="4">在Hexo-fluid的分类页中增加说明</font></p><blockquote><p>整了个文章专栏，想要在分类页面写个说明，本以为很简单，却发现需要修改的是主题页面文件，要改的东西挺多。基本上都是AI指导实现，仅做记录。<br>本文记录的是通过修改主题模板实现的方法，未来主题更新还需要手动重新配置，如果需要注入发可以前往：<a href="https://b.wihi.top/posts/2da73f2a.html">在Hexo-fluid的分类页中增加说明(2)--注入法</a></p></blockquote><div class="note note-success">            <p>本篇文章内容涉及hexo-fluid主题相关代码内容，<a href="https://github.com/fluid-dev/hexo-theme-fluid/tree/master">点击跳转仓库地址</a></p>           </div><h2 id="实现">实现</h2><h3 id="一-思路描述">一.思路描述</h3><p> 由于分类页面属于通过EJS模板文件读取相关数据列表然后构建的，并非从md等文件加载，因此只能考虑修改主题页面模板文件。</p><p> 于是找到分类页面的主题模板文件<code>categories.ejs</code>首先进行简要分析：</p><ol><li>页面元数据设置</li></ol><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs javascript">page.<span class="hljs-property">layout</span> = <span class="hljs-string">&#x27;categories&#x27;</span><br>page.<span class="hljs-property">title</span> = theme.<span class="hljs-property">category</span>.<span class="hljs-property">title</span> || <span class="hljs-title function_">__</span>(<span class="hljs-string">&#x27;category.title&#x27;</span>)<br>page.<span class="hljs-property">subtitle</span> = theme.<span class="hljs-property">category</span>.<span class="hljs-property">subtitle</span> || <span class="hljs-title function_">__</span>(<span class="hljs-string">&#x27;category.subtitle&#x27;</span>)<br>page.<span class="hljs-property">banner_img</span> = theme.<span class="hljs-property">category</span>.<span class="hljs-property">banner_img</span><br>page.<span class="hljs-property">banner_img_height</span> = theme.<span class="hljs-property">category</span>.<span class="hljs-property">banner_img_height</span><br>page.<span class="hljs-property">banner_mask_alpha</span> = theme.<span class="hljs-property">category</span>.<span class="hljs-property">banner_mask_alpha</span><br></code></pre></td></tr></table></figure><p>这部分设置了页面的基本属性：</p><ul><li>使用 'categories' 布局</li><li>标题和副标题从主题配置中获取，如果未配置则使用国际化翻译</li><li>设置横幅图片、高度和遮罩透明度</li></ul><ol start="2"><li>获取分类数据</li></ol><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> orderBy = theme.<span class="hljs-property">category</span>.<span class="hljs-property">order_by</span> || <span class="hljs-string">&#x27;name&#x27;</span><br><span class="hljs-keyword">var</span> curCats = site.<span class="hljs-property">categories</span>.<span class="hljs-title function_">find</span>(&#123; <span class="hljs-attr">parent</span>: &#123; <span class="hljs-attr">$exists</span>: <span class="hljs-literal">false</span> &#125; &#125;).<span class="hljs-title function_">sort</span>(orderBy).<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">cat</span> =&gt;</span> cat.<span class="hljs-property">length</span>)<br></code></pre></td></tr></table></figure><p>这部分：</p><ul><li>获取分类排序方式（默认为按名称排序）</li><li>查询所有顶级分类（没有父分类的分类）</li><li>按指定方式排序</li><li>过滤掉空分类（<code>cat.length</code> 检查分类下是否有文章）</li></ul><ol start="3"><li>渲染分类列表</li></ol><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs javascript">&lt;%- <span class="hljs-title function_">partial</span>(<span class="hljs-string">&#x27;_partials/category-list&#x27;</span>, &#123;<br>  <span class="hljs-attr">curCats</span>: curCats,<br>  <span class="hljs-attr">params</span>: &#123;<br>    <span class="hljs-attr">orderBy</span>: orderBy,<br>    postLimit  : theme.<span class="hljs-property">category</span>.<span class="hljs-property">post_limit</span>,<br>    <span class="hljs-attr">postOrderBy</span>: theme.<span class="hljs-property">category</span>.<span class="hljs-property">post_order_by</span> || config.<span class="hljs-property">index_generator</span>.<span class="hljs-property">order_by</span><br>  &#125;<br>&#125;) %&gt;<br></code></pre></td></tr></table></figure><p>这部分：</p><ul><li>引入 <code>_partials/category-list</code> 子模板</li><li>传递当前分类列表 (<code>curCats</code>)</li><li>传递参数包括：<ul><li>分类排序方式</li><li>文章数量限制</li><li>文章排序方式（默认使用全局配置）</li></ul></li></ul><p> 分析我们需要实现功能中需要加入的内容：由于我们的专栏介绍内容可能较多，于是考虑从额外的数据文件中读取数据，然后渲染（并且设置相关样式）。</p><p> 从数据文件中读取数据采用hexo提供的<code>source/_data</code>数据文件读取相关文件数据的功能。</p><p> 设置样式考虑使用CSS，在主题配置中直接引用css是全局性的，由于我们不想要全局性的，因此选择直接写在模板文件中。</p><h2 id="二-详细操作">二.详细操作</h2><ol><li>数据文件： 在项目的<code>source/_data</code>文件夹下新建文件<code>column_descriptions.yml</code>并且写下如下配置（下面的就是示例）：</li></ol><figure class="highlight nix"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs nix"><span class="hljs-params">columns:</span><br>  <span class="hljs-operator">-</span> <span class="hljs-params">name:</span> <span class="hljs-string">&quot;例子1&quot;</span><br>    <span class="hljs-params">subtitle:</span> <span class="hljs-string">&quot;例子1小标题&quot;</span><br>    <span class="hljs-params">icon:</span> <span class="hljs-string">&quot;icon-computer&quot;</span> <span class="hljs-comment">#示例图标，详细需要配合图标库</span><br>    <span class="hljs-params">description:</span> <span class="hljs-string">&quot;例子1描述&quot;</span><br>    <span class="hljs-params">color:</span> <span class="hljs-string">&quot;#1890ff&quot;</span> <span class="hljs-comment">##示例颜色</span><br>  <br>  <span class="hljs-operator">-</span> <span class="hljs-params">name:</span> <span class="hljs-string">&quot;例子2&quot;</span><br>    <span class="hljs-params">subtitle:</span> <span class="hljs-string">&quot;例子2小标题&quot;</span><br>    <span class="hljs-params">icon:</span> <span class="hljs-string">&quot;icon-life&quot;</span> <span class="hljs-comment">#示例图标，详细需要配合图标库</span><br>    <span class="hljs-params">description:</span> <span class="hljs-string">&quot;例子2描述&quot;</span><br>    <span class="hljs-params">color:</span> <span class="hljs-string">&quot;#f5222d&quot;</span> <span class="hljs-comment">#示例颜色</span><br><br><span class="hljs-comment"># 后门还可以根据需要按照示例格式增加内容</span><br></code></pre></td></tr></table></figure><ol start="2"><li>样式文件：在<code>source/css</code>文件夹下新建文件<code>custom.css</code>并且写入如下内容：</li></ol><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* 专栏容器 */</span><br><span class="hljs-selector-class">.columns-container</span> &#123;<br>  <span class="hljs-attribute">display</span>: grid;<br>  <span class="hljs-attribute">gap</span>: <span class="hljs-number">1.8rem</span>;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">2.5rem</span> <span class="hljs-number">0</span>;<br>&#125;<br><br><span class="hljs-comment">/* 单个专栏样式 */</span><br><span class="hljs-selector-class">.teach-column-desc</span> &#123;<br>  <span class="hljs-attr">--column-color</span>: <span class="hljs-number">#1890ff</span>; <span class="hljs-comment">/* 默认颜色 */</span><br>  <span class="hljs-attr">--column-color-rgb</span>: <span class="hljs-number">24</span>, <span class="hljs-number">144</span>, <span class="hljs-number">255</span>; <span class="hljs-comment">/* 默认RGB值 */</span><br>  <span class="hljs-attr">--column-hover-color</span>: <span class="hljs-number">#40a9ff</span>; <span class="hljs-comment">/* 悬停颜色 */</span><br>  <br>  <span class="hljs-attribute">padding</span>: <span class="hljs-number">1.8rem</span>;<br>  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">12px</span>;<br>  <span class="hljs-attribute">border-left</span>: <span class="hljs-number">4px</span> solid <span class="hljs-built_in">var</span>(--column-color);<br>  <span class="hljs-attribute">background</span>: <br>    <span class="hljs-built_in">radial-gradient</span>(circle at <span class="hljs-number">90%</span> <span class="hljs-number">10%</span>, <span class="hljs-built_in">rgba</span>(<span class="hljs-built_in">var</span>(--column-color-rgb), <span class="hljs-number">0.03</span>) <span class="hljs-number">0%</span>, transparent <span class="hljs-number">20%</span>),<br>    <span class="hljs-built_in">linear-gradient</span>(to bottom, <span class="hljs-built_in">rgba</span>(<span class="hljs-built_in">var</span>(--column-color-rgb), <span class="hljs-number">0.02</span>), <span class="hljs-built_in">rgba</span>(<span class="hljs-built_in">var</span>(--column-color-rgb), <span class="hljs-number">0.01</span>)),<br>    <span class="hljs-number">#ffffff</span>;<br>  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">4px</span> <span class="hljs-number">15px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.05</span>);<br>  <span class="hljs-attribute">transition</span>: <br>    transform <span class="hljs-number">0.35s</span> ease, <br>    box-shadow <span class="hljs-number">0.35s</span> ease,<br>    border-color <span class="hljs-number">0.3s</span> ease;<br>  <span class="hljs-attribute">position</span>: relative;<br>  <span class="hljs-attribute">overflow</span>: hidden;<br>&#125;<br><br><span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">:hover</span> &#123;<br>  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateY</span>(-<span class="hljs-number">5px</span>);<br>  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">8px</span> <span class="hljs-number">25px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.1</span>);<br>  <span class="hljs-attribute">border-left-color</span>: <span class="hljs-built_in">var</span>(--column-hover-color);<br>&#125;<br><br><span class="hljs-comment">/* 添加微妙的背景图案 */</span><br><span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">::before</span> &#123;<br>  <span class="hljs-attribute">content</span>: <span class="hljs-string">&quot;&quot;</span>;<br>  <span class="hljs-attribute">position</span>: absolute;<br>  <span class="hljs-attribute">top</span>: -<span class="hljs-number">20px</span>;<br>  <span class="hljs-attribute">right</span>: -<span class="hljs-number">20px</span>;<br>  <span class="hljs-attribute">width</span>: <span class="hljs-number">80px</span>;<br>  <span class="hljs-attribute">height</span>: <span class="hljs-number">80px</span>;<br>  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.05</span>;<br>  <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">var</span>(--column-color);<br>  <span class="hljs-attribute">mask-image</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">&quot;data:image/svg+xml,%3Csvg xmlns=&#x27;http://www.w3.org/2000/svg&#x27; viewBox=&#x27;0 0 24 24&#x27;%3E%3Cpath fill=&#x27;currentColor&#x27; d=&#x27;M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z&#x27;/%3E%3C/svg%3E&quot;</span>);<br>  <span class="hljs-attribute">mask-repeat</span>: no-repeat;<br>  <span class="hljs-attribute">z-index</span>: -<span class="hljs-number">1</span>;<br>&#125;<br><br><span class="hljs-selector-class">.desc-header</span> &#123;<br>  <span class="hljs-attribute">display</span>: flex;<br>  <span class="hljs-attribute">align-items</span>: flex-start;<br>  <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1.2rem</span>;<br>&#125;<br><br><span class="hljs-selector-class">.desc-header</span> <span class="hljs-selector-tag">i</span><span class="hljs-selector-class">.iconfont</span> &#123;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2.2rem</span>;<br>  <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">15px</span>;<br>  <span class="hljs-attribute">flex-shrink</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-color);<br>  <span class="hljs-attribute">transition</span>: color <span class="hljs-number">0.3s</span> ease;<br>&#125;<br><br><span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">:hover</span> <span class="hljs-selector-class">.desc-header</span> <span class="hljs-selector-tag">i</span><span class="hljs-selector-class">.iconfont</span> &#123;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-hover-color);<br>&#125;<br><br><span class="hljs-selector-class">.desc-header</span> <span class="hljs-selector-tag">h3</span> &#123;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">5px</span> <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.45rem</span>;<br>  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">600</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-color);<br>  <span class="hljs-attribute">transition</span>: color <span class="hljs-number">0.3s</span> ease;<br>&#125;<br><br><span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">:hover</span> <span class="hljs-selector-class">.desc-header</span> <span class="hljs-selector-tag">h3</span> &#123;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-hover-color);<br>&#125;<br><br><span class="hljs-selector-class">.subtitle</span> &#123;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">0.95rem</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-number">#666</span>;<br>  <span class="hljs-attribute">font-style</span>: italic;<br>&#125;<br><br><span class="hljs-selector-class">.desc-content</span> <span class="hljs-selector-tag">p</span> &#123;<br>  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.85</span>;<br>  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.08rem</span>;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-number">#333</span>;<br>  <span class="hljs-attribute">position</span>: relative;<br>  <span class="hljs-attribute">padding-left</span>: <span class="hljs-number">1.8rem</span>;<br>&#125;<br><br><span class="hljs-selector-class">.desc-content</span> <span class="hljs-selector-tag">p</span><span class="hljs-selector-pseudo">::before</span> &#123;<br>  <span class="hljs-attribute">content</span>: <span class="hljs-string">&quot;&quot;</span>;<br>  <span class="hljs-attribute">position</span>: absolute;<br>  <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">top</span>: <span class="hljs-number">0.6em</span>;<br>  <span class="hljs-attribute">width</span>: <span class="hljs-number">8px</span>;<br>  <span class="hljs-attribute">height</span>: <span class="hljs-number">8px</span>;<br>  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">50%</span>;<br>  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">var</span>(--column-color);<br>  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.7</span>;<br>  <span class="hljs-attribute">transition</span>: background <span class="hljs-number">0.3s</span> ease;<br>&#125;<br><br><span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">:hover</span> <span class="hljs-selector-class">.desc-content</span> <span class="hljs-selector-tag">p</span><span class="hljs-selector-pseudo">::before</span> &#123;<br>  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">var</span>(--column-hover-color);<br>&#125;<br><br><span class="hljs-selector-class">.highlight</span> &#123;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-color);<br>  <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">600</span>;<br>  <span class="hljs-attribute">position</span>: relative;<br>  <span class="hljs-attribute">display</span>: inline-block;<br>  <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">5px</span>;<br>  <span class="hljs-attribute">transition</span>: color <span class="hljs-number">0.3s</span> ease;<br>&#125;<br><br><span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">:hover</span> <span class="hljs-selector-class">.highlight</span> &#123;<br>  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--column-hover-color);<br>&#125;<br><br><span class="hljs-selector-class">.highlight</span><span class="hljs-selector-pseudo">::after</span> &#123;<br>  <span class="hljs-attribute">content</span>: <span class="hljs-string">&quot;&quot;</span>;<br>  <span class="hljs-attribute">position</span>: absolute;<br>  <span class="hljs-attribute">bottom</span>: -<span class="hljs-number">2px</span>;<br>  <span class="hljs-attribute">left</span>: <span class="hljs-number">0</span>;<br>  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;<br>  <span class="hljs-attribute">height</span>: <span class="hljs-number">2px</span>;<br>  <span class="hljs-attribute">background</span>: currentColor;<br>  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.3</span>;<br>  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;<br>  <span class="hljs-attribute">transition</span>: opacity <span class="hljs-number">0.3s</span> ease;<br>&#125;<br><br><span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">:hover</span> <span class="hljs-selector-class">.highlight</span><span class="hljs-selector-pseudo">::after</span> &#123;<br>  <span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.4</span>;<br>&#125;<br><br><span class="hljs-comment">/* 响应式设计 */</span><br><span class="hljs-keyword">@media</span> (<span class="hljs-attribute">max-width</span>: <span class="hljs-number">768px</span>) &#123;<br>  <span class="hljs-selector-class">.columns-container</span> &#123;<br>    <span class="hljs-attribute">gap</span>: <span class="hljs-number">1.3rem</span>;<br>  &#125;<br>  <br>  <span class="hljs-selector-class">.teach-column-desc</span> &#123;<br>    <span class="hljs-attribute">padding</span>: <span class="hljs-number">1.3rem</span>;<br>  &#125;<br>  <br>  <span class="hljs-selector-class">.desc-header</span> &#123;<br>    <span class="hljs-attribute">flex-direction</span>: column;<br>    <span class="hljs-attribute">align-items</span>: flex-start;<br>  &#125;<br>  <br>  <span class="hljs-selector-class">.desc-header</span> <span class="hljs-selector-tag">i</span><span class="hljs-selector-class">.iconfont</span> &#123;<br>    <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">10px</span>;<br>  &#125;<br>&#125;<br><br><span class="hljs-comment">/* 为不支持 mask-image 的浏览器提供回退 */</span><br><span class="hljs-keyword">@supports</span> <span class="hljs-keyword">not</span> (<span class="hljs-attribute">mask-image</span>: none) &#123;<br>  <span class="hljs-selector-class">.teach-column-desc</span><span class="hljs-selector-pseudo">::before</span> &#123;<br>    <span class="hljs-attribute">background</span>: none;<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure><ol start="3"><li>修改模板文件:打开<code>themes/fluid/layout</code>文件夹，找到<code>categories.ejs</code>文件并打开。</li></ol><ul><li>在文件开头第一行换行插入对css引用：</li></ul><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs routeros">&lt;link <span class="hljs-attribute">rel</span>=<span class="hljs-string">&quot;stylesheet&quot;</span> <span class="hljs-attribute">href</span>=<span class="hljs-string">&quot;/css/custom.css&quot;</span>&gt;<br></code></pre></td></tr></table></figure><ul><li>在<strong>第一对</strong>&lt;%%&gt;中的末尾新增如下内容：</li></ul><figure class="highlight processing"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs processing"><span class="hljs-comment">// 加载专栏配置文件</span><br><span class="hljs-keyword">const</span> columnData = site.<span class="hljs-property">data</span>.<span class="hljs-property">column_descriptions</span>;<br><br><span class="hljs-comment">// 十六进制转RGB函数（用于CSS变量）</span><br>function <span class="hljs-title function_">hexToRgb</span>(<span class="hljs-built_in">hex</span>) &#123;<br>  <span class="hljs-built_in">hex</span> = <span class="hljs-built_in">hex</span>.<span class="hljs-property">replace</span>(<span class="hljs-string">&#x27;#&#x27;</span>, <span class="hljs-string">&#x27;&#x27;</span>);<br>  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">hex</span>.<span class="hljs-property">length</span> === <span class="hljs-number">3</span>) &#123;<br>    <span class="hljs-built_in">hex</span> = <span class="hljs-built_in">hex</span>[<span class="hljs-number">0</span>] + <span class="hljs-built_in">hex</span>[<span class="hljs-number">0</span>] + <span class="hljs-built_in">hex</span>[<span class="hljs-number">1</span>] + <span class="hljs-built_in">hex</span>[<span class="hljs-number">1</span>] + <span class="hljs-built_in">hex</span>[<span class="hljs-number">2</span>] + <span class="hljs-built_in">hex</span>[<span class="hljs-number">2</span>];<br>  &#125;<br>  <span class="hljs-keyword">const</span> r = <span class="hljs-title function_">parseInt</span>(<span class="hljs-built_in">hex</span>.<span class="hljs-property">substring</span>(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>), <span class="hljs-number">16</span>);<br>  <span class="hljs-keyword">const</span> g = <span class="hljs-title function_">parseInt</span>(<span class="hljs-built_in">hex</span>.<span class="hljs-property">substring</span>(<span class="hljs-number">2</span>, <span class="hljs-number">4</span>), <span class="hljs-number">16</span>);<br>  <span class="hljs-keyword">const</span> b = <span class="hljs-title function_">parseInt</span>(<span class="hljs-built_in">hex</span>.<span class="hljs-property">substring</span>(<span class="hljs-number">4</span>, <span class="hljs-number">6</span>), <span class="hljs-number">16</span>);<br>  <span class="hljs-keyword">return</span> [r, g, b];<br>&#125;<br></code></pre></td></tr></table></figure><ul><li>在<strong>两对</strong>&lt;%%&gt;的<strong>中间</strong>新增如下内容：</li></ul><figure class="highlight vbscript-html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><code class="hljs vbscript-html"><span class="language-vbscript">&lt;% <span class="hljs-keyword">if</span> (columnData &amp;&amp; columnData.columns &amp;&amp; columnData.columns.length) &#123; %&gt;</span><span class="language-xml"></span><br><span class="language-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;columns-container&quot;</span>&gt;</span></span><br><span class="language-xml">    </span><span class="language-vbscript">&lt;% columnData.columns.forEach(column =&gt; &#123; </span><br><span class="language-vbscript">      <span class="hljs-keyword">const</span> color = column.color || <span class="hljs-comment">&#x27;#1890ff&#x27;;</span></span><br><span class="language-vbscript">      <span class="hljs-keyword">const</span> rgb = hexTo<span class="hljs-built_in">Rgb</span>(color);</span><br><span class="language-vbscript">    %&gt;</span><span class="language-xml"></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;teach-column-desc&quot;</span> </span></span><br><span class="hljs-tag"><span class="language-xml">           <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;</span></span></span><br><span class="hljs-string"><span class="hljs-tag"><span class="language-xml">             --column-color: </span></span></span><span class="language-vbscript">&lt;%- color %&gt;</span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">;</span></span></span><br><span class="hljs-string"><span class="hljs-tag"><span class="language-xml">             --column-color-rgb: </span></span></span><span class="language-vbscript">&lt;%= rgb.<span class="hljs-built_in">join</span>(<span class="hljs-comment">&#x27;,&#x27;) %&gt;</span></span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">;</span></span></span><br><span class="hljs-string"><span class="hljs-tag"><span class="language-xml">           &quot;</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;desc-header&quot;</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;iconfont icon-</span></span></span><span class="language-vbscript">&lt;%= column.icon || <span class="hljs-comment">&#x27;info-circle-fill&#x27; %&gt;</span></span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">            <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span></span><span class="language-vbscript">&lt;%= column.name %&gt;</span><span class="language-xml">专栏说明<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span></span><br><span class="language-xml">            </span><span class="language-vbscript">&lt;% <span class="hljs-keyword">if</span> (column.subtitle) &#123; %&gt;</span><span class="language-xml"></span><br><span class="language-xml">              <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;subtitle&quot;</span>&gt;</span></span><span class="language-vbscript">&lt;%= column.subtitle %&gt;</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">            </span><span class="language-vbscript">&lt;% &#125; %&gt;</span><span class="language-xml"></span><br><span class="language-xml">          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;desc-content&quot;</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">            <span class="hljs-tag">&lt;<span class="hljs-name">strong</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;highlight&quot;</span>&gt;</span></span><span class="language-vbscript">&lt;%= column.name %&gt;</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span></span><br><span class="language-xml">            </span><span class="language-vbscript">&lt;%= column.description %&gt;</span><span class="language-xml"></span><br><span class="language-xml">          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">    </span><span class="language-vbscript">&lt;% &#125;) %&gt;</span><span class="language-xml"></span><br><span class="language-xml">  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml"></span><span class="language-vbscript">&lt;% &#125; %&gt;</span><br></code></pre></td></tr></table></figure><ul><li>最后完整内容如下：</li></ul><figure class="highlight vbscript-html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><code class="hljs vbscript-html"><span class="language-xml"><span class="hljs-comment">&lt;!-- 直接引入分类页专属 CSS --&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">&quot;stylesheet&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;/css/custom.css&quot;</span>&gt;</span></span><br><span class="language-xml"></span><span class="language-vbscript">&lt;%</span><br><span class="language-vbscript">page.layout = <span class="hljs-comment">&#x27;categories&#x27;</span></span><br><span class="language-vbscript">page.title = theme.category.title || __(<span class="hljs-comment">&#x27;category.title&#x27;)</span></span><br><span class="language-vbscript">page.subtitle = theme.category.subtitle || __(<span class="hljs-comment">&#x27;category.subtitle&#x27;)</span></span><br><span class="language-vbscript">page.banner_img = theme.category.banner_img</span><br><span class="language-vbscript">page.banner_img_height = theme.category.banner_img_height</span><br><span class="language-vbscript">page.banner_mask_alpha = theme.category.banner_mask_alpha</span><br><span class="language-vbscript">var orderBy = theme.category.order_by || <span class="hljs-comment">&#x27;name&#x27;</span></span><br><span class="language-vbscript">var curCats = site.categories.find(&#123; parent: &#123; $exists: <span class="hljs-literal">false</span> &#125; &#125;).sort(orderBy).<span class="hljs-built_in">filter</span>(cat =&gt; cat.length)</span><br><span class="language-vbscript">// 加载专栏配置文件</span><br><span class="language-vbscript"><span class="hljs-keyword">const</span> columnData = site.data.column_descriptions;</span><br><span class="language-vbscript"></span><br><span class="language-vbscript">// 十六进制转RGB函数（用于CSS变量）</span><br><span class="language-vbscript"><span class="hljs-keyword">function</span> hexTo<span class="hljs-built_in">Rgb</span>(hex) &#123;</span><br><span class="language-vbscript">  hex = hex.<span class="hljs-built_in">replace</span>(<span class="hljs-comment">&#x27;#&#x27;, &#x27;&#x27;);</span></span><br><span class="language-vbscript">  <span class="hljs-keyword">if</span> (hex.length === <span class="hljs-number">3</span>) &#123;</span><br><span class="language-vbscript">    hex = hex[<span class="hljs-number">0</span>] + hex[<span class="hljs-number">0</span>] + hex[<span class="hljs-number">1</span>] + hex[<span class="hljs-number">1</span>] + hex[<span class="hljs-number">2</span>] + hex[<span class="hljs-number">2</span>];</span><br><span class="language-vbscript">  &#125;</span><br><span class="language-vbscript">  <span class="hljs-keyword">const</span> r = parse<span class="hljs-built_in">Int</span>(hex.<span class="hljs-keyword">sub</span><span class="hljs-built_in">string</span>(<span class="hljs-number">0</span>, <span class="hljs-number">2</span>), <span class="hljs-number">16</span>);</span><br><span class="language-vbscript">  <span class="hljs-keyword">const</span> g = parse<span class="hljs-built_in">Int</span>(hex.<span class="hljs-keyword">sub</span><span class="hljs-built_in">string</span>(<span class="hljs-number">2</span>, <span class="hljs-number">4</span>), <span class="hljs-number">16</span>);</span><br><span class="language-vbscript">  <span class="hljs-keyword">const</span> b = parse<span class="hljs-built_in">Int</span>(hex.<span class="hljs-keyword">sub</span><span class="hljs-built_in">string</span>(<span class="hljs-number">4</span>, <span class="hljs-number">6</span>), <span class="hljs-number">16</span>);</span><br><span class="language-vbscript">  return [r, g, b];</span><br><span class="language-vbscript">&#125;</span><br><span class="language-vbscript">%&gt;</span><span class="language-xml"></span><br><span class="language-xml"></span><br><span class="language-xml"><span class="hljs-comment">&lt;!-- 动态加载专栏说明 --&gt;</span></span><br><span class="language-xml"></span><span class="language-vbscript">&lt;% <span class="hljs-keyword">if</span> (columnData &amp;&amp; columnData.columns &amp;&amp; columnData.columns.length) &#123; %&gt;</span><span class="language-xml"></span><br><span class="language-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;columns-container&quot;</span>&gt;</span></span><br><span class="language-xml">    </span><span class="language-vbscript">&lt;% columnData.columns.forEach(column =&gt; &#123; </span><br><span class="language-vbscript">      <span class="hljs-keyword">const</span> color = column.color || <span class="hljs-comment">&#x27;#1890ff&#x27;;</span></span><br><span class="language-vbscript">      <span class="hljs-keyword">const</span> rgb = hexTo<span class="hljs-built_in">Rgb</span>(color);</span><br><span class="language-vbscript">    %&gt;</span><span class="language-xml"></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;teach-column-desc&quot;</span> </span></span><br><span class="hljs-tag"><span class="language-xml">           <span class="hljs-attr">style</span>=<span class="hljs-string">&quot;</span></span></span><br><span class="hljs-string"><span class="hljs-tag"><span class="language-xml">             --column-color: </span></span></span><span class="language-vbscript">&lt;%- color %&gt;</span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">;</span></span></span><br><span class="hljs-string"><span class="hljs-tag"><span class="language-xml">             --column-color-rgb: </span></span></span><span class="language-vbscript">&lt;%= rgb.<span class="hljs-built_in">join</span>(<span class="hljs-comment">&#x27;,&#x27;) %&gt;</span></span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">;</span></span></span><br><span class="hljs-string"><span class="hljs-tag"><span class="language-xml">           &quot;</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;desc-header&quot;</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;iconfont icon-</span></span></span><span class="language-vbscript">&lt;%= column.icon || <span class="hljs-comment">&#x27;info-circle-fill&#x27; %&gt;</span></span><span class="language-xml"><span class="hljs-tag"><span class="hljs-string">&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">            <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span></span><span class="language-vbscript">&lt;%= column.name %&gt;</span><span class="language-xml">专栏说明<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span></span><br><span class="language-xml">            </span><span class="language-vbscript">&lt;% <span class="hljs-keyword">if</span> (column.subtitle) &#123; %&gt;</span><span class="language-xml"></span><br><span class="language-xml">              <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;subtitle&quot;</span>&gt;</span></span><span class="language-vbscript">&lt;%= column.subtitle %&gt;</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">            </span><span class="language-vbscript">&lt;% &#125; %&gt;</span><span class="language-xml"></span><br><span class="language-xml">          <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;desc-content&quot;</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">            <span class="hljs-tag">&lt;<span class="hljs-name">strong</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;highlight&quot;</span>&gt;</span></span><span class="language-vbscript">&lt;%= column.name %&gt;</span><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">strong</span>&gt;</span></span><br><span class="language-xml">            </span><span class="language-vbscript">&lt;%= column.description %&gt;</span><span class="language-xml"></span><br><span class="language-xml">          <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">    </span><span class="language-vbscript">&lt;% &#125;) %&gt;</span><span class="language-xml"></span><br><span class="language-xml">  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml"></span><span class="language-vbscript">&lt;% &#125; %&gt;</span><span class="language-xml"></span><br><span class="language-xml"></span><br><span class="language-xml"></span><span class="language-vbscript">&lt;%- partial(<span class="hljs-comment">&#x27;_partials/category-list&#x27;, &#123;</span></span><br><span class="language-vbscript">  curCats: curCats,</span><br><span class="language-vbscript">  params: &#123;</span><br><span class="language-vbscript">    orderBy: orderBy,</span><br><span class="language-vbscript">    postLimit  : theme.category.post_limit,</span><br><span class="language-vbscript">    postOrderBy: theme.category.post_order_by || config.index_generator.order_by</span><br><span class="language-vbscript">  &#125;</span><br><span class="language-vbscript">&#125;) %&gt;</span><br></code></pre></td></tr></table></figure><h2 id="后记：">后记：</h2><p> 这些都是通过AI学习后进行的操作，可能中间有所不妥，还请多多指教，这篇主要用来记录。<br> 这些修改都是基于主题fluid1.9.8版本进行的操作，新或旧版可能无效，请见谅。<br> 以上全部内容遵循GNU 通用公共许可证 v3.0</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/8de7287f.html</id><link href="https://b.wihi.top/posts/8de7287f.html"/><published>2025-07-29T04:00:00.000Z</published><summary>介绍在Hexo Fluid主题分类页面添加专栏说明的方法，通过修改EJS模板、创建YAML数据文件和自定义CSS样式，实现动态加载美观的专栏介绍模块，提升分类页面的内容展示效果</summary><title>在Hexo-fluid的分类页中增加说明</title><updated>2026-04-04T12:50:06.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="CSS" scheme="https://b.wihi.top/categories/CSS/"/><category term="CSS" scheme="https://b.wihi.top/tags/CSS/"/><content><![CDATA[<p><font size="4">Material for MkDocs---添加背景</font></p><blockquote><p>最近为了搞我的文档<a href="https://doc.wihi.top">知识库</a>经过考虑选择了mkdoc，主题选择了Material。后来寻思整个背景图片，个人CSS水平一般，于是找AI代写，经过多次调试，终于整好了。</p></blockquote><h2 id="介绍">介绍</h2><ol><li>通过媒体查询实现横屏与竖屏状态下显示不同的背景</li><li>层次分明的毛玻璃效果</li><li>任何比例下显示都进行了兼容和优化</li></ol><p>要查看效果可以去参考我的<a href="https://doc.wihi.top">知识库</a></p><h2 id="使用方法">使用方法</h2><ol><li><p>补充CSS代码中的背景图片url(竖屏与横屏)</p></li><li><p>将CSS代码保存到你的mkdoc项目中<strong>docs文件夹</strong>中的任意一个位置。例如把CSS代码放到：docs/styles/bg.css中</p></li><li><p>在你的mkdoc项目下的<strong>mkdocs.yml</strong>中添加如下内容</p></li></ol><figure class="highlight nix"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs nix"><span class="hljs-params">extra_css:</span><br>  <span class="hljs-operator">-</span> styles<span class="hljs-symbol">/bg.css</span>   <span class="hljs-comment"># 这里仅供作示例，请根据实际情况替换位置（无需写docs，默认就是docs下的路径了）</span><br></code></pre></td></tr></table></figure><h2 id="注意事项">注意事项</h2><ol><li>本CSS采用MIT License协议，以下为概览：</li></ol><ul><li><strong>允许任何人免费使用、修改、分发</strong></li><li><strong>不强制要求署名</strong></li><li><strong>不提供任何担保，作者不承担责任</strong></li><li><strong>修改后的代码可以闭源</strong></li></ul><ol start="2"><li><p>本CSS优化针对的是<code>Material for MkDocs</code>的6.2.8版本，新或旧版本可能会无效或出现BUG</p></li><li><p>本CSS优化针对的是主题中开启导航选项卡，也就是在<code>mkdocs.yml</code>中添加配置：</p></li></ol><figure class="highlight nestedtext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs nestedtext"><span class="hljs-attribute">theme</span><span class="hljs-punctuation">:</span><br>  <span class="hljs-attribute">features</span><span class="hljs-punctuation">:</span><br>      <span class="hljs-bullet">-</span> <span class="hljs-string">navigation.tabs</span><br></code></pre></td></tr></table></figure><p><strong>并且没有再单独设置其他影响布局的配置</strong>否则可能会出现任何奇怪的显示背景</p><ol start="4"><li><p>本CSS中对于设置导航栏、页脚，内容栏等按照主题颜色为蓝色，内容背景颜色为白色设置的不透明度，如果您需要修改颜色，请修改相关的rgp值。</p></li><li><p>修复桌面端下左侧导航栏问题的相关CSS代码本来是想让桌面端访问时候左侧的导航栏为都白色半透明背景，因为之前设置完后最上方有一个白条，阴差阳错就变成了整体白色列表，别说还挺好看的，所以就保留了。</p></li></ol><h2 id="CSS样式：">CSS样式：</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><code class="hljs css"><span class="hljs-comment">/* ========== 基础背景设置 ========== */</span><br><span class="hljs-selector-tag">body</span> &#123;<br>    <span class="hljs-attribute">background-size</span>: cover;<br>    <span class="hljs-attribute">background-attachment</span>: fixed;<br>    <span class="hljs-attribute">background-position</span>: center;<br>    <span class="hljs-attribute">background-repeat</span>: no-repeat;<br>&#125;<br><br><span class="hljs-comment">/* 竖屏设备背景 */</span><br><span class="hljs-keyword">@media</span> (<span class="hljs-attribute">orientation</span>: portrait) &#123;<br>    <span class="hljs-selector-tag">body</span> &#123;<br>        <span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">&#x27;&#x27;</span>); //替换你自己的竖屏背景，注意不要删掉引号<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/* 横屏设备背景 */</span><br><span class="hljs-keyword">@media</span> (<span class="hljs-attribute">orientation</span>: landscape) &#123;<br>    <span class="hljs-selector-tag">body</span> &#123;<br>        <span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">&#x27;&#x27;</span>); //替换你自己的横屏背景，注意不要删掉引号<br>    &#125;<br>&#125;<br><br><span class="hljs-comment">/* ========== 半透明效果组件 ========== */</span><br><span class="hljs-comment">/* 标签栏 */</span><br><span class="hljs-selector-class">.md-tabs</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">63</span>, <span class="hljs-number">81</span>, <span class="hljs-number">181</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>);<br>&#125;<br><br><span class="hljs-comment">/* 页脚 */</span><br><span class="hljs-selector-class">.md-footer</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">63</span>, <span class="hljs-number">81</span>, <span class="hljs-number">181</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>);<br>&#125;<br><br><span class="hljs-comment">/* 对话框 */</span><br><span class="hljs-selector-class">.md-dialog</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.9</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">10px</span>);<br>&#125;<br><br><span class="hljs-comment">/* 内容区域 */</span><br><span class="hljs-selector-class">.md-content__inner</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: transparent <span class="hljs-meta">!important</span>;<br>&#125;<br><br><span class="hljs-comment">/* 搜索框 */</span><br><span class="hljs-selector-class">.md-search</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>    -webkit-<span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>);<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>);<br>&#125;<br><br><span class="hljs-comment">/* 导航栏 */</span><br><span class="hljs-selector-class">.md-header</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">63</span>, <span class="hljs-number">81</span>, <span class="hljs-number">181</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>    -webkit-<span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>);<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>);<br>&#125;<br><br><span class="hljs-comment">/* 主内容区 */</span><br><span class="hljs-selector-class">.md-main</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>&#125;<br><br><span class="hljs-comment">/* ========== 修复桌面端下左侧导航栏问题(莫名其妙就修复了，还挺好看的) ========== */</span><br><br><span class="hljs-selector-class">.md-nav--primary</span> <span class="hljs-selector-class">.md-nav__title</span>~<span class="hljs-selector-class">.md-nav__list</span> &#123;<br>    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>) <span class="hljs-meta">!important</span>;<br>    -webkit-<span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">box-shadow</span>: none <span class="hljs-meta">!important</span>;<br>&#125;<br><br><span class="hljs-comment">/* 右侧目录栏标题 - 提高优先级 */</span><br><span class="hljs-selector-class">.md-sidebar--secondary</span> <span class="hljs-selector-class">.md-nav__title</span>,<br><span class="hljs-selector-class">.md-sidebar--secondary</span> <span class="hljs-selector-class">.md-nav__title</span><span class="hljs-selector-pseudo">::before</span> &#123;<br>    <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>) <span class="hljs-meta">!important</span>;<br>    -webkit-<span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">box-shadow</span>: none <span class="hljs-meta">!important</span>;<br>&#125;<br><br><span class="hljs-comment">/* 移除原始样式中的背景和阴影 */</span><br><span class="hljs-selector-class">.md-nav--secondary</span> <span class="hljs-selector-class">.md-nav__title</span> &#123;<br>    <span class="hljs-attribute">background</span>: transparent <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">box-shadow</span>: none <span class="hljs-meta">!important</span>;<br>&#125;<br><br><br><span class="hljs-comment">/* 确保基础样式也被覆盖 */</span><br><span class="hljs-selector-class">.md-nav__title</span> &#123;<br>    <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">0.85</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>) <span class="hljs-meta">!important</span>;<br>    -webkit-<span class="hljs-attribute">backdrop-filter</span>: <span class="hljs-built_in">blur</span>(<span class="hljs-number">5px</span>) <span class="hljs-meta">!important</span>;<br>    <span class="hljs-attribute">box-shadow</span>: none <span class="hljs-meta">!important</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/a996b252.html</id><link href="https://b.wihi.top/posts/a996b252.html"/><published>2025-07-28T04:00:00.000Z</published><summary>介绍如何为Material for MkDocs主题添加自适应背景，提供完整的CSS解决方案。包含横竖屏不同背景设置、毛玻璃效果实现、导航栏优化及兼容性处理，适用于MkDocs 6.2.8版本</summary><title>Material for MkDocs---添加背景</title><updated>2025-07-28T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Teach手记" scheme="https://b.wihi.top/categories/Teach%E6%89%8B%E8%AE%B0/"/><category term="Teach手记" scheme="https://b.wihi.top/tags/Teach%E6%89%8B%E8%AE%B0/"/><content><![CDATA[<p><font size="4">图片中的EXIF信息</font></p><blockquote><p>起因是最近在和AI闲谈时，突然AI提及了一个全新的陌生的名词“EXIF信息”详细追问一下了解到了EXIF信息是啥以及对我们日常的影响</p></blockquote><h2 id="正文：">正文：</h2><p> 简而言之EXIF就行包含在图片中看不见的信息，只有使用十六进制等打开后才能看见，里面会包含我们的拍摄的设备信息，分辨率啊之类的，有的还会包含有GPS等信息。如果说我们在居家自拍的照片没有处理就发布在网上可能会泄露我们的地址，然后被不法分子加以利用。但是其实不必担心，像微信QQ之类的软件分享照片的时候就自动去除了EXIF，拍摄的时候可以选择关闭EXIF中包含的GPS定位（虽然我的手机我没找到在哪里关），我们也可以选择用专门删除EXIF信息的软件处理一下拍摄后的图片，如果说找不到这种软件那就去微信QQ自己给自己分享一下，分享后再下载下来的那个照片就相当于被去除了。</p><p> 其实正文到这里就结束了，就是想给大家分享一下这个东西，拍摄照片的时候注意一下关闭定位，发送的时候注意处理一下之类的。下面是AI对于EXIF信息的介绍，想看的读者可以往下滑再看看。</p><h2 id="EXIF的系统介绍">EXIF的系统介绍</h2><blockquote><p>以下内容由AI介绍（AI名字我就不说了，以免说我打广告）</p></blockquote><h3 id="图片的EXIF信息是什么？">图片的EXIF信息是什么？</h3><p><strong>EXIF</strong>（Exchangeable Image File Format，可交换图像文件格式）是一种嵌入在数字照片中的<strong>元数据</strong>标准，用于记录与照片相关的设备参数、拍摄环境、时间地点等信息。它最初由日本电子工业发展协会（JEIDA）于1996年制定，现已成为数码相机、智能手机等设备存储照片元数据的通用标准。</p><hr><h3 id="EXIF信息的作用">EXIF信息的作用</h3><ol><li><p><strong>记录拍摄参数</strong></p><ul><li>包括光圈（F值）、快门速度、ISO感光度、焦距、闪光灯状态等，帮助用户了解照片的拍摄条件。</li><li>示例：摄影师可以通过EXIF分析某张照片的曝光参数，学习如何优化拍摄技巧。</li></ul></li><li><p><strong>存储设备信息</strong></p><ul><li>记录相机或手机的品牌、型号、固件版本等，便于识别设备来源。</li></ul></li><li><p><strong>时间与地理位置</strong></p><ul><li><strong>时间戳</strong>：记录拍摄日期和时间。</li><li><strong>GPS坐标</strong>：如果设备开启了定位功能，EXIF会包含经纬度信息（例如：北纬39.9042°，东经116.4074°对应北京）。</li></ul></li><li><p><strong>辅助管理和后期处理</strong></p><ul><li>通过EXIF信息，用户可以按时间、地点或设备分类照片，或在后期调整参数时参考原始数据。</li></ul></li><li><p><strong>法律与证据价值</strong></p><ul><li>在司法鉴定中，EXIF信息可作为照片真实性、拍摄时间地点的辅助证据（但需注意其可被修改）。</li></ul></li></ol><hr><h3 id="为什么包含GPS等敏感内容却未被淘汰？">为什么包含GPS等敏感内容却未被淘汰？</h3><p>尽管EXIF可能泄露隐私，但它依然被广泛使用，原因如下：</p><h4 id="1-技术与功能需求">1. <strong>技术与功能需求</strong></h4><ul><li><strong>默认记录</strong>：大多数设备（尤其是智能手机）默认开启EXIF记录功能，方便用户管理照片。</li><li><strong>行业标准</strong>：EXIF已成为摄影、新闻、科研等领域的基础工具，例如：<ul><li><strong>新闻报道</strong>：记者需通过EXIF验证照片的真实性。</li><li><strong>科学研究</strong>：生态学家利用照片的GPS信息追踪物种分布。</li></ul></li></ul><h4 id="2-用户控制权存在">2. <strong>用户控制权存在</strong></h4><ul><li><strong>可手动关闭</strong>：用户可以在设备设置中关闭定位服务或EXIF记录（如iPhone的“照片设置”中关闭“位置”权限）。</li><li><strong>后期处理</strong>：通过软件（如Photoshop、ExifTool）可手动删除或修改EXIF数据。</li></ul><h4 id="3-隐私意识不足">3. <strong>隐私意识不足</strong></h4><ul><li>许多用户不了解EXIF的风险，或认为“拍照分享无害”。例如，社交媒体上的旅行照片可能暴露家庭住址（通过GPS定位家中）。</li></ul><h4 id="4-平台处理差异">4. <strong>平台处理差异</strong></h4><ul><li><strong>部分平台自动剥离EXIF</strong>：如微信、微博、Instagram等社交平台会自动删除上传图片的EXIF信息。</li><li><strong>部分平台保留EXIF</strong>：如Twitter、Telegram等可能保留部分元数据。</li></ul><h4 id="5-安全风险与便利性的权衡">5. <strong>安全风险与便利性的权衡</strong></h4><ul><li>对于普通用户，EXIF的便利性（如自动整理照片、地图标记）通常大于隐私风险。</li><li>对于高敏感场景（如军事、政府），可通过专用工具批量删除EXIF。</li></ul><hr><h3 id="所有图片都包含EXIF吗？">所有图片都包含EXIF吗？</h3><p>并非所有图片都包含EXIF信息，具体取决于以下因素：</p><h4 id="1-设备类型">1. <strong>设备类型</strong></h4><ul><li><strong>智能手机/数码相机</strong>：默认生成EXIF（含GPS、拍摄参数）。</li><li><strong>扫描仪/屏幕截图</strong>：通常不包含EXIF，或仅保留基础信息（如时间）。</li><li><strong>绘图软件生成的图片</strong>：如Photoshop保存的图片可能不含EXIF，除非手动添加。</li></ul><h4 id="2-文件格式">2. <strong>文件格式</strong></h4><ul><li><strong>支持EXIF的格式</strong>：JPEG、TIFF、RAW、PNG（部分支持）。</li><li><strong>不支持EXIF的格式</strong>：GIF、BMP（仅少量元数据）。</li></ul><h4 id="3-后期处理">3. <strong>后期处理</strong></h4><ul><li><strong>编辑后丢失EXIF</strong>：用普通图片编辑器（如Windows画图）保存图片时，EXIF可能被清除。</li><li><strong>专业工具保留EXIF</strong>：如Lightroom、Snapseed会保留或允许编辑EXIF。</li></ul><h4 id="4-平台规则">4. <strong>平台规则</strong></h4><ul><li><strong>社交平台</strong>：如微信、微博会剥离EXIF；Telegram则可能保留。</li><li><strong>云存储服务</strong>：Google Photos会保留EXIF，但提供“模糊位置”选项；iCloud默认保留。</li></ul><hr><h3 id="如何查看和管理EXIF信息？">如何查看和管理EXIF信息？</h3><h4 id="查看方法：">查看方法：</h4><ol><li><strong>Windows系统</strong>：右键图片 → “属性” → “详细信息”。</li><li><strong>Mac系统</strong>：打开“预览” → 工具 → 显示EXIF数据。</li><li><strong>手机App</strong>：Android的“相册”详情页、iOS的“照片”App（部分信息）。</li><li><strong>专业工具</strong>：ExifTool、Adobe Lightroom、在线工具（如EXIF Viewer by 365Tracker）。</li></ol><h4 id="删除或修改方法：">删除或修改方法：</h4><ol><li><strong>手动操作</strong>：<ul><li>使用ExifTool命令行工具（如 <code>exiftool -all= image.jpg</code> 删除所有EXIF）。</li><li>在Photoshop中通过“文件简介”面板编辑元数据。</li></ul></li><li><strong>自动工具</strong>：<ul><li>批量处理软件（如Bulk EXIF Remover）。</li><li>在线服务（如Optimizilla、TinyPNG，压缩图片时自动剥离EXIF）。</li></ul></li></ol><hr><h3 id="总结">总结</h3><p>EXIF信息是数字摄影的“幕后记录者”，既有实用价值也存在隐私隐患。它的存在并非不合理，而是需要用户主动管理。对于普通用户，关闭不必要的定位权限即可规避风险；对于高敏感场景，则需使用专业工具彻底清除元数据。正如国家安全部提醒的那样，随手分享的照片可能成为泄密源头，谨慎处理EXIF信息是数字时代的基本素养。</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/bc44f5a.html</id><link href="https://b.wihi.top/posts/bc44f5a.html"/><published>2025-05-25T04:00:00.000Z</published><summary>介绍图片EXIF信息的定义、作用及隐私风险，涵盖拍摄参数、设备信息和GPS定位等元数据的记录原理，提供查看和管理EXIF的实用方法，并分析其技术价值与安全隐患的平衡</summary><title>图片中的EXIF信息</title><updated>2025-05-25T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Hexo" scheme="https://b.wihi.top/categories/Hexo/"/><category term="Hexo" scheme="https://b.wihi.top/tags/Hexo/"/><content><![CDATA[<p><font size="4">解决Hexo中第三方图床图片无法显示问题</font></p><blockquote><p>起因是,使用某云盘做外链图床时发现图片无法在https访问时正常显示,在使用云盘作为图床时，该问题.通常是因为浏览器的<strong>跨域资源共享（CORS）**政策或**引用来源限制</strong>导致的</p></blockquote><h2 id="问题原因">问题原因</h2><ol><li><p>引用来源限制（Referrer Policy）</p><p>：</p><ul><li>当你将图片托管在云盘上，并通过 URL 引用这些图片时，云盘的服务器可能会检查请求的<strong>Referer</strong>头（该头记录了请求发起页面的 URL）。如果<strong>Referer</strong>头携带的 URL 和云盘的资源域名不匹配，云盘可能会拒绝提供资源或返回错误响应。</li></ul></li><li><p>CORS策略</p><p>：</p><ul><li>浏览器在加载跨域资源时，会检查 CORS（跨域资源共享）策略。如果服务器未正确配置 CORS 头，浏览器会阻止显示资源。</li></ul></li></ol><h2 id="通过-meta-name-referrer-content-no-referrer-来解决">通过 <code>&lt;meta name=&quot;referrer&quot; content=&quot;no-referrer&quot;/&gt;</code> 来解决</h2><p>在页面 <code>&lt;head&gt;</code> 中加入 <code>&lt;meta name=&quot;referrer&quot; content=&quot;no-referrer&quot;/&gt;</code> 后，可以解决图片无法显示的问题，其原因如下：</p><ol><li><p>控制 Referrer 头部</p><p>：</p><ul><li><strong><code>&lt;meta name=&quot;referrer&quot; content=&quot;no-referrer&quot;/&gt;</code></strong> 设置了一个特定的引用策略，告知浏览器在请求图片时不携带任何 Referer 头。这样，云盘的服务器就无法收到来自原网站的 Referer 信息，也就不会因为来源不匹配而拒绝返回图片。</li></ul></li><li><p>避免隐私泄露</p><p>：</p><ul><li>在某些情况下，Referer 头部会暴露用户正在访问的页面 URL，这可能会带来隐私泄露的风险。使用 <code>no-referrer</code> 策略可以有效地避免这个问题，同时也避免了由于 Referer 不匹配而导致的请求失败。</li></ul></li></ol><h2 id="总结">总结</h2><p>通过设置 <code>&lt;meta name=&quot;referrer&quot; content=&quot;no-referrer&quot;/&gt;</code>，浏览器会在请求图片时不发送 Referer 头，避免了跨域请求时因为 Referer 不匹配而导致的访问被拒绝。这种方式有助于解决使用云盘作为图床时，图片无法显示的问题。</p><h2 id="如何在Hexo系统上修改">如何在Hexo系统上修改:</h2><p>根据实际情况在<code>thems</code>中找到自己的主题文件夹,然后在<code>layout</code>文件夹中搜索<code>head.ejs</code>文件并且打开,然后在<code>&lt;head&gt;</code>标签下写入<code> &lt;meta name=&quot;referrer&quot; content=&quot;no-referrer&quot;/&gt;</code>如果没有head标签就自己创建一个</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/d5051a4d.html</id><link href="https://b.wihi.top/posts/d5051a4d.html"/><published>2025-02-22T04:00:00.000Z</published><summary>解决Hexo博客中使用第三方图床时图片无法显示的问题，分析跨域资源共享(CORS)和引用来源限制的原因，提供通过添加meta标签禁用Referer头的解决方案，确保图片正常加载</summary><title>解决Hexo中第三方图床图片无法显示问题</title><updated>2025-02-22T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Docker" scheme="https://b.wihi.top/categories/Docker/"/><category term="Docker" scheme="https://b.wihi.top/tags/Docker/"/><content><![CDATA[<p><font size="4">灵活运用Docker--部署应用:Nextcloud&amp;Ubuntu</font></p><blockquote><p>简单来说就是为了方便，直接拉取镜像创建容器然后访问就可以用了，相当于是开箱即用。</p></blockquote><h2 id="Docker部署Nextcloud">Docker部署Nextcloud</h2><blockquote><p>无聊翻阅宝塔的Docker应用列表的时候发现了NextCloud：<code>开源免费的私有云存储网盘项目</code> 我觉得他最大的优点就是可以多端协作，在服务端部署后，安卓、windows、Web网页，豆可以操作。</p></blockquote><h3 id="安装与启动">安装与启动</h3><p>其实没啥要说的，指令流程可以去搜一下，甚至如果你使用<code>宝塔</code>只需要在docker的应用列表那里搜<code>Nextcloud</code>就可直接安装了，但是安装好后要多等一会儿，我2c2g的服务器点击启动后需要等大概1分钟左右那个面板状态才显示已启动，才能访问，所以说如果你点了启动发现状态没更新，不要担心，多等一会就OK。访问进去后直接让你注册，你直接输入自己想用的输入用户名和密码，直接输入然后点击确定就可以了。</p><h3 id="挂载第三方存储">挂载第三方存储</h3><p>这个值得一提，如果说你需要挂载第三方存储，例如对象存储，需要在部署好后，在**应用-已安装应用-外部存储支持(可能是英文，自己翻译一下)**启用后，就可以在左侧列表看到<code>外部存储</code>这个选项，然后根据实际情况配置外部存储即可。</p><p><strong>PS：如果你选择S3存储，那么主机名就是存储桶的那个链接，不要带<code>http://</code>或<code>https://</code>等协议头，后面结尾不要跟路径和<code>/</code>直接就写域名，下面端口如果http就写80，https就写443。</strong></p><p>更多内容可以查看官方文档<a href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/external_storage_configuration_gui.html">配置外部存储(GUI)</a></p><h2 id="Docker部署Ubnutu-乌班图">Docker部署Ubnutu(乌班图)</h2><blockquote><p>因为穷，所以没钱买服务器，或者说只是跑代码，不划算，所以找人花钱在别人服务器上部署一个Docker容器部署乌班图系统。</p></blockquote><h3 id="安装和部署SSH">安装和部署SSH</h3><p>直接搞个乌班图docker镜像创建容器即可，然后用伪终端在容器内执行代码安装ssh，配置一个端口转发暴露即可使用ssh连接容器。是的，没错，直接使用<code>ssh -p 转发的容器SSH端口 root@宿主机IP</code>就可以链接了。链接的不是宿主机，就是部署了乌班图系统的Docker容器。</p><h3 id="访问容器">访问容器</h3><p>推荐使用指令对docker的容器端口进行转发到宿主机端口，转发后即可访问转发后的端口进行工作。当然也可以选择暴露全部端口，但是不安全，而且容易造成端口冲突。</p><h3 id="关于systemctl">关于systemctl</h3><blockquote><p>以下内容由AI总结</p></blockquote><p>在 Docker 容器中使用伪终端来执行 <code>systemctl</code> 或类似的系统服务管理指令时，通常会遇到问题，主要是因为 Docker 容器的设计理念与传统的虚拟机或物理服务器有所不同。以下是一些关键原因：</p><h4 id="1-Docker-容器的“最小化”特性">1. Docker 容器的“最小化”特性</h4><p>Docker 容器通常被设计为运行单一进程（或一个应用程序）。为了减少镜像体积和提高启动效率，容器内部不包含完整的操作系统服务管理框架（例如 <code>systemd</code> 或 <code>init</code> 系统）。因此，容器内无法使用 <code>systemctl</code> 来启动、停止服务或管理系统状态。</p><h4 id="2-缺少-systemd">2. 缺少 <code>systemd</code></h4><p><code>systemd</code> 是一种系统和服务管理器，通常用于管理 Linux 系统中的服务。Docker 容器默认并不包含 <code>systemd</code>，因为容器内只运行一个主进程（通常是某个应用或服务），没有像传统系统中那样的多个后台服务。所以，<code>systemctl</code> 无法在容器内正常工作，因为它依赖于 <code>systemd</code> 来启动和管理服务。</p><h4 id="3-容器的-PID-1-问题">3. 容器的 PID 1 问题</h4><p>容器的 PID 1 是应用程序本身，而不是一个管理系统（例如 <code>systemd</code>）。<code>systemd</code> 通常需要在主机的 PID 1 进程中运行才能正确管理服务和处理信号。然而，在 Docker 中，PID 1 只是你启动的应用进程，这意味着无法通过 <code>systemctl</code> 来管理其他进程。</p><h4 id="4-systemctl-需要一个运行时环境">4. <code>systemctl</code> 需要一个运行时环境</h4><p><code>systemctl</code> 和类似的服务管理命令通常需要访问一个完整的操作系统环境，包括系统日志、配置文件、进程管理等，而容器通常不具备这些环境。容器的文件系统和网络配置是有限制的，且通常不提供完整的系统环境来支持传统的服务管理。</p><h4 id="解决方案：">解决方案：</h4><ol><li><p><strong>使用 <code>docker exec</code></strong>：<br>如果你希望在已经运行的容器中执行某些操作，可以使用 <code>docker exec</code> 来启动命令，而不是使用 <code>systemctl</code>。例如：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">docker <span class="hljs-built_in">exec</span> -it &lt;container_id&gt; bash<br></code></pre></td></tr></table></figure><p>然后在容器内运行所需的命令。</p></li><li><p><strong>使用自定义启动脚本</strong>：<br>你可以为容器编写一个自定义的启动脚本，用于启动多个进程。你可以使用 <code>supervisord</code> 或 <code>tini</code> 等工具来模拟服务管理。</p></li><li><p><strong>使用 Docker Compose</strong>：<br>如果你需要管理多个服务，可以使用 Docker Compose 来定义多个容器，并且将它们作为服务进行管理。</p></li><li><p><strong>为容器提供 <code>systemd</code> 支持（不推荐）</strong>：<br>如果确实需要 <code>systemd</code>，你可以在 Docker 容器中安装和配置它，但这通常不推荐，除非你有特定需求。安装 <code>systemd</code> 会使容器变得更加复杂，并且失去了 Docker 的轻量化优势。</p></li></ol><h4 id="总结：">总结：</h4><p><code>systemctl</code> 等工具依赖于传统的 Linux 系统环境和服务管理，而 Docker 容器设计上并没有提供这种环境。你可以使用其他方式（如 <code>supervisord</code>）来启动和管理多个进程，但这通常不是 Docker 的推荐做法。</p><p><strong>关于我的解决方案：既然不能用那就不用，直接<code>cd</code>进程序的安装目录<code>./可执行文件 指令</code>执行命令</strong></p><p> </p><h3 id="写在最后">写在最后</h3><p>Docker容器中部署Ubuntu后使用容器内<code>ssh、伪终端</code>跑代码再部署其他应用属实是无奈之举，这可能不符合docker的设计理念，甚至可能有一些安全隐患，所以请自行甄别是否合理，可行。</p><p>完结撒花！</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/5c355465.html</id><link href="https://b.wihi.top/posts/5c355465.html"/><published>2025-01-26T04:00:00.000Z</published><summary>分享使用Docker部署Nextcloud私有云盘和Ubuntu系统的过程，Nextcloud的多端协作与外部存储的配置，以及在Docker容器中运行Ubuntu系统的SSH连接和进程管理解决方案</summary><title><![CDATA[灵活运用Docker--部署应用:Nextcloud&Ubuntu]]></title><updated>2025-01-26T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Teach手记" scheme="https://b.wihi.top/categories/Teach%E6%89%8B%E8%AE%B0/"/><category term="Teach手记" scheme="https://b.wihi.top/tags/Teach%E6%89%8B%E8%AE%B0/"/><content><![CDATA[<p><font size="4">解决Vercel文章链接地址末尾无.html访问问题</font></p><blockquote><p>使用Hexo构建静态网页托管在cloudflare Pages后我发现文章链接地址为/xxx.html或xxx都可以访问，以为是默认就可以的，后来迁移vercel发现了并不是默认就可以，而是需要另外重写链接的。</p></blockquote><h2 id="解决问题">解决问题</h2><p><strong>解决方法：编写以下重定向规则</strong></p><p>如果是<strong>Vercel</strong>那么在项目的根目录里面新增一个<code>vercel.json</code>文件后写入以下内容，若为其他静态托管平台请自行查阅如何编辑重写规则</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs css">&#123;<br>  &quot;rewrites&quot;: [<br>    &#123;<br>      &quot;<span class="hljs-selector-tag">source</span>&quot;: <span class="hljs-string">&quot;/:slug*&quot;</span>,<br>      <span class="hljs-string">&quot;destination&quot;</span>: <span class="hljs-string">&quot;/:slug*.html&quot;</span><br>    &#125;<br>  ]<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="内容解释">内容解释</h2><blockquote><p>以下为AI生成的解释：</p></blockquote><p><code>vercel.json</code> 配置文件是用来在 Vercel 平台上配置特定的路由重写规则（Rewrites），可以帮助你实现自定义的 URL 路径结构。下面是对这个配置文件和其原理的详细解释。</p><h3 id="vercel-json-文件"><code>vercel.json</code> 文件</h3><p><code>vercel.json</code> 是一个配置文件，用来为你在 Vercel 上托管的应用设置自定义的行为。通过这个文件，你可以定义一些如重写（rewrites）、重定向（redirects）、自定义构建配置等规则。这个文件允许你精确控制你的应用如何响应请求、如何处理路由等。</p><h3 id="代码解析">代码解析</h3><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;rewrites&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span><br>    <span class="hljs-punctuation">&#123;</span><br>      <span class="hljs-attr">&quot;source&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;/:slug*&quot;</span><span class="hljs-punctuation">,</span><br>      <span class="hljs-attr">&quot;destination&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;/:slug*.html&quot;</span><br>    <span class="hljs-punctuation">&#125;</span><br>  <span class="hljs-punctuation">]</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><p>这段配置主要是通过 <strong>重写规则（Rewrites）</strong> 来实现对 URL 路径的处理。</p><h4 id="rewrites-的作用"><code>rewrites</code> 的作用</h4><ul><li><code>rewrites</code> 用来处理 URL 重写。它允许你将一个请求的 URL 重写到另一个 URL，而不改变浏览器的地址栏显示（即，用户访问的路径不会改变，但请求的资源或页面可能会改变）。</li><li>重写规则在请求到达服务器时生效，处理 URL 后，服务器根据新的 URL 路径来查找并返回对应的资源。</li></ul><h4 id="配置的具体含义">配置的具体含义</h4><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;source&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;/:slug*&quot;</span><span class="hljs-punctuation">,</span><br>  <span class="hljs-attr">&quot;destination&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;/:slug*.html&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><ul><li><p><strong><code>source</code>:</strong> 表示匹配的原始 URL 路径。在这里，<code>/:slug*</code> 表示任意以 <code>/</code> 开头的路径，并且 <code>slug</code> 部分是一个占位符，代表动态的部分。<code>*</code> 是一个通配符，意味着后面可以匹配任意长度的路径。</p><p>举个例子，如果用户访问 <code>/about</code> 或 <code>/blog/2025/01/26</code>，这些路径都会被 <code>:slug*</code> 匹配。</p></li><li><p><strong><code>destination</code>:</strong> 指定了请求被重写后的目标 URL。在这里，<code>/:slug*.html</code> 表示将匹配到的路径重写成加上 <code>.html</code> 后缀的路径。例如，如果访问的是 <code>/about</code>，就会重写成 <code>/about.html</code>；如果访问的是 <code>/blog/2025/01/26</code>，就会重写成 <code>/blog/2025/01/26.html</code>。</p></li></ul><h4 id="原理">原理</h4><ul><li><p><strong>无后缀路径问题：</strong> 默认情况下，Vercel 会把请求的路径作为文件夹或文件来查找资源。如果你的网页是静态 HTML 文件（如 <code>about.html</code>），但没有 <code>.html</code> 后缀，Vercel 会尝试根据路径自动查找匹配的文件，可能找不到。这个重写规则的目的是通过自动将请求的 URL 后缀转换为 <code>.html</code> 来解决这个问题。</p><p>比如，用户访问 <code>/about</code>，Vercel 默认会去查找一个名为 <code>about</code> 的资源，但如果你的文件名是 <code>about.html</code>，它可能无法自动识别为 <code>.html</code> 文件。通过重写规则，将 <code>/about</code> 重写成 <code>/about.html</code>，就可以确保 Vercel 正确地查找并返回你所期望的文件。</p></li><li><p><strong>保持 URL 清洁：</strong> 使用这个重写规则后，用户仍然可以通过不带 <code>.html</code> 后缀的 URL 访问网站，而实际文件是带有 <code>.html</code> 后缀的。这种方式让你的 URL 看起来更简洁、干净。</p></li></ul><h3 id="适用场景">适用场景</h3><ul><li>如果你的网站有很多静态 HTML 文件，并且希望用户访问时不带 <code>.html</code> 后缀（例如，<code>/about</code> 而不是 <code>/about.html</code>），可以使用这种方法进行 URL 重写。</li><li>有时，这种做法也是为了兼容某些 SEO 或用户体验上的要求，因为很多时候 URL 中不含文件扩展名的路径更符合规范，也让链接看起来更加简洁。</li></ul><h3 id="总结">总结</h3><p>通过在 <code>vercel.json</code> 中添加这个重写规则，你可以实现自动将没有 <code>.html</code> 后缀的 URL 转换为带 <code>.html</code> 后缀的路径，从而确保静态文件能够正确被 Vercel 服务器找到并返回。同时，这种方式保持了 URL 的整洁和简洁，提升了用户体验。</p><p>完结撒花！</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/95bcdae3.html</id><link href="https://b.wihi.top/posts/95bcdae3.html"/><published>2025-01-26T04:00:00.000Z</published><summary>解决Hexo博客部署在Vercel平台时文章链接无法省略.html后缀访问的问题。通过配置vercel.json文件中的重写规则，实现无后缀URL到.html文件的自动映射，从而保持链接简洁性</summary><title>解决Vercel文章链接地址末尾无.html访问问题</title><updated>2025-01-26T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><content><![CDATA[<p><font size="4">动态日志(实时更新)</font></p><div class="note note-success">            <p>从2025年1月25日开始记录</p>           </div><ul><li><p>Time: 2026-4-5</p></li><li><p>Time: 增加<code>隐私政策</code>，修改文章<code>Android-实用工具记录</code>，优化主题文字配色，更换部分文章头图，增加RSS订阅功能。</p></li><li><p>Time: 2026-4-4</p></li><li><p>Content: 新增两篇文章<code>通过Cloudflare Workers API部署项目</code>、<code>在Hexo-fluid的分类页中增加说明(2)--注入法</code>。本博客加入<code>开往-友链接力</code></p></li><li><p>Time: 2026-3-28</p></li><li><p>Content: 优化网站构建插件，删除文章<code>PHP不跳转随机图API</code>，更新主题。</p></li><li><p>Time: 2026-3-21</p></li><li><p>Content: 优化全站文章内容与SEO,删除文章<code>C++学习基础笔记-常见头文件+printf语法+科学记数法</code></p></li><li><p>Time: 2026-1-17</p></li><li><p>Content: 新增一篇文章<code>NoMachine客户端 不断创建tray monitor进程解决办法</code></p></li><li><p>Time: 2026-1-1</p></li><li><p>Content: 新增一篇文章<code>辞旧迎新：再见2025，你好2026</code></p></li><li><p>Time: 2025-11-16</p></li><li><p>Content: 新增一篇文章<code>二进制学习笔记</code></p></li><li><p>Time: 2025-10-19</p></li><li><p>Content: 新增一篇文章<code>WS2812B灯带项目</code> 计划页重写：更换封面图与新增计划</p></li><li><p>Time: 2025-9-21</p></li><li><p>Content: 新增文章<code>启动，人生中第一块开发板！</code> 全部文章使用AI重写描述和关键词SEO</p></li><li><p>Time: 2025-8-7</p></li><li><p>Content: 新增文章<code>CoudFlare-R2配置mTLS</code></p></li><li><p>Time: 2025-8-6</p></li><li><p>Content: 新增文章<code>自动删除CloudFlare域名缓存脚本</code> 并且CDN启用非html重写</p></li><li><p>Time: 2025-8-4</p></li><li><p>Content: 全部文章重新增加4号字体标题以优化无JavaScript下的显示问题。删除文章<code>岸的执念与海的呼唤</code>，原因是今天重新读发现写的很一般。部分文章标题包含中文冒号的改为英文冒号。博客全局启用css、js、html压缩。</p></li><li><p>Time: 2025-8-3</p></li><li><p>Content: 优化全部文章描述SEC，全部文章新增详细时间（全部为12：00：00），修改文章<code>Hexo优化：速度与SEO</code></p></li><li><p>Time: 2025-8-1</p></li><li><p>Content: 新增两篇文章: <code>Material for MkDocs---数学公式</code>和<code>Cloudfalre结合阿里云域名设置DNSSSEC</code>。全部文章增加h1标题。修改部分文章标头顺序。修改计划页头图。</p></li><li><p>Time: 2025-7-29</p></li><li><p>Content: 删除文章<code>Teach手记Rclone手册</code>、<code>Teach手记ffmpeg</code>、<code>未命名海岸线</code> 、重置部分文章链接。浓缩文章内容。</p></li><li><p>Time: 2025-7-28</p></li><li><p>Content: 替换废话文章<code>Centos8.5修改系统Python版本</code>为新的文章<code>Teach手记: Material for MkDocs---添加背景</code>。重写<code>关于页</code>。缩减首页大图占比至27%。调整导航菜单顺序。增加博客版本号至底部。替换博客默认大图为泰山顶拍摄的图片。替换友链页顶部大图。修改博客介绍。</p></li><li><p>Time: 2025-7-20</p></li><li><p>Content: 修复图片失效问题，选择自建图床</p></li><li><p>Time: 2025-6-19</p></li><li><p>Content: 重写文章<code>岸的虚构与海的真相</code>并且更名为<code>岸的执念与海的呼唤</code></p></li><li><p>Time: 2025-5-31</p></li><li><p>Content: 新增文章<code>Teach手记:FFmpeg常用指令速查手册</code>与<code>Teach手记:Rclone常用指令速查手册</code>，端午安康</p></li><li><p>Time: 2025-5-28</p></li><li><p>Content: 新增自定义页<code>计划 • 日程表</code>，补档文章<code>笔搁纸鸯-成立闲谈</code>，删除网站字体以提升速度，放弃第三方库js/css本地托管。</p></li><li><p>Time: 2025-5-25</p></li><li><p>Content: 因部分原因替换<code>2c3c7e8c</code>链接下的文章，并且新开一个专栏，Teach手记，以后在这个专栏中专门写一些在网上冲浪的心得。更换静态资源托管链接为<code>fastly</code>的。</p></li><li><p>Time: 2025-4-13</p></li><li><p>Content: 新增一篇文章<code>《未命名海岸线》</code></p></li><li><p>Time: 2025-4-12</p></li><li><p>Content: 新增一篇文章<code>岸的虚构与海的真相</code></p></li><li><p>Time：2025-4-2</p></li><li><p>Content：新增友链</p></li><li><p>Time：2025-3-19</p></li><li><p>Content：替换静态托管链接，由<code>jsd</code>更改为初七云的<code>smartcis</code></p></li><li><p>Time: 2025-2-23</p></li><li><p>Content: 恢复代码块样式为fluid主题自带，安装自动提交收录插件，优化部分文章内容，全部文章持续更新。</p></li><li><p>Time: 2025-2-22</p></li><li><p>Content: 重写并改名原文章<code>在服务器上使用宝塔部署Hexo</code>为<code>Hexo优化：速度与SEO</code>，新增Cloudflare删缓存脚本第二代，优化代码块css。</p></li><li><p>Time: 2025-2-22</p></li><li><p>Content: 新增一篇文章:<code>解决Hexo中图片因跨域资源共享（CORS）政策或引用来源限制无法显示问题</code>,以防后续忘记。</p></li><li><p>Time：2025-1-26</p></li><li><p>Content：新增两篇文章<code>灵活运用Docker--部署应用</code>与<code>解决文章链接地址结尾无.html访问问题</code>，修改文章安卓实用软件，修改首页动态标题加载时间。</p></li><li><p>Time：2025-1-25</p></li><li><p>Content：删除部分敏感/废话文章，提示文章质量，删除末尾的多余提示，更换顶部图外链，增快博客访问速度，增加首页文章封面图片。</p></li></ul><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/1ee8a059.html</id><link href="https://b.wihi.top/posts/1ee8a059.html"/><link href="https://img.wihi.top/banner/cc864bf073ffa317fd382e893343bc6b.jpeg" rel="enclosure"/><published>2025-01-25T04:00:00.000Z</published><summary>笔搁纸鸯动态日志，记录博客更新内容，文章修改增减等，从2025年1月25日开始记录记录，实时更新，你可以通过本文章更好的了解笔搁纸鸯</summary><title>动态日志(实时更新)</title><updated>2026-04-05T15:30:06.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="脚本" scheme="https://b.wihi.top/categories/%E8%84%9A%E6%9C%AC/"/><category term="脚本" scheme="https://b.wihi.top/tags/%E8%84%9A%E6%9C%AC/"/><content><![CDATA[<p><font size="4">获取图片链接的油猴脚本</font></p><blockquote><p>前段时间研究了Python、Shell脚本爬虫，发现都得模拟浏览器访问然后爬取源码，后来脑洞大开，直接写个油猴脚本，直接获取当前源码并且提取图片链接并且保存到一个txt文件种非常方便。</p></blockquote><div class="note note-info">            <p>Last time: 2024/10/5</p>           </div><h3 id="源码：">源码：</h3><p>废话不多说，直接上代码：</p><div class="note note-success">            <p>请尊重我的劳动成果，禁止用于商业售卖，转发请标明来源。</p>           </div><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-comment">// ==UserScript==</span><br><span class="hljs-comment">// @name         提取页面图片链接到文件（可拖动）</span><br><span class="hljs-comment">// @namespace    http://tampermonkey.net/</span><br><span class="hljs-comment">// @version      0.4</span><br><span class="hljs-comment">// @description  在点击悬浮按钮后提取页面中所有图片的链接到文本文件并提供下载链接，支持拖动操作</span><br><span class="hljs-comment">// @author       CSDevil</span><br><span class="hljs-comment">// @match        *://*/*</span><br><span class="hljs-comment">// ==/UserScript==</span><br><br>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-string">&#x27;use strict&#x27;</span>;<br><br>    <span class="hljs-keyword">let</span> startX, startY;<br>    <span class="hljs-keyword">const</span> floatingButton = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">&#x27;div&#x27;</span>);<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">position</span> = <span class="hljs-string">&#x27;fixed&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">top</span> = <span class="hljs-string">&#x27;50%&#x27;</span>; <br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">left</span> = <span class="hljs-string">&#x27;10px&#x27;</span>; <br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">transform</span> = <span class="hljs-string">&#x27;translateY(-50%)&#x27;</span>; <br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">width</span> = <span class="hljs-string">&#x27;50px&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">height</span> = <span class="hljs-string">&#x27;50px&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">background</span> = <span class="hljs-string">&#x27;#007bff&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">color</span> = <span class="hljs-string">&#x27;#fff&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">borderRadius</span> = <span class="hljs-string">&#x27;50%&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">textAlign</span> = <span class="hljs-string">&#x27;center&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">lineHeight</span> = <span class="hljs-string">&#x27;50px&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">cursor</span> = <span class="hljs-string">&#x27;pointer&#x27;</span>;<br>    floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">zIndex</span> = <span class="hljs-string">&#x27;99999&#x27;</span>;<br>    floatingButton.<span class="hljs-property">textContent</span> = <span class="hljs-string">&#x27;提取&#x27;</span>;<br><br>    <span class="hljs-keyword">let</span> isProcessing = <span class="hljs-literal">false</span>;<br><br>    <span class="hljs-comment">// 添加触摸事件处理</span><br>    floatingButton.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;touchstart&#x27;</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) &#123;<br>        <span class="hljs-keyword">const</span> touch = e.<span class="hljs-property">touches</span>[<span class="hljs-number">0</span>];<br>        startX = touch.<span class="hljs-property">clientX</span> - floatingButton.<span class="hljs-title function_">getBoundingClientRect</span>().<span class="hljs-property">left</span>;<br>        startY = touch.<span class="hljs-property">clientY</span> - floatingButton.<span class="hljs-title function_">getBoundingClientRect</span>().<span class="hljs-property">top</span>;<br>    &#125;);<br><br>    floatingButton.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;touchmove&#x27;</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) &#123;<br>        e.<span class="hljs-title function_">preventDefault</span>();<br>        <span class="hljs-keyword">const</span> touch = e.<span class="hljs-property">touches</span>[<span class="hljs-number">0</span>];<br>        floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">left</span> = (touch.<span class="hljs-property">clientX</span> - startX) + <span class="hljs-string">&#x27;px&#x27;</span>;<br>        floatingButton.<span class="hljs-property">style</span>.<span class="hljs-property">top</span> = (touch.<span class="hljs-property">clientY</span> - startY) + <span class="hljs-string">&#x27;px&#x27;</span>;<br>    &#125;);<br><br>    <span class="hljs-comment">// 添加点击事件监听器</span><br>    floatingButton.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;click&#x27;</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) &#123;<br>        <span class="hljs-keyword">if</span> (isProcessing) <span class="hljs-keyword">return</span>;<br>        isProcessing = <span class="hljs-literal">true</span>;<br><br>        <span class="hljs-comment">// 提取页面中所有图片链接</span><br>        <span class="hljs-keyword">const</span> imageLinks = <span class="hljs-title class_">Array</span>.<span class="hljs-title function_">from</span>(<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelectorAll</span>(<span class="hljs-string">&#x27;img&#x27;</span>))<br>            .<span class="hljs-title function_">map</span>(<span class="hljs-function"><span class="hljs-params">image</span> =&gt;</span> image.<span class="hljs-property">src</span>)<br>            .<span class="hljs-title function_">filter</span>(<span class="hljs-function"><span class="hljs-params">src</span> =&gt;</span> src); <span class="hljs-comment">// 过滤有效的src</span><br><br>        <span class="hljs-comment">// 将链接保存到文本文件并提供下载链接</span><br>        <span class="hljs-keyword">const</span> linkText = imageLinks.<span class="hljs-title function_">join</span>(<span class="hljs-string">&#x27;\n&#x27;</span>);<br>        <span class="hljs-keyword">const</span> blob = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Blob</span>([linkText], &#123; <span class="hljs-attr">type</span>: <span class="hljs-string">&#x27;text/plain&#x27;</span> &#125;);<br>        <span class="hljs-keyword">const</span> url = <span class="hljs-variable constant_">URL</span>.<span class="hljs-title function_">createObjectURL</span>(blob);<br>        <br>        <span class="hljs-comment">// 获取当前网页的URL并进行处理</span><br>        <span class="hljs-keyword">const</span> pageUrl = <span class="hljs-variable language_">window</span>.<span class="hljs-property">location</span>.<span class="hljs-property">href</span>;<br>        <span class="hljs-keyword">const</span> sanitizedPageUrl = pageUrl.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/[^a-zA-Z0-9]/g</span>, <span class="hljs-string">&#x27;_&#x27;</span>).<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, <span class="hljs-number">50</span>);<br>        <span class="hljs-keyword">const</span> fileName = <span class="hljs-string">`<span class="hljs-subst">$&#123;sanitizedPageUrl&#125;</span>_image_links.txt`</span>;<br><br>        <span class="hljs-comment">// 创建下载链接并模拟点击</span><br>        <span class="hljs-keyword">const</span> downloadLink = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">&#x27;a&#x27;</span>);<br>        downloadLink.<span class="hljs-property">href</span> = url;<br>        downloadLink.<span class="hljs-property">download</span> = fileName; <span class="hljs-comment">// 使用处理后的URL作为文件名</span><br>        downloadLink.<span class="hljs-property">style</span>.<span class="hljs-property">display</span> = <span class="hljs-string">&#x27;none&#x27;</span>; <span class="hljs-comment">// 隐藏链接</span><br>        <span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-title function_">appendChild</span>(downloadLink);<br>        downloadLink.<span class="hljs-title function_">click</span>();<br><br>        <span class="hljs-comment">// 提供下载反馈</span><br>        <span class="hljs-keyword">const</span> notification = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">&#x27;div&#x27;</span>);<br>        notification.<span class="hljs-property">textContent</span> = <span class="hljs-string">&#x27;正在下载...&#x27;</span>;<br>        <span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-title function_">appendChild</span>(notification);<br><br>        <span class="hljs-comment">// 清理工作</span><br>        <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>            <span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-title function_">removeChild</span>(downloadLink); <span class="hljs-comment">// 移除链接</span><br>            <span class="hljs-variable constant_">URL</span>.<span class="hljs-title function_">revokeObjectURL</span>(url); <span class="hljs-comment">// 释放URL对象</span><br>            <span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-title function_">removeChild</span>(notification); <span class="hljs-comment">// 移除通知</span><br>            isProcessing = <span class="hljs-literal">false</span>; <span class="hljs-comment">// 重置状态</span><br>        &#125;, <span class="hljs-number">100</span>); <span class="hljs-comment">// 延时释放，确保下载完成</span><br>    &#125;);<br><br>    <span class="hljs-comment">// 将悬浮按钮添加到页面中</span><br>    <span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-title function_">appendChild</span>(floatingButton);<br>&#125;)();<br><br><br></code></pre></td></tr></table></figure><p> </p><h3 id="后记：">后记：</h3><p><strong>代码本无害，请合法使用，不要非法获取网站图片。</strong></p><p>完结撒花</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/d288e07e.html</id><link href="https://b.wihi.top/posts/d288e07e.html"/><published>2024-07-22T04:00:00.000Z</published><summary>分享一个实用的油猴脚本，能够提取网页中的所有图片链接并保存为文本文件。脚本支持拖拽操作，自动生成包含当前URL的文件名，方便于进行图片下载和筛选</summary><title>获取图片链接的油猴脚本</title><updated>2024-07-22T04:00:00.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Android" scheme="https://b.wihi.top/categories/Android/"/><category term="Android" scheme="https://b.wihi.top/tags/Android/"/><content><![CDATA[<p><font size="4">Android-实用工具记录</font></p><blockquote><p>突然间灵光一闪，打算写一篇文章，记录一下Android使用时候一些用的上的APP</p></blockquote><h2 id="工具类">工具类</h2><h4 id="MT管理器">MT管理器</h4><p>顾名思义，Android系统的文件管理器，你可以选择压缩、编辑文件，最主要的是你可以对<code>APK</code>文件进行修改，当然，它有会员才能解锁的功能，不过如果你不需要高级的安卓逆向的操作，你是不需要会员的。截止2025年7月它还又更新了视频音乐播放，代码文字自动补全，链接网络存储（FTP、S3等）等另我爱不释手的功能。它的功能还有很多，自己去了解趴。</p><ul><li><a href="https://mt2.cn/">MT官网</a></li></ul><h4 id="QR扫码器">QR扫码器</h4><p>这玩意就是识别二维码用的，不过只能识别标准二维码，像微信的小程序那样的二维码就识别不了了，不过用起来还是嘎嘎方便的。</p><ul><li>未找到官网</li></ul><h4 id="Termux">Termux</h4><p>这款软件相当于一个linux系统的虚拟机，你可以执行linux的指令等，安装包也不大，如果你有本地跑Node等需求的话可以使用这款软件。</p><ul><li><a href="https://termux.dev/cn/">Termux官网</a></li></ul><h4 id="Lit图片压缩">Lit图片压缩</h4><p>顾名思义，用来压缩图片的，找不到作者、官网，因此其的付费才能用的功能彻底用不了了，去付费版我也没有，因此只能用来压缩png、jpg等图片，有图片数量限制。</p><ul><li>未找到官网</li></ul><h4 id="MX播发器">MX播发器</h4><p>安卓上的媒体播放器，特点就是方便简洁，值得一提的是还有个<code>小窗模式</code>，手机系统自带到视频播放器有些臃肿(因为我的手机配置比较低的缘故，光是打开软件就需要5秒左右)</p><ul><li>未找到官网</li></ul><h3 id="Thunderbird">Thunderbird</h3><p>这是一个广受欢迎的开源免费邮箱客户端，并不是安卓独有，而是多个平台都有。可以把邮箱账号登录在该软件上进行邮件的收发等功能。有这款软件就可以丢掉臃肿的多个不同邮箱的不同客户端了，只需要这一个就可以了。</p><p>官网地址：</p><ul><li><a href="https://www.thunderbird.net/zh-CN/">Thunderbird官网</a></li></ul><h3 id="豆包AI">豆包AI</h3><p>说豆包AI是为了夸赞它的AI绘图能力，我使用了很多家绘图AI进行绘画人像，发现只有豆包AI画的最自然，最细节。当然这只是我的个人观点。</p><p>官网地址：</p><ul><li><a href="https://www.doubao.com/">豆包AI官网</a></li></ul><h3 id="Obsidian">Obsidian</h3><p>这是一款非常好用的markdown笔记软件，同时可以用来管理一些知识数据，可以构建知识图谱等，非常好用。</p><p>官网地址：</p><ul><li><a href="https://obsidian.md/">Obsidian官网</a></li></ul><h3 id="Read-You">Read You</h3><p>这是一个以 Material You 风格呈现的 Android RSS 阅读器，你可以用它来导入本站的RSS订阅。</p><ul><li><a href="https://github.com/ReadYouApp/ReadYou">Github仓库地址</a></li></ul><h2 id="网络代理类">网络代理类</h2><h4 id="Httpcanary">Httpcanary</h4><p>俗称小黄鸟，说好点是应用网络流量调试，其实就是抓包，因此这玩意也很敏感，就不附上下载链接了，官方跑路了一段时间又回来了，改了个新名字叫做<code>Reqable</code>行行前往，去百度、必应、Github搜索吧，这里就不附上下载链接了。</p><h4 id="Virtual-Hosts">Virtual Hosts</h4><p>这款软件可以帮助你在安卓手机上不需要root就可以修改host，原理和Httpcanary差不多，都是创建本地VPN进行修改网络，这里附上该项目的Github仓库地址，如果进不去请更换网络。</p><ul><li><a href="https://github.com/x-falcon/Virtual-Hosts">Github仓库地址</a></li></ul><h4 id="Clash">Clash</h4><p>这款软件是用来连接代理服务器的，<code>匹夫无罪，怀璧其罪。</code>这款软件本身只是用来连接代理服务器，但是如果你用了干非法的事情那就不行，敏感软件，自己去必应、Github搜索<code>Clash</code> 有电脑版和手机版，自行下载了解使用吧。</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/974b1ce3.html</id><link href="https://b.wihi.top/posts/974b1ce3.html"/><published>2024-06-10T04:00:00.000Z</published><summary>推荐一些Android平台上实用但不太知名的工具类APP，包括文件管理、二维码扫描、终端模拟、图片压缩、媒体播放器等，希望对同样使用安卓但找不到趁手工具的朋友有所帮助</summary><title>Android-实用工具记录</title><updated>2026-04-05T15:29:01.000Z</updated></entry><entry><author><name>鸣心</name></author><category term="Docker" scheme="https://b.wihi.top/categories/Docker/"/><category term="Docker" scheme="https://b.wihi.top/tags/Docker/"/><content><![CDATA[<p><font size="4">使用Docker搭建NSFW-JS鉴黄接口</font></p><div class="note note-success">            <p>本文章部分内容来源于<a href="https://cloud.tencent.com/developer/article/2076782">此文章</a>，如有侵权请联系删除</p>           </div><blockquote><p>起因是这样的，搭建了个图床但苦于找不到合适的鉴黄，终于皇天不负有心人，让我给找到了，写篇文章记录一下。</p></blockquote><p>找来找去，目前就发现一个方法，<strong>Docker</strong>安装鉴黄接口，NSFW JS可能不是很准确，但是任然可以识别90%的违规图片，它重在开源，而且自建免费，不用担心被刷。</p><h2 id="正文：">正文：</h2><ol><li>安装<br>你先得有个docker环境，docker怎么安装就去百度吧，很简单的。然后执行以下代码：</li></ol><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs routeros"><span class="hljs-comment">#复制下面的命令部署NSFW JS</span><br>docker <span class="hljs-built_in">run</span> -d -p 127.0.0.1:5000:5000/tcp \ --env <span class="hljs-attribute">PORT</span>=5000 \ <span class="hljs-attribute">--restart</span>=always \ eugencepoi/nsfw_api:latest<br></code></pre></td></tr></table></figure><div class="note note-info">            <p>上面这个代码里面“127.0.0.1:5000”是只对127.0.0.1的内网开放，因此外网是访问不了的，需要改为外网也能访问的话把**127.0.0.1:**去掉即可</p>           </div><blockquote><p>吐槽一句：镜像真大，带宽小的机子得下载半个小时。</p></blockquote><p>访问调用方法：</p><p>访问下面的链接：</p><p>http://127.0.0.1:5000?url=</p><p>“url=”后面跟你的图片链接，貌似这个API只能对图片链接进行鉴别，其他方法好像不行。</p><p>终端可以用这个指令：</p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs routeros">curl -X <span class="hljs-built_in">GET</span> -H <span class="hljs-string">&#x27;Content-Type: application/json&#x27;</span> <span class="hljs-string">&quot;http://127.0.0.1:5000?url=&quot;</span><br></code></pre></td></tr></table></figure><ol start="2"><li>测试</li></ol><p>终端执行以下代码：</p><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs swift">curl <span class="hljs-operator">-</span><span class="hljs-type">X</span> <span class="hljs-type">GET</span> <span class="hljs-operator">-</span><span class="hljs-type">H</span> &#x27;<span class="hljs-type">Content</span><span class="hljs-operator">-</span><span class="hljs-type">Type</span>: application<span class="hljs-regexp">/json&#x27; &quot;http:/</span><span class="hljs-regexp">/127.0.0.1:5000?url=https:/</span><span class="hljs-regexp">/www.google.com/</span>images<span class="hljs-regexp">/branding/</span>googlelogo<span class="hljs-regexp">/2x/</span>googlelogo_color_272x92dp.png<span class="hljs-string">&quot;</span><br></code></pre></td></tr></table></figure><p>正常应该返回这个：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-punctuation">&#123;</span> <span class="hljs-attr">&quot;score&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-number">0.00016061133646871895</span><span class="hljs-punctuation">,</span> <span class="hljs-attr">&quot;url&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png&quot;</span> <span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure><ol start="3"><li>返回字段说明</li></ol><p>score是图片得分，范围在0-1之间，1 表示它肯定是成人内容，而 0 则不是。其实大于0.9就可以认为是成人内容。</p><p>更多使用说明可以查看<a href="https://hub.docker.com/r/eugencepoi/nsfw_api">Docker hub</a>上的介绍</p><p>经过测试好像被鉴别的链接地址的域名每个小时只能用1000次，不然会提示Too many 好像是为了防止恶意调用，请自行研究。</p><h2 id="结语">结语</h2><p>写这篇文章主要是为了记录一下，防止哪天找不到。</p><p>完结撒花！</p><p> </p><center>鸣心/Write</center>]]></content><id>https://b.wihi.top/posts/17981503.html</id><link href="https://b.wihi.top/posts/17981503.html"/><published>2024-05-26T04:00:00.000Z</published><summary>使用Docker快速部署NSFW-JS鉴黄API接口的完整教程，包含安装命令、调用方法、测试示例和结果解析</summary><title>使用Docker搭建NSFW-JS鉴黄接口</title><updated>2024-05-26T04:00:00.000Z</updated></entry></feed>